Jump to content

SOLVED: Find closest point on line


Jenna Huntsman
 Share

You are about to reply to a thread that has been inactive for 820 days.

Please take a moment to consider if this thread is worth bumping.

Recommended Posts

Hey all,

My math knowledge has failed me and I need some advice:

I need to find a point on a line, with vector A being the line's origin and vector B being it's direction (the line is of infinite length).

I need to find the closest point to vector P on the line.

How can I do this?

I've been looking at these functions (from the LSL wiki) but they're producing garbage numbers:

Pulled from :http://wiki.secondlife.com/wiki/Geometric

vector gLXdV(vector O,vector D,vector A){
    return (O-A)-((O-A)*D)*D;}

vector gLXnX(vector O,vector D,vector A){
    return gLXdV(O,D,A) + A;}

//O = Origin, D = Direction, A = abitrary point.

Thanks!

 

EelDP.png

In the above example, I need to find C

 

EDIT:

Solved it, just needed to take a break

vector LinePoint(vector origin, vector dir, vector point)
{
    //This made Jenna sad :C
    vector dirNorm = (dir-origin)/llVecDist(dir,origin);
    vector x = point-origin;
    vector Lp = dirNorm*((x.x*dirNorm.x)+(x.y*dirNorm.y)+(x.z*dirNorm.z)); //offset relative to the origin
    return Lp+origin;
}

 

Edited by Jenna Huntsman
Solved, had a brainfart
Link to comment
Share on other sites

  • Jenna Huntsman changed the title to SOLVED: Find closest point on line

One minor improvement,

(x.x*dirNorm.x)+(x.y*dirNorm.y)+(x.z*dirNorm.z)

is actually the same as

(x*dirnorm)

And writing it myself because I find the problem interesting and (no offense yours might be more efficient) I find your version a bit hard to parse:

vector LinePoint(vector origin, vector dir, vector point)
{
    vector dirNorm = llVecNorm(dir-origin);
    float dist = llVecDist(dir,point);
    return origin + dirNorm*dist;
}

 

  • Thanks 1
Link to comment
Share on other sites

19 minutes ago, Quistess Alpha said:

One minor improvement,

(x.x*dirNorm.x)+(x.y*dirNorm.y)+(x.z*dirNorm.z)

is actually the same as

(x*dirnorm)

And writing it myself because I find the problem interesting and (no offense yours might be more efficient) I find your version a bit hard to parse:

vector LinePoint(vector origin, vector dir, vector point)
{
    vector dirNorm = llVecNorm(dir-origin);
    float dist = llVecDist(dir,point);
    return origin + dirNorm*dist;
}

 

No worries - the solution I came to was based on a formula I found elsewhere which (presumably) couldn't multiply vectors directly; hence writing it out long form - my brain isn't working very well today :(

  • Like 1
Link to comment
Share on other sites

oop, and it turns out your version is more correct, geometry is hard: https://en.wikipedia.org/wiki/Dot_product

vector LinePoint(vector origin, vector dir, vector point)
{
    vector dirNorm = llVecNorm(dir-origin);
    float dist = dirnorm*(point-origin);
    return origin + dirNorm*dist;
}

Was scratching my head for a bit trying to figure out what the dot product was doing in there. turns out AC and AP have different lengths. (AP is longer)

Link to comment
Share on other sites

23 hours ago, Jenna Huntsman said:

I've been looking at these functions (from the LSL wiki) but they're producing garbage numbers:

Pulled from :http://wiki.secondlife.com/wiki/Geometric

vector gLXdV(vector O,vector D,vector A){
    return (O-A)-((O-A)*D)*D;}

vector gLXnX(vector O,vector D,vector A){
    return gLXdV(O,D,A) + A;}

//O = Origin, D = Direction, A = abitrary point.

FWIW, these do work when you feed in D as a direction (D-O) already,  as a unit vector.

  • Like 2
Link to comment
Share on other sites

You are about to reply to a thread that has been inactive for 820 days.

Please take a moment to consider if this thread is worth bumping.

Please sign in to comment

You will be able to leave a comment after signing in



Sign In Now
 Share

×
×
  • Create New...