Determines whether the vertex is in the Multi-edge mode.

Source: Internet
Author: User
0. Preface

Recently, I have encountered similar geometric location problems and have not spent any time summing up them. This article summarizes the methods and code for determining the location of common points and polygon. Hope to help you.

All polygon mentioned in this article are convex polygon. Some descriptions may be incorrect. Please correct them.

1. polygon to be tested

Before starting, we need to build a test environment.

I constructed a special polygon, as shown below.

/\

|

| _ |

The clockwise coordinates (screen coordinate system) of the top vertex are: () (60, 30) (60, 50) (20, 50) (20, 30)

2. Ray Discriminant

 

Based on the polygon, we can draw the following conclusions:

If a point is inside a polygon, any angle of radiation will certainly have an intersection with the polygon, or overlap with the polygon line.

If a point is located outside the polygon, any angle of radiation is eitherOne intersectionThere are either two intersections, no intersections, or overlapping the boundary of a polygon.

Based on the above conclusion, we can determine the relationship between the point and the polygon position by judging the number of intersections between the point and the polygon.

Note:

L overlapping borders of rays and polygon

L differentiate rays of internal and external points when there is an intersection

For the first note, you can set the Ray angle to zero, so that you only need to determine whether the y values of two adjacent vertices are equal. Then determine the X value of the point.

For the second note, many articles on the Internet have mentioned that when the intersection is an odd number after the ray is done, it is represented inside the polygon. This is a wrong idea, not only for the concave polygon, it is not true for convex polygon.

For example, if a Ray from an external point passes through a vertex, the number of intersections is an odd number, but the point is not inside the polygon.

As for how to differentiate these two cases, I can think of an imperfect method. When the ray of an external point has an intersection with a polygon, the intersection must be a vertex, if the ray moves one or one bit down, either there are two intersections or no intersections. For the sake of safety, we try to move the rays to the center of adjacent points as much as possible. In this way, we can determine that the ray of an external point has an intersection point with the polygon.

However, this method is not perfect, because with the shift operation, internal points may be moved out of the outside. In addition, if the judgment point is at (60, 30), the first (20, 30) will be met during the judgment, and then the shift operation will cause an error.

To solve these problems, I first scanned at first to determine whether the vertex was on the vertex, although it affected a little efficiency, and when it was determined that the vertex was a unit away from the polygon, the judgment may be wrong. However, this method is very effective as long as it does not require high precision.

The Code is as follows:

  1. Bool insidepolygon1 (pointd * polygon, int N, pointd pt)
  2. {
  3. Int I, J;
  4. Bool inside, redo;
  5. Redo = true;
  6. For (I = 0; I <n; ++ I)
  7. {
  8. If (polygon [I]. x = pt. X & // whether the vertex is located
  9. Polygon [I]. Y = pt. Y)
  10. {
  11. Redo = false;
  12. Inside = true;
  13. Break;
  14. }
  15. }
  16. While (redo)
  17. {
  18. Redo = false;
  19. Inside = false;
  20. For (I = 0, j = n-1; I <n; j = I ++)
  21. {
  22. If (polygon [I]. Y <pt. Y & pt. Y <polygon [J]. Y) |
  23. (Polygon [J]. Y <pt. Y & pt. Y <polygon [I]. y ))
  24. {
  25. If (Pt. x <= polygon [I]. x | pt. x <= polygon [J]. X)
  26. {
  27. Double _ x = (pt. y-polygon [I]. y) * (polygon [J]. x-polygon [I]. x)/(polygon [J]. y-polygon [I]. y) + polygon [I]. x;
  28. If (Pt. x <_ x) // left of the online
  29. Inside =! Inside;
  30. Else if (Pt. x = _ x) // online
  31. {
  32. Inside = true;
  33. Break;
  34. }
  35. }
  36. }
  37. Else if (Pt. Y = polygon [I]. Y)
  38. {
  39. If (Pt. x <polygon [I]. X) // the intersection point is on the vertex.
  40. {
  41. Polygon [I]. Y> polygon [J]. Y? -- Pt. Y: ++ pt. Y;
  42. Redo = true;
  43. Break;
  44. }
  45. }
  46. Else if (polygon [I]. Y = polygon [J]. Y & // on the horizontal boundary line
  47. PT. Y = polygon [I]. Y &&
  48. (Polygon [I]. x <pt. X & pt. x <polygon [J]. x) |
  49. (Polygon [J]. x <pt. X & pt. x <polygon [I]. X )))
  50. {
  51. Inside = true;
  52. Break;
  53. }
  54. }
  55. }
  56. Return inside;
  57. }

