What is the best way to check if a point is on a line

Hi all,

what is the best whay to check if a point is on a line (point between start and endpoint of the line).
I was thinking of collinear vectors but in this case i have to create first a vector.

Any tip is welcome

You can use this method and check against a tolerance distance:

https://developer.rhino3d.com/api/RhinoCommon/html/M_Rhino_Geometry_Line_DistanceTo.htm

If you interested in a math approach:
Substract the point to test from the line starting point. you‘ll get a vector. The other vector is the endpoint - startpoint of the line. Now if the unitized dot product of both vectors is 1 then they are parallel, and if the length of the first vector is smaller then the second one, the point is within the finite line.

haha thats what i try at moment but i need colinear not only parallel…have to check the dot product

so you‘ll need an not-finite solution. Then forget about the length comparison and also test for -1 (antiparallelity) Be aware that you need to unitze the vectors when applying the dot product.

TomTom i use this method (maybe it works somehow also for 3d vector not only 2d).

In my case is the Z value for all points the same.
It works here is the code

import Rhino as rh

a = []
for i in y:
    sp = i.PointAtStart
    ep = i.PointAtEnd
    vecl = ep-sp
    rvecl = rh.Geometry.Vector3d(round(vecl.X),round(vecl.Y),round(vecl.Z))
    for p in x:
        vecp = p-sp
        rvecp = rh.Geometry.Vector3d(round(vecp.X),round(vecp.Y),round(vecp.Z))
        if (rvecl.X*rvecp.Y)-(rvecl.Y*rvecp.X) == 0:
            a.append(i)

Thanks for all the help

# input -> pt as Point3d; line as Vector3d
# get both vectors
vecA = pt - line.From
vecB = line.To - line.From

# retreive its length
lengthA = vecA.Length
lengthB = line.Length

# make length = 1 for both vectors
vecA.Unitize()
vecB.Unitize()
# calculate the dot 
dot = vecA * vecB

print (dot)

a = False
# if the dot is close to 1 the point is on the line 
if (dot > 0.99999 and dot < 1.00001):
    # length A needs to be smaller to be within finite range 
    if (lengthA <= lengthB):
        a = True


This is what I was talking about above, works in 3d space.

1 Like

Is there a reason not to use Line.DistanceTo(Point)? That seems like a better, or at least much terser, way to me (outside of satisfying mathematical curiosity of course :nerd_face:).

1 Like

Or even the ready-made Grasshopper component “Curve Closest Point”?

1 Like

Hm…in the end i want to calculate the weights on each hanging point…(the picture represents a rig in a fair hall above a booth and the point are the lamps etc).
Like in this answer Result forces on a grid
To calculate the weights i need the distance between PointAtStart and the points in between (start and end of the line) and if i use vectors at the beginning it is simple to get the length.

The other thing is the line and polyline type…if i use only a vector (StartEndPoint) i can avoid any error because of the geometry.type.

Im a total noob i have not a really solid reason not to use your solution…just testing and learning.
Hope it makes sens in any kind.:upside_down_face:

1 Like

I’m not sure this is giving you exactly what you want. The co-linear vector approach does not ensure that the point is between the start and end of the line, and the rounding applied means that nearby points are included, as shown by these test points which result in three hits rather than one:
image

@TomTom’s solution can be adopted, as can @AndersDeleuran’s, to output distance from the start point if that is what you need, e.g.:
image

Regards
Jeremy

1 Like