-
bibuti.
Distance between a point and a line?
I can't seem to find a good example with easy to read documentation of this.
Has anyone done this before and has a simple example I can look at?
i'm obsessed with video games.
-
bibuti.
i'm obsessed with video games.
-
// ends of line segment.
var ax,ay,az;
var bx,by,bz;
// point
var px,py,pz;
var ab = Math.sqrt( (bx-ax)*(bx-ax) + (by-ay)*(by-ay) + (bz-az)*(bz-az) );
var bp = Math.sqrt( (px-bx)*(px-bx) + (py-by)*(py-by) + (pz-bz)*(pz-bz) );
var pa = Math.sqrt( (ax-px)*(ax-px) + (ay-py)*(ay-py) + (az-pz)*(az-pz) );
var tp = (ab+bp+pa) /2.0;
var ta = Math.sqrt(tp*(tp-ab) * (tp-bp) * (tp-pa));
var minDistance = 2.0 * (ta/ab);
-
Senior Member
Thanks! Now if I can figure out a way to do that with fewer square roots, that would be perfect...
-
Senior Member
Here's how I would do it using vectors:
Note that Point can be flash's Point class, or your own object... really anything that has x and y properties. You can also make two variables for every point pX and pY (which is probably the most efficient way) but I didn't want to clutter the code here
Code:
//the point
var p:Point = new Point(100,100)
//the line
var lineP1:Point = new Point(50,50)
var lineP2:Point = new Point(200,200)
//get the normalized vector of the line
var norm:Point = new Point(lineP2.x-lineP1.x,lineP2.y-lineP1.y)
var mag:Number = Math.sqrt(norm.x*norm.x + norm.y*norm.y)
norm.x/=mag
norm.y/=mag
//now project your point on the line
var pointVector:Point = new Point(p.x-lineP1.x,p.y-lineP1.y)
var dotProduct:Number = pointVector.x*norm.x + pointVector.y*norm.y
//now... get the point on the line closest to our point
var newPoint:Point = new Point(norm.x*dotProduct + lineP1.x, norm.y*dotProduct + lineP1.y)
//now get the distance between the points.. this is your answer
var minDist:Number = Math.sqrt(Math.pow(p.x-newPoint.x,2)+Math.pow(p.y-newPoint.y,2))
So there, only two sqrt operations...
And if your line is static, that first sqrt can be precomputed before the simulation (well, the whole normalized vector really).
None of this code is tested, but I've done it so many times, I'm pretty sure it works. If it doesn't let me know and I'll fix it...
Also as a general tip, if you want to really grasp this stuff, learn about vectors and the dot product - they are EXTREMELY useful with these kind of things
Hope that helps
Last edited by ozmic66; 07-20-2007 at 10:38 AM.
-
Senior Member
Thanks. So, dot products, you say? All I remember is that you get them by multiplying two vectors together to get a scalar. I guess I'll have to do some research then.
-
Funkalicious
I made this for a platform shooter prototype. I treated a shot as a line, and check if the enemies (which are circular in form) are on the line.
Code:
function Intersect(line1, line2) {
var a1:Number = line1[0];
var b1:Number = line1[1];
var a2:Number = line2[0];
var b2:Number = line2[1];
//
var X:Number = (b2-b1)/(a1-a2);
//trace(X)
return (X);
}
Enemy.prototype.HitTest = function(line) {
//Defining line (y=mx+b)
var m:Number = line[0];
var b:Number = line[1];
//Defining point with coordinates (k,h)
var k:Number = this.HitPos.x;
var h:Number = this.HitPos.y;
//
var r:Number = this.R // = Radius of the enemy
//
var b2 = h-(m*k)
//
var m3 = -1/m
var b3 = h-(m3*k)
//
var X2 = Intersect([m,b], [m3,b3])
var Y2 = m3*X2+b3
//
dX = X2-k
dY = Y2-h
//
var dist = Math.sqrt((dX*dX)+(dY*dY))
//trace(dist)
//
if (dist < r){
return (true)
}else{
return (false)
}
};
It's been a while since I coded this and if I remember correctly a line (y = mx + b) is defined as an array [m, b]. The reason I went this way, is that I wanted to keep using the line definitions that were already in the game. Why they were there would be going to much into the gamespecific engine.
There was a webpage I based this on, but it was lost in a format of my system drive. I believe it was something like this:
Create a second line with the same slope as the first line, which goes through the point. With that just calculate the delta X and delta Y of the two lines. This can be easily done by resolving equations in which either y or x are known, which would be your points coordinates. Then just calculate your distance.
It's not your standard way of doing it (Ozmic did a fine job explaining that), but it got me my result using just lineair functions, which would allow me to make one definition of a line and reuse that troughout my code.
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|