Search code examples
vectorlinepoint

Check if a point lies on a line vector


To get another point (r) on the line that passes through point p in the direction v we can use the following formula, and substitute any value for a:

r = p + a*v

To test if r is on the line, we must only find a value for a that satisfies. In my current implementation, I check if a is the same for each component of the vectors by reorganizing the equation for r to:

a = px - rx / vx

In code terms, this looks like the following:

boolean isPointOnLine(Vector2f r, Vector2f p, Vector2f v) {
    return (p.x - r.x) / v.x == (p.y - r.y) / v.y; 
}

However, this method does not work: If any component of v is 0, the fraction will evaluate to infinity. Hence we get an incorrect result.

How do I check if r is on the line correctly?


Solution

  • In 3D you do the following:

    If a point r=(x,y,z) is on the line with p=(px,py,pz) another point on the line and v=(vx,vy,vz) the direction calculate the following

    CROSS(v,r-p)=0
    

    or by component

    (py-ry)*vz - (pz-rz)*vy==0
    (pz-rz)*vx - (px-rx)*vz==0
    (px-rx)*vy - (py-ry)*vx==0
    

    For the 2D version, make all z-components zero

    (px-rx)*vy - (py-ry)*vx == 0
    

    No division needed, no edge cases and simple fast multiplication.

    Of course due to round-off the result will be never be exactly zero. So what you need is a formula for the minimum distance, and a check if the distance is within some tolerance

    d = abs((px-rx)*vy-(py-ry)*vx)/sqrt(vx*vx+vy*vy) <= tol