There is an n-sided shape, the vertex is P1,P2,..., pn; Given a known point P, determine whether p is inside or outside the polygon.
Preliminary knowledge: The definition of intersection of two segments, if the ends of one segment are at both ends of another segment, the two segments intersect
The two sides of the 2-point segment can be realized with the cross-multiplication of vectors!
Basic steps:
1, over P point vertical upward as a ray
2, determine the intersection of this ray and N edge
3, add all the intersections, if an odd number is inside the polygon, otherwise outside the polygon
The idea is very simple, another explanation of several special situations:
1, the ray intersects with the vertex of the polygon, such as the Pi point of the ray over polygon, if Pi-1 and pi+1 on the opposite side of this ray, this intersection can be counted as if this two o'clock is on the same side of the Ray, then this intersection is not counted. This conclusion is very simple, and drawing a picture should make it clear.
The 2,p point is on one edge of the polygon, and P is also considered to be in the polygon
The 3,p is not on the edge of the polygon, but the ray of P is coincident with an edge of the polygon, such as coincident with the pi,pi+1 segment, if Pi-1 and pi+2 are on either side of the ray, this is an intersection, otherwise this situation does not count as the intersection. Similar to a situation, draw a picture should understand!
By the way, the point in the plane of the figure of the judgment
A planar graph is composed of M polygons, but no two polygons have intersecting edges, only coincident vertices
This is equivalent to the algorithm that calls the M-point in the polygon
The above implementation is very simple, I recently look at the parallel algorithm aspect, so this article is mainly for the parallel algorithm preparation
Also refer to: http://www.cppblog.com/w2001/archive/2007/09/06/31694.html
http://blog.csdn.net/hjh2005/article/details/9246967
Three ways to determine whether a point is in a polygon
1. Fork multiplication discriminant method (only for convex polygons)
Imagine a convex polygon, each of which divides the entire 2D screen into the left and right sides, connecting the first endpoint of each side and the point to be tested to get a vector V, the two 2-D vector is expanded into 3-dimensional, and then the side and the V-fork, to determine the result of the 3-dimensional vector of the z-component of the symbol And then deduce whether the point is inside and outside the convex polygon. It is important to note that whether the polygon vertex is left-handed or right-handed, this has an effect on the specific way of judging.
2. Area Discriminant method (only for convex polygons)
The area of the 4th and the two points of the triangle are respectively set to S1,S2,S3, as long as the s1+s2+s3> the original Triangle area is not in the Triangle range. You can use the Helen formula. Can you get an algorithm for convex polygons? (not sure)
3. Angle and discriminant method (for freeform)
Double angle = 0;
Realpointlist::iterator iter1 = Points.begin ();
for (Realpointlist::iterator Iter2 = (iter1 + 1); Iter2 < Points.end (); ++iter1, ++iter2)
{
Double x1 = (*iter1). x-p.x;
Double y1 = (*iter1). y-p.y;
Double x2 = (*iter2). x-p.x;
Double y2 = (*iter2). y-p.y;
Angle + = angle2d (x1, y1, x2, y2);
}
if (Fabs (angle-span::P I2) < 0.01) return true;
else return false;
Alternatively, you can use bounding box to speed up.
if (P.x < (*iter)->boundingbox.left | |
p.x > (*iter)->boundingbox.right | |
P.y < (*iter)->boundingbox.bottom | |
P.y > (*iter)->boundingbox.top) ...
For polygons, calculating the bounding box is very simple. You just need to find the maximum and minimum values in the horizontal and vertical directions.
For triangles: The angle of the intersection of the 4th and the two points of the triangle is set to j1,j2,j3 respectively, as long as the j1+j2+j3>360 is not in the triangle range.
4. Horizontal/vertical Cross-point discriminant method (for freeform)
Note that if p is a horizontal-to-left Ray, then the intersection of this ray with the polygon must be an odd number, and if p is outside the polygon, it must be even (0). Therefore, we can consider each edge of the polygon in order to find out the total number of intersections. There are some special cases to consider. If you consider the side (P1,P2),
1) If the ray passes through P1 or P2, the intersection will be counted as 2 times, if the coordinates of P are the same as the smaller ordinate in the P1,P2, the case is ignored directly.
2) If the ray level, then the Ray has no intersection, or there are countless, this situation is also directly ignored.
3) If the ray is upright, and the horizontal axis of the P0 is less than the horizontal axis of P1,P2, it must intersect.
4) Before judging the intersection, the first is whether P is on the Edge (P1,P2), and if so, the direct conclusion is: P re-polygon inside.
(citation http://blog.sina.com.cn/s/blog_62986cd40100gjv2.html?retcode=0)
Realize:
Syntax: Result=insidepolygon (Point *polygon,int n,point p);
Parameters:
*polygon: Polygon Vertex array
N: Number of polygon vertices
P: Be judged point
Return value: 0: Point inside polygon, 1: Dot Outside polygon
Attention:
If the P-point is on the polygon vertex or edge, the return value is indeterminate and needs to be judged separately.
Need MATH.H
SOURCE program:
#define MIN (x < y x:y)
#define MAX (x > Y x:y)
typedef struct {
Double x, y;
} point;
int Insidepolygon (point *polygon,int n,point p)
{
int counter = 0;
int i;
Double xinters;
Point P1,p2;
P1 = polygon[0];
for (i=1;i<=n;i++) {
P2 = polygon[i% N];
if (P.y > MIN (p1.y,p2.y)) {
if (p.y <= MAX (p1.y,p2.y)) {
if (p.x <= MAX (p1.x,p2.x)) {
if (p1.y! = p2.y) {
Xinters = (p.y-p1.y) * (p2.x-p1.x)/(P2.Y-P1.Y) +p1.x;
if (p1.x = = p2.x | | p.x <= xinters)
counter++;
}
}
}
}
P1 = p2;
}
if (counter% 2 = = 0)
return (OUTSIDE);
Else
return (INSIDE);
}
Determine if a point is inside a polygon