3. Angle and discriminant

Angle and discriminant are used to determine the angle of the angle formed by all adjacent vertices of a vertex and a polygon to determine the positional relationship between a vertex and a polygon.

If the point is inside the polygon, the angle is three hundred and sixty degrees as long as it is not on the boundary or vertex.

If it is on the boundary line, the angle is one hundred and eighty degrees.

If the point is located outside the polygon, the angle and degree cannot reach three hundred and sixty degrees. However, the angle and possibility reach one hundred and eighty degrees, for example, the judgment point (60, 10 ).

The Code is as follows:

  1. // Do not judge the vertex as needed
  2. Bool ispointinline (const pointd & PT, const pointd & pt1, const pointd & pt2)
  3. {
  4. Bool inside = false;
  5. If (Pt. Y = pt1.y &&
  6. Pt1.y = pt2.y &&
  7. (Pt1.x <pt. X & pt. x <pt2.x) |
  8. (Pt2.x <pt. X & pt. x <pt1.x )))
  9. {
  10. Inside = true;
  11. }
  12. Else if (Pt. x = pt1.x &&
  13. Pt1.x = pt2.x &&
  14. (Pt1.y <pt. Y & pt. Y <pt2.y) |
  15. (Pt2.y <pt. Y & pt. Y <pt1.y )))
  16. {
  17. Inside = true;
  18. }
  19. Else if (pt1.y <pt. Y & pt. Y <pt2.y) |
  20. (Pt2.y <pt. Y & pt. Y <pt1.y ))&&
  21. (Pt1.x <pt. X & pt. x <pt2.x) |
  22. (Pt2.x <pt. X & pt. x <pt1.x )))
  23. {
  24. If (0 = (Pt. y-pt1.y)/(pt2.y-pt1.y)-(Pt. X-pt1.x)/(pt2.x-pt1.x ))
  25. {
  26. Inside = true;
  27. }
  28. }
  29. Return inside;
  30. }
  31. Bool insidepolygon2 (pointd * polygon, int N, pointd P)
  32. {
  33. Int I, J;
  34. Double angle = 0;
  35. Bool inside = false;
  36. For (I = 0, j = n-1; I <n; j = I ++)
  37. {
  38. If (polygon [I]. x = p. x & // whether the vertex is located
  39. Polygon [I]. Y = P. Y)
  40. {
  41. Inside = true;
  42. Break;
  43. }
  44. Else if (ispointinline (p, polygon [I], polygon [J]) // whether it is on the Boundary Line
  45. {
  46. Inside = true;
  47. Break;
  48. }
  49. Double X1, Y1, X2, Y2;
  50. X1 = polygon [I]. X-P. X;
  51. Y1 = polygon [I]. Y-P. Y;
  52. X2 = polygon [J]. X-P. X;
  53. Y2 = polygon [J]. Y-P. Y;
  54. Double radian = atan2 (Y1, X1)-atan2 (Y2, X2 );
  55. Radian = ABS (radian );
  56. If (radian> m_pi) radian = 2 * m_pi-radian;
  57. Angle + = radian; // calculation angle and
  58. }
  59. If (FABS (6.28318530717958647692-angle) <1e-7)
  60. Inside = true;
  61. Return inside;
  62. }

Some people's angle and discriminant methods are called the corner method, and there is a similar method called the arc-length method.

Http://haibarali.blog.163.com/blog/static/23474013200722813356858/

4. Area and discriminant

 

Based on the angle and discriminant method, we can continue to evolve and draw the following conclusions:

If a point is inside a polygon, the area of the triangle formed by the point and all adjacent vertices of the polygon is the area of the polygon. Otherwise.

Triangle Area:

Given that the Triangle A (x1, Y1) B (X2, Y2) C (X3, Y3) is known, the area formula is:

| X1 X2 X3 |

S (a, B, c) = | Y1 Y2 Y3 | * 0.5 (positive when the three points are counter-clockwise and negative when the three points are clockwise)

| 1 1 1 |

= (X1 * Y2-X1 * Y3-X2 * Y1 + x2 * Y3 + X3 x Y1-X3 * Y2) * 0.5

Calculate the Polygon Area:

Based on the triangle method above,

We know that the polygon a1a2a3... an (either along or counterclockwise). If any point P exists on the plane, the area formula is:

S (A1, A2, a3...)

= S (p, a1, a2) + S (p, A2, A3) +... + S (p, An, A1)

Since P is optional, it is better to use (0, 0) for convenience.

The Code is as follows:

  1. Bool insidepolygon3 (pointd * polygon, int N, pointd pt)
  2. {
  3. Int I, J;
  4. Bool inside = false;
  5. Double polygon_area = 0;
  6. Double trigon_area = 0;
  7. For (I = 0, j = n-1; I <n; j = I ++)
  8. {
  9. Polygon_area + = polygon [I]. x * polygon [J]. Y-polygon [J]. x * polygon [I]. Y;
  10. Trigon_area + = ABS (
  11. PT. x * polygon [I]. Y-
  12. PT. x * polygon [J]. Y-
  13. Polygon [I]. x * PT. Y +
  14. Polygon [I]. x * polygon [J]. Y +
  15. Polygon [J]. x * PT. Y-
  16. Polygon [J]. x * polygon [I]. Y
  17. );
  18. }
  19. Trigon_area * = 0.5;
  20. Polygon_area = ABS (polygon_area * 0.5 );
  21. If (FABS (trigon_area-polygon_area) <1e-7)
  22. Inside = true;
  23. Return inside;
  24. }

Polygon Area Calculation

Http://www.cppblog.com/zyzx/archive/2009/04/27/81241.html

How to expand the Determinant

Http://www.tongji.edu.cn /~ Math/xxds/kcja/kcja_ B/1-6.htm

5. Dot-line Discriminant

This method was added as prompted by glshader.

If the point is located on the same side of all the boundary lines, it can be determined that the point is inside the polygon.

The determination method is to determine the slope difference between the two rays at the same starting point.

The Code is as follows:

  1. Bool insidepolygon4 (pointd * polygon, int N, pointd P)
  2. {
  3. Int I, J;
  4. Bool inside = false;
  5. Int count1 = 0;
  6. Int count2 = 0;
  7. For (I = 0, j = n-1; I <n; j = I ++)
  8. {
  9. Double value = (P. x-polygon [J]. x) * (polygon [I]. y-polygon [J]. y)-(P. y-polygon [J]. y) * (polygon [I]. x-polygon [J]. X );
  10. If (value> 0)
  11. ++ Count1;
  12. Else if (value <0)
  13. ++ Count2;
  14. }
  15. If (0 = count1 |
  16. = Count2)
  17. {
  18. Inside = true;
  19. }
  20. Return inside;
  21. }

6. Summary

We have summarized the four discriminant methods. Although many principles are simple, we can find that many details are worth further consideration in practice.

 

This blog post is transferred from: http://blog.csdn.net/fwj380891124/article/details/7737143

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.