Code archives/Algorithms/Point inside convex polygon
This code has been declared by its author to be Public Domain code.
Download source code
| |||||
Normally it's quite difficult to tell if a point is inside an arbitrary polygon. For a concave polygon, or one with holes in, the scanning method is the way to go. But when you've got a convex polygon, things get a lot easier! Remember that the definition of a convex polygon is "A polygon such that every line segment between two vertices of the polygon does not go exterior to the polygon (i.e., it remains inside or on the boundary of the polygon)." We can use this fact to split a convex polygon into a fan of triangles, originating from one of its vertices. Then the point is inside the polygon if and only if it is inside one of the triangles, which is easy to check with a little bit of maths. Remember that this only works on a *convex* polygon, not just any one, so only use it when you know you've got one, such as a convex hull. | |||||
'little type for keeping track of 2d points Type point Field x#,y# Function create:point(x#,y#) p:point=New point p.x=x p.y=y Return p End Function End Type 'returns True if p1 and p2 are on the same side of the line a->b Function sameside(p1x#,p1y#,p2x#,p2y#,ax#,ay#,bx#,by#) cp1# = (bx-ax)*(p1y-ay)-(p1x-ax)*(by-ay) cp2# = (bx-ax)*(p2y-ay)-(p2x-ax)*(by-ay) If cp1*cp2 >= 0 Then Return True End Function 'Clever little trick for telling if a point is inside a given triangle 'If for each pair of points AB in the triangle, P is on the same side of AB as 'the other point in the triangle, then P is in the triangle. Function pointintriangle(px#,py#,ax#,ay#,bx#,by#,cx#,cy#) If sameside(px,py,ax,ay,bx,by,cx,cy) And sameside(px,py,bx,by,ax,ay,cx,cy) And sameside(px,py,cx,cy,ax,ay,bx,by) Return True Else Return False EndIf End Function 'returns True if (x,y) is inside convex polygon defined by list of points 'points must be in clockwise (or anticlockwise) order. 'won't work for just any polygon! 'Works by splitting polygon into triangles, and checking each of those Function pointinside(x# , y# , points:tlist) p1:point = Null p2:point = Null For p:point = EachIn points If p1 If p2 If pointintriangle(x , y , p1.x , p1.y , p2.x , p2.y , p.x , p.y) Return True EndIf EndIf p2=p Else p1 = p EndIf Next Return False End Function |
Comments
| ||
I have been using This point in poly function: http://www.darwin3d.com/gamedev/articles/col0199.pdf when I get a chance I will test and compare both codes. If its significantly faster (wich I am almost shure it is) I will add it to my library. Thanks for sharing. |
| ||
As far as I can tell, that's just talking about general polygons again? |
| ||
Yes, I am not disputing that. There are three sample c programs that illustrate what is being explained. I have converted them to bmax and I am using them in my library. they work efficiently well for my purpose I am also using the npoly lib made in blitzbasic which I have adopted and modified for my personal use. I am not trying to discredit you. I think your example is a great alternative to the said code. I am not a great programmer nor am I trying to reinvent the wheel, I want some code that will prevent me from wasting hours/days by the computer trying to solve. so I leave my doors open to alternative and/or better solutions. I apreciate your sharing so that people like me can leach :). And yes I have contributed. not much of a discovery but stuff I had problems with and figured out. may be usefull for somebody. "I will not give up with out a fight!" |
| ||
Yeah of course, I just thought I was missing something simple there! |
| ||
This seems to be working fine for the concave polygon I just tested it with. Perhaps it works sometimes for concave polygons, but not reliably for all of them. |
| ||
Yep, that's true. |
Code Archives Forum