A Flash Developer Resource Site

Results 1 to 7 of 7

Thread: Distance between a point and a line?

  1. #1
    bibuti. nolen's Avatar
    Join Date
    Sep 2002
    Location
    az.
    Posts
    191

    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.

  2. #2
    bibuti. nolen's Avatar
    Join Date
    Sep 2002
    Location
    az.
    Posts
    191
    Anyone?
    i'm obsessed with video games.

  3. #3
    Senior Member
    Join Date
    Nov 2003
    Posts
    524
    // 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);

  4. #4
    Senior Member axcho's Avatar
    Join Date
    Jun 2006
    Posts
    113
    Thanks! Now if I can figure out a way to do that with fewer square roots, that would be perfect...

  5. #5
    Senior Member ozmic66's Avatar
    Join Date
    Oct 2005
    Posts
    472
    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.
    Pixelwave Flash-based iPhone framework
    iPhone Games: Flyloop | Freedom Run

    Twitter: Oztune

  6. #6
    Senior Member axcho's Avatar
    Join Date
    Jun 2006
    Posts
    113
    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.

  7. #7
    Funkalicious TOdorus's Avatar
    Join Date
    Nov 2006
    Location
    Nijmegen, Netherlands
    Posts
    697
    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
  •  




Click Here to Expand Forum to Full Width

HTML5 Development Center