tags:

views:

263

answers:

3

I have 4 points that form some quadrilateral. The lines can't cross or anything like that, it should be a square, rectangle, rhombus, parallelogram, etc.

The lines that connect them break the field into 9 regions. With a square, it would look like a tic-tac-toe board (#), but with other shapes the lines will be at angles.

A point falls randomly into this 9-region field. I know the coordinates of the random point, as well as the coordinates of the quadrilateral's 4 corners.

Is there any way I can find which field contains the point without using the equations of the lines?

I'm basically looking for something like

if(p.x > q1.x && p.x < q4.x && p.y < q3.y) {
    //It's in the top left region
}
etc

I'm thinking that this isn't possible when using sloped lines (rather than a square/rectangle) without solving the line equations. But I thought I'd run it by the math guys first. THANKS!

+4  A: 

It may be equivalent to 'using the equations of the lines', but the obvious thing to do is to compute the affine transformation that takes your four points to the unit square (0,0), (0,1), (1,0), (1,1). To decide the location of a point, apply the transform to the point and compare the result against the unit square.

William Pursell
Hmmm... sounds complicated :)I'm doing this to easier make some if conditionals like in the original question. Doing a square or rectangle was trivial, and my code is set up to take that, so I'd rather have something similar.I understand how to use the equations of lines to determine the regions, but I'll have to make some computations and etc. and it won't be as neat as if it were a square. I'm about to do that unless anyone has better advice.So is this something that I can compute simply/easily/neatly? If not I'll probably just go with the lines. Thanks very much though.
cksubs
Not that complicated...the fourth point is determined by the other 3, and for the moment assume one point is (0,0). The other 2 points are (a,b) and (c,d). The transform is thus:(x,y) -> (D(bx-ay) , D(cy-dx)) (where D=(1/(bc-ad))So compare those values to 0 and 1. To allow for the point (p,q) instead of (0,0), just compute:(x,y) --> (D(bx-ay) - p , D(cy-dx) - q
William Pursell
(When computing for (p.q) != (0,0), adjust a,b,c,d relative to p,q
William Pursell
+1  A: 

Anything you do is effectively "using the equations of the lines", so I'm not sure what to make of that condition. I assume you just want easy inequalities to check which region the random point (x,y) is in, so that's what I'll show you how to do.

From your question, it sounds like you always have a parallelogram, so let's assume that the points are (0,0), (a,b), (c,d), and (a+c,b+d), which makes the explanation a little easier to follow. To fix your mental picture, imagine that (a,b) is roughly "to the right" of (0,0) and (c,d) is roughly "above" (0,0). Then the equations for the "horizontal" lines are -bx+ay=0 and -bx+ay=-bc+ad, so you get three possibilities, depending on how -bx+cy compares to 0 and -bc+ad:

// Assuming -bc+ad is positive
-bx+ay < 0           // it's in the "bottom row"
0 < -bx+ay < -bc+ad // it's in the "middle row"
-bc+ad < -bx+ay     // it's in the "top row"

Similarly, the equations for the "vertical" lines are dx-cy=0 and dx-cy=da-bc, so the three possibilities, depending on how dx-cy compares to 0 and to da-cb:

// Still assuming ad-bc is positive
dx-cy < 0           // it's in the "left column"
0 < dx-cy < da-cb  // it's in the "middle column"
da-cb < dx-cy      // it's in the "right column"

Of course, if da-cb is negative, then the three possibilities in each case are "less than da-cb", "between da-cb and 0", and "greater than 0" instead. Finally, if equality ever holds, then the point (x,y) is actually on one of the lines rather than in one of the regions.

Anton Geraschenko
Anton Geraschenko
Thanks, this is awesome. What do you think regarding the comment bringing up trapezoid regions though? Like I said there, I want to map the outside point to the best (I think that's *closest*) point on the edge of the shape. Because of trapezoids I don't think this tic-tac-toe approach would work. I guess I check to see if it's a trapezoid and then have some other behavior... Any better way to do it? I think the "closest point on the lines" idea is probably the way to go so I'm going to think about that for a bit.
cksubs
For finding the *closest* point that is on the edge of the shape, I don't see how determining the region of the tic-tac-toe board helps you. The only method that I can think of right now is to produce a candidate for each edge of the shape (the closest point on a particular edge is either the projection of the point onto the segment, or one of the two end points) and then check which of the four candidates is closest. If you really want to be able to think about this problem, I recommend learning about dot products (http://en.wikipedia.org/wiki/Dot_product), especially scalar projection.
Anton Geraschenko
Thanks, I'll try using the four candidate points for now. I'll perhaps dig deeper into this with dot products on the next version.
cksubs
+1  A: 
AakashM
Hmm, you're right. I meant with "the lines can't cross" that you can't get an hourglass shaped figure, but this complicates things. Damn... what I need to know is how to correctly map the point outside the region to a point on the edge of the region. With 9 tic-tac-toe regions that's easy... if it's in one of the corner regions, set it to that corner of the shape. Otherwise, set it to some point on the shape's edges. But with this new info, the blue point could be on either the left, top, or center edge, or in either of the top corners. I need to think about this better...
cksubs
@cksubs: Notice also that if you pick a point between the two horizontal red lines which is *way* off to the right, then the *closest* point on the boundary is the lower right corner, even though the point isn't in the lower right region. These regions aren't doing what you want them to.
Anton Geraschenko