Lets say we have a rectangular mesh, perhaps created with our half mesh tool, and we want to imprint upon it some polygon shape. For instance, we may want to model the temperature or fluid flow in such a polygon and need a mesh in that shape. By imprinting the polygon onto the mesh, we can create a simple stair step mesh that can be used for modeling.

What is the criteria for determining if a cell is inside the polygon or not? Clearly any cell that is fully inside the polygon would be considered “in”. What about one where one of the vertices is outside? Or two are outside? For the figure above, the imprinting follows a simple rule: if the cell center is in the polygon, then the cell is inside.
Shooting Rays
To create our stair step mesh, we need to cycle through the cells in the rectangular mesh and check each cell center to see if its inside. The classic way to determine if a point lies inside a polygon is to shoot a ray from this point and see how many times it crosses the polygon. If its an even number, the point is outside. An odd number of crossings means its inside. The Wikipedia has a nice article on this here.

Hitting a vertex – A rare Event?
There is a subtlety with this scheme. Your ray may strike one of the vertices of the polygon. In that case, you will likely get double counting. It will appear that your ray has crossed both polygon segments N and N+1. As a result, you may conclude exactly the wrong result. My initial reaction to this situation was: it could happen, but will be extremely rare. Wrong! Both meshes and polygons are created by humans. And humans tend to like round numbers. It is much more likely you will have a vertex point at (1,1) than at (1.0001, 0.9999). Similarly for the cell positions. In my own testing, I hit this problem right away.
The solution is found in how we think about a segment. Rather than thinking of a segment as two points and the line that connects them, we can think of it as just one point and the line. The figure shows the idea.

This can be implemented with a judicious use of the > and >= operators.
Implementations
A quick search of the internet reveals many implementations of this odd-even crossing approach. Bob Stein’s article compares a few implementations, looking at lines of code, number of if statements and so on. The routines he looks at range from 44 to 91 lines of code and include from 2 to 19 if statements, and 0 to 2 divides. When I first implemented this, some years ago, my code ran 70 lines and included 7 if statements and 3 divides. In my defense, my code also checked how close a point was to a segment and included the point if it was within some tolerance. Still, it seems a bit bulky compared to some of the implementations Stein looked at. He was justifiably proud of his implementation, which is only 44 long with no divides.
A bit more looking on the web reveals the incredibly tiny 12 line routine of W. Randolph Franklin. It contains only one if and one divide. I tried it out for a couple of cases and it does seem to capture the essense of the method without a single wasted character. Here is the Franklin’s routine:
int pnpoly(int npol, float *xp, float *yp, float x, float y) { int i, j, c = 0; for (i = 0, j = npol-1; i < npol; j = i++) { if ((((yp[i]<=y) && (y<yp[j])) || ((yp[j]<=y) && (y<yp[i]))) && (x < (xp[j] - xp[i]) * (y - yp[i]) / (yp[j] - yp[i]) + xp[i])) c = !c; } return c; }
(Note this code is Copyright © 1970-2003, Wm. Randolph Franklin )
Stair Step Mesh
With a routine like this, we can easily create a stairstep mesh. You can envision a program something like this:
int main() { MESH_TYPE *pMesh; CELL_TYPE *pCell; int i; //Make a triangle float xp[10] = {0., 1.0, 1.0}; float yp[10] = {0., 0., 1.0}; //Create mesh pMesh = createMesh(0., 0., 1.0, 1.0, 0.1, 0.1); //Determine which cells in mesh are 'live' FOR_EACH(i, pCell, *(pMesh->cells)) { pCell->live = pnpoly(3, xp, yp, pCell->x, pCell->y,) } return 0; }
For this to work, we need to add a few more fields to the cell structure defined previously. Specifically, we need the cell center coordinates and a flag stating whether the cell is live or dead.
Some additional work would be required to actually use this stair step mesh in a CFD code. For instance, it is not efficient to keep dead cells in our cell list. Every time we loop through the cells, we will need an if statement:
. Also, we have not identified the boundary faces or made any effort to transfer the boundary conditions from the polygon segments to the edge faces of the stair step mesh. These are tasks for another day.

