Skip to main content
GameDev.net gamedev.net
🔒 Locked

Point inside a quad? (Solved!)

Started by RuneLancer Jun 26, 2005 at 1:31 AM 4 replies 8.9k views
Original Post
RuneLancer
RuneLancer
This one should be real easy, but I actually found nothing while hunting around on google. The best I could come up with were winded debates on how to find if a point is inside a (2D) polygon. Close, but not quite what I want as it doesn't take height into account. Maybe I'm just not looking for the right terms. :/ Let's suppose I have a 3D surface that's essentially a heightmap. Given a list of polygons and an X,Z position, I want to find... - Which polygon the object sits atop of (there are no overlapping polygons, by the way) - At which point along the Y axis the object would intersect the polygon if, say, I were to let it "drop" down to the ground. Any assistance would be greatly appreciated. :) Edit: My trig know-how is pretty limited, so be gentle. :P Explanations on how this works would most certainly benefit me in the future though. [Edited by - RuneLancer on June 26, 2005 4:38:17 PM]
Zakwayda
Zakwayda
For finding the y given an x and z, you could use bilinear interpolation, or barycentric or parametric coordinates. If the heightmap is a regular grid, identifying the appropriate quad or triangle is trivial; if it's irregular you might have to do a little more work. Anyway, ask if you need further details.
RuneLancer
RuneLancer
I have no idea what barycentric/parametric coordinates have to do with my problem (like I said, I'm not quite fluent in this domaine so the link isn't very obvious ;) ) and all's bilinear interpolation turned up were image filtering algorithms. I did find a means of telling wether a point is inside a triangle while hunting for some of these terms, however. :)

I split my quads into two triangles. Works well enough, however, so that pretty much solves my first problem unless someone has a better solution. Basically, if fAB * fBC > 0 and fBC * fCA > 0 the point is inside.
fAB = (y-y1) * (x2-x1) - (x-x1) * (y2-y1)
fBC = (y-y2) * (x3-x2) - (x-x2) * (y3-y2)
fCA = (y-y3) * (x1-x3) - (x-x3) * (y1-y3)
X and Y are the coordinates of the point, and the other x/ys are the points defining the triangle. Works well enough, though it seems like an awful lot of calculations.

All's I'm stuck with now is finding the height at a given point in my quad. Unfortunately, the quads are irregular and could be shaped anything. That is, I don't have nice even-lenghted sides with 90' angles at all four corners. They could be any shape, since it's for a map engine.

Any help on that last point would be greatly appreciated. :) For the time being, I'm just setting the height of the player to the height of the first point in the quad, which is not a valid solution at all...
Zakwayda
Zakwayda
Ok, it's not a regular heightfield, and I assume the quads aren't necessarily planar, so (as you are doing already) they will need to be dealt with as a triangle pair to get accurate results.

You're currently using a perp-dot (determinant) predicate to determine point-triangle containment. This is pretty standard and isn't an unreasonable number of calculations to devote to the problem. This is especially true given that it also gives you the information you need to solve your other problem, that is, finding the y value corresponding to your x and z.

Backing up for a second, barycentric coordinates are a way of parameterizing space in terms of a set of points and their associated weights. Information on this subject should be plentiful online, so I'll cut to the chase and try to sketch out the code you're looking for:

float invSum = 1.0f / (fAB + fBC + fCA);
float b1 = fBC * invSum;
float b2 = fCA * invSum;
float b3 = 1.0f - b1 - b2;
y = b1 * y1 + b2 * y2 + b3 * y3;

Can't guarantee I got that exactly right, but you might try it out and see if it works.
RuneLancer
RuneLancer
After a bit of tweaking, I managed to get it to work properly. :D I can't begin to thank you enough, this thing had me completely stumped, and my deficient math skills didn't help the case much.

You've made a fellow programmer's day. Thanks man. :)

Zakwayda
Zakwayda
Great, I'm glad it worked! :-)

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.