benson@blake.acs.washington.edu (Dan Benson) (08/08/90)
I know this has been asked before but I missed the answers. I want to know the best way to determine whether a point is inside of a polygon where the polygon is represented as a set of ordered floating point numbers (its boundary). I'm actually using 3D points but the polygons are defined on 2D planes. Also, the polygons can be any shape, concave, convex. If anyone has some suggestions or real answers I would appreciate it. And if there is more interest I will post a summary. Thanks in advance, -- | Dan Benson benson@ee.washington.edu | | Dept. of Elec. Engr., FT-10 | | University of Washington (206) 685-7567 | | Seattle, WA 98195 |
metz@iam.unibe.ch (Igor Metz) (08/08/90)
In article <5990@milton.u.washington.edu> benson@blake.acs.washington.edu (Dan Benson) writes: >I know this has been asked before but I missed the answers. I want to >know the best way to determine whether a point is inside of a polygon >where the polygon is represented as a set of ordered floating point >numbers (its boundary). I'm actually using 3D points but the polygons >are defined on 2D planes. Also, the polygons can be any shape, concave, >convex. get THE book: F.P. Preparata/ M.I. Shamos: Computational Geometry: An Introduction. 2nd ed. New York: Springer, 1988. p. 41ff -- Igor Metz Institut fuer Informatik und angew. Mathematik, Universitaet Bern, Switzerland. domainNet: metz@iam.unibe.ch Phone: (0041) 31 65 49 90 ARPA: metz%iam.unibe.ch@relay.cs.net Fax: (0041) 31 65 39 65
phil@hpsmdca.HP.COM (Philip Walden) (08/08/90)
I use a simple routine that computes the sum of arc angles between the test point and each vertex on the polygon. If the sum == 0, its outside If the summ == 2pi its inside. I have attached a brief explanation in pseudo-fortran. In the actual algorithm I use, the polygon can actually be a set of polygons (members) such that "holes" can be created. The key to it all is the fortran intrinsic ATAN2(rise,run) which returns the 4 quandrant angle (-pi to pi) of the specified vector. Don't use ATAN(rise/run) as it returns only 2 quadrant angles (-pi/2 to pi/2). Yes it works for anything. Brief explanation: ************************* Is a point inside a polygon? Use sum of arc angles: Given a point (x,y) and a polygon SUM(i=1,n) (xi,yi), total arc angle is sum = 0 for i = 1,n ! assumes (x1,y1) = (xn,yn) do dx1 = (x - xi) dy1 = (y - yi) dx2 = (xi+1 - x) dy2 = (yi+1 - y) ds1 = SQRT(dx1**2 + dy1**2) ds2 = SQRT(dx2**2 + dy2**2) sini = (dx1*dy2 - dx2*dy1)/ds1*ds2 !from cross product cosi = (dx1*dx2 + dy1*dy2)/ds1*ds2 !from dot product sum = sum + atan2(sini,cosi) end do If |sum| > 0, point is inside Note: you can skip the computation of ds1, ds2 and the divisions by ds1*ds2, as they cancel out in the atan2 function. I just put them in to clarify the algorithm.
rusmin@twinsun.com (Rusmin Dirgantoro) (08/22/90)
In article <5990@milton.u.washington.edu> benson@blake.acs.washington.edu (Dan Benson) writes: >I know this has been asked before but I missed the answers. I want to >know the best way to determine whether a point is inside of a polygon >where the polygon is represented as a set of ordered floating point >numbers (its boundary). I'm actually using 3D points but the polygons >are defined on 2D planes. Also, the polygons can be any shape, concave, >convex. First of all, I missed the answers of previous postings as well. So.. this idea I'm posting might not be new to you guys. I was working on something like this some time ago for my Geometric Modeling class. The idea I was using was adapted from some good articles of some journals. I don't remember the exact name and date of the journals by heart. The idea is.. 0. Assume your polygon is PG and your point is PT. 1. Create a coordinate frame CF, where the XY plane is the plane of PG. We'll be working with this coordinate system from now on. 2. Transform PT's coordinate into CF coordinate, say we get (CF)PT. 3. If (CF)PTz != 0, PT IS OUTSIDE PG; DONE. If (CF)PTz == 0, PT may be inside PG; continue step 4. 4. Transform PG's boundary (the set of ordered points) into CF coordinates. The points should then have Z == 0, of course. 5. Build segment equations S1..Sn for each segment on the boundary. S1..Sn are line eqs with endpoints. They don't go from/to infinity. S1..Sn are based on CF coordinate system, so they are simply 2D-eqs since we don't care about Z anymore (Z is always 0). 6. Build a random (yes, random) ray equation R. R starts from (CF)PT to infinity. R is on the XY plane of CF. Again, we don't care about Z anymore. 7. Find intersections between R and S1..Sn. Say the number of intersections is NI. 8. If NI is even or zero, PT IS OUTSIDE PG; DONE. If NI is odd, PT IS INSIDE PG; DONE. Please note here that there's a very special case, that is.. Somehow R intersects any of the ordered points (the corners of PG), so step 8 won't necessary give the right answer. One of the solutions for this special case is.. Add step 7 with: When intersecting R with S1..Sn, if R intersects Si at an Si's endpoint, back to step 6 (try another random R). This solution may look dumb to you. But.. believe me.. it works just fine. Here, I assume we are all aware of computation errors, such as round-up errors, floating point errors, etc. So appropiate floating point comparisons should be applied. Of course there are many other ideas on this problem. I'd like to hear them as well. BTW, I'm sure I still have some piece of code doing this problem. And I still have hardcopies of the articles I mentioned above. If anyone is desperate, I'm willing to search those resources in my hayestacks. Just let me know. Ciao. -- -- Rusmin Dirgantoro rusmin@twinsun.com Twin Sun Inc. 1(213)640-6885 voice El Segundo, California ---
markv@gauss.Princeton.EDU (Mark VandeWettering) (08/22/90)
In article <1990Aug22.022743.4139@twinsun.com> rusmin@twinsun.com (Rusmin Dirgantoro) writes: >In article <5990@milton.u.washington.edu> benson@blake.acs.washington.edu (Dan Benson) writes: >> [ ask for points in polygon algorithms ] > [ responds with an "almost right" algorithm ] The solution proposed by rusmin@twinsun.com was based upon the Jordan Curve theorem: any ray from inside a polygon crosses an odd number of edges on its way to infinity. He chose a random ray that began at the point in question, and counted the number of intersections. Problem: if you intersected a vertex you were kind of clueless. Solution, fire another ray. You solve these problems by simplifying everything. The ray you shoot should go to the positive X axis. Assume without loss of generality that your point is the origin. Now: if you are going to intersect a vertex, its because the y component of an edge endpoint is == 0. Well, decide whether you want to count this as positive or negative. Assume positive (I always do). It turns out you get the right answer anyway. For example origin ^ | o o counts as one intersection | v origin ^ ^ |/ o o counts as zero or two intersections origin o o counts as zero or two intersections |\ v v Voila! C'est explique! mark
rusmin@twinsun.com (Rusmin Dirgantoro) (08/23/90)
In article <2018@idunno.Princeton.EDU> markv@gauss.Princeton.EDU (Mark VandeWettering) writes: >In article <1990Aug22.022743.4139@twinsun.com> rusmin@twinsun.com (Rusmin Dirgantoro) writes: >>In article <5990@milton.u.washington.edu> benson@blake.acs.washington.edu (Dan Benson) writes: >>> [ ask for points in polygon algorithms ] >> [ responds with an "almost right" algorithm ] > >You solve these problems by simplifying everything. The ray you shoot should >go to the positive X axis. Assume without loss of generality that your >point is the origin. Now: if you are going to intersect a vertex, its because >the y component of an edge endpoint is == 0. Well, decide whether you want >to count this as positive or negative. Assume positive (I always do). It >turns out you get the right answer anyway. For example >... Mark came up with a smart solution for the "ambiguous ray-edge intersection" (AREI) problem (anyone agrees with this name?). I like his article. But his solution has a little glitch. Consider this case.. origin ^ ^ | | o o---> or <---o or o---> or <---o | | v v (1) (2) (3) (4) Are we going to count (1), (2), (3), or (4) as one or zero? Consider this polygon... +--------------------------------+ | | | | | D E F | y=0 - - o - - o----o----o - - o - - o----o-----o - - o - - A B C | | G H I | | | | +-----------+ A..I are checkpoints for origin or possible positions of the point relative to the polygon. How are we going to do it? I believe there're solutions for this kind of glitch. Are they simple, though? Do we really want to do them? Ciao.. -- Rusmin Dirgantoro rusmin@twinsun.com Twin Sun Inc. 1(213)640-6885 office El Segundo, California 1(213)837-3941 home
markv@gauss.Princeton.EDU (Mark VandeWettering) (08/23/90)
>Mark came up with a smart solution for the "ambiguous ray-edge intersection" >(AREI) problem (anyone agrees with this name?). I like his article. >But his solution has a little glitch. Hardly my own idea. It was shown to me by Eric Haines originally, but I don't think he claims credit for it either. Any takers? Is it patented by Unisys as well :-)? But, it is stump the computer jock time, he gave a nice tough diagram, and its time to show that this really will work. >Consider this case.. > > origin ^ ^ > | | > o o---> or <---o or o---> or <---o > | | > v v > (1) (2) (3) (4) > >Are we going to count (1), (2), (3), or (4) as one or zero? Apply the rule I gave you blindly, lets assume we break ties by assuming they are in above the point in question. Therfore 1 & 2 count as zero intersections, and 3 & 4 count as 1 intersection. Now, on to the case you gave: >Consider this polygon... > > +--------------------------------+ > | | > | | > | D E F | >y=0 - - o - - o----o----o - - o - - o----o-----o - - o - - > A B C | | G H I > | | > | | > +-----------+ > A, B, C, E, G, H, are all counted as zero. D & F are counted as one. Therefore the total is two, and the point is outside. If we broke ties the other way, then B and H count one, and we get the same answer. Pretty damned amazing, isn't it? I really do thank Eric for showing me this. Its one of my favorite little snippets of code. Mark
jindak@surfside.sgi.com (Chris Schoeneman) (08/24/90)
In article <2034@idunno.Princeton.EDU> markv@gauss.Princeton.EDU (Mark VandeWettering) writes: >>Mark came up with a smart solution for the "ambiguous ray-edge intersection" >>(AREI) problem (anyone agrees with this name?). I like his article. >>But his solution has a little glitch. > >Apply the rule I gave you blindly, lets assume we break ties by assuming >they are in above the point in question. Therfore 1 & 2 count as zero >intersections, and 3 & 4 count as 1 intersection. Now, on to the case >you gave: > >>Consider this polygon... >> >> +--------------------------------+ >> | | >> | | >> | D E F | >>y=0 - - o - - o----o----o - - o - - o----o-----o - - o - - >> A B C | | G H I >> | | >> | | >> +-----------+ >> >Mark Mark is right, of course: the same code works. But I feel this solution can be stated more clearly, and make acceleration techniques more obvious. After all, speed is what it's all about, isn't it? The ray interesects an edge if and only if the edge crosses the x-axis. A vertex on the x-axis is considered above it, that is: zero is considered to be positive. * If we assume 0 is positive, the answer presents itself: * count an edge if and only if sign(y1)!=sign(y2). Now we can determine a crossing very fast. Two's-compliment (integer) numbers of n bits can be XOR'd and then AND'd with 2^(n-1). Non-zero means a crossing, zero means no crossing. But in 3D floating point is the norm. What do we do? The SAME thing! Many floating point storage schemes are arranged like so: +-+----------+----------------+ MSB |S| Exponent | Mantissa | LSB +-+----------+----------------+ The S is the sign bit, and it gives the sign of the mantissa, i.e. the sign of the overall number. Like two's-compliment, zero has a zero sign bit; it is in this sense positive. If your floating point is stored this way, then you can XOR and AND, just like before. This is NOT portable, some fp's may be stored differently. Some floating points have both a positive and negative zero. (You can get a negative zero by, say, multiplying -1.0E-25 * 1.0E-25. The answer has no significant digits, but is definitely negative.) Is this a problem? No, a point will have a negative zero y value if it IS below (but very close) to the x-axis. If the other side is above the x-axis then a crossing should be, and is, detected. -Chris Schoeneman Chris Schoeneman | I was neat, clean, shaved and sober, jindak@surfside.esd.sgi.com | and I didn't care who knew it. Silicon Graphics, Inc. | -Raymond Chandler Mountain View, CA | (The Big Sleep)
corkum@csri.toronto.edu (Brent Thomas Corkum) (08/24/90)
There's one question I have concerning this algorithm that I hope someone can answer. It seems to me that a point exactly on an edge can evaluate either inside or outside depending on which edge your on. ie. +----A----+ | | | | +----B----+ Using the algorithm I've seen, A would evaluate inside and B outside. Is there a quick and dirty way to handle points exactly on edges? I realize that a seperate calculation can be done to determine whether a point is on a line but this is expensive computationally isn't it? Brent corkum@ecf.toronto.edu
rusmin@twinsun.com (Rusmin Dirgantoro) (08/24/90)
In article <1990Aug23.000651.10581@twinsun.com> rusmin@twinsun.com (Rusmin Dirgantoro) writes: >In article <2018@idunno.Princeton.EDU> markv@gauss.Princeton.EDU (Mark VandeWettering) writes: >>In article <1990Aug22.022743.4139@twinsun.com> rusmin@twinsun.com (Rusmin Dirgantoro) writes: >>>In article <5990@milton.u.washington.edu> benson@blake.acs.washington.edu (Dan Benson) writes: >>>> [ ask for points in polygon algorithms ] >>> [ responds with an "almost right" algorithm ] >But his solution has a little glitch. >... >Consider this polygon... > > +--------------------------------+ > | | > | | > | D E F | >y=0 - - o - - o----o----o - - o - - o----o-----o - - o - - > A B C | | G H I > | | > | | > +-----------+ Ooops... This is not right. I'm sorry about that. After rethinking about it, I found that Mark's algorithm works in this case as well. I was out of my head. Just ignore my previous posting. Thanks for your responses, though. Bye. -- Rusmin Dirgantoro rusmin@twinsun.com Twin Sun Inc. 1(213)640-6885 office El Segundo, California 1(213)837-3941 home
rusmin@twinsun.com (Rusmin Dirgantoro) (08/24/90)
In article <1990Aug23.181401.2258@jarvis.csri.toronto.edu> corkum@csri.toronto.edu (Brent Thomas Corkum) writes: > >There's one question I have concerning this algorithm that I hope someone >can answer. It seems to me that a point exactly on an edge can evaluate >either inside or outside depending on which edge your on. >ie. > +----A----+ > | | > | | > +----B----+ >Using the algorithm I've seen, A would evaluate inside and B outside. Is >there a quick and dirty way to handle points exactly on edges? I realize >that a seperate calculation can be done to determine whether a point >is on a line but this is expensive computationally isn't it? I'm not sure what you mean by 'handle'. But.. if I'm allowed to add something here, I believe this would lead to a discussion of PMC (Point Membership Classification), a classic issue in Geometric Modeling. Points on boundaries (here, edges) always have two neighborhoods, inside the object (here, polygon) and outside. For this reason people give points on boundaries *ON* classification, not *IN* nor *OUT*. Ex: In your problem.. A has *IN* neighborhood *BELOW* and *OUT* neighborhood *ABOVE*. B has *IN* neighborhood *ABOVE* and *OUT* neighborhood *BELOW*. So, both A & B have *ON* classification. Since we ought to pick either above or below on the ray (re: Eric/Mark's algorithm), the algorithm doesn't explore enough information for points with *ON* classification. It was meant to decide only either *IN* or *OUT*. That's why the algorithm could give different answers for *ON* points. What do you think Eric? Mark? Sorry, I am not answering your questions.. just sharing a little old idea. G'day.. -- Rusmin Dirgantoro rusmin@twinsun.com Twin Sun Inc. 1(213)640-6885 office El Segundo, California 1(213)837-3941 home
zap@lysator.liu.se ("Zap" Andersson) (08/28/90)
Forgive me if I am but a fool, but I have created a very simple algorithm and I have never had any problems with the Ambiguos Ray Intersections. But perhaps my polygon storage methods help me? I simply swap all endpoints so each line has its 'first' end upwards and its 'last' end downwards. Then I simply EXCLUDE the 'first' point from the intersection test, but INCLUDE the 'last' i.e. point is on the line if first < point <= last .... I havn't been thinking to hard if this is a loser method but it works ok in my implementations.....??? /Zap