Finding a point on an edge


I tried with several sets of points aligned or not, and got the same consistent results on my machine.

Note that the methods based on distance (by the way suggested by Kirill) have no test and do the same calculation regardless of the points.


Possibly, to cope with the case where the point is at an extremity, this version performs well

def G6.point_within_segment3?(pt, pt1, pt2)
	x, y, z = pt.to_a
	x1, y1, z1 = pt1.to_a
	return true if x1 == x && y1 == y && z1 == z
	x2, y2, z2 = pt2.to_a
	return true if x2 == x && y2 == y && z2 == z
	(x1-x2)*(x1-x2) + (y1-y2)*(y1-y2) + (z1-z2)*(z1-z2) >= (x1-x)*(x1-x) + (y1-y)*(y1-y) + (z1-z)*(z1-z) + (x2-x)*(x2-x) + (y2-y)*(y2-y) + (z2-z)*(z2-z)

This is a big blow for me, as I always thought that using the API methods was faster than doing arithmetic computations in Ruby.


However, when we use Geom::Point3d#to_a
we get [Float,Float,Float] and not [Length,Length,Length].

I think we want to leverage the APIs == to test within tolerance.

pt1 == pt2
pt1.x == pt2.x && pt1.y == pt2.y && pt1.z == pt2.z


Your remark is very relevant, Dan. If we want to stick to Sketchup tolerance on point comparison, then we must compare length. This explodes the response time

def G6.point_within_segment4?(pt, pt1, pt2)
	x, y, z = pt.x, pt.y, pt.z
	x1, y1, z1 = pt1.x, pt1.y, pt1.z
	x2, y2, z2 = pt2.x, pt2.y, pt2.z
	return true if (x1 == x && y1 == y && z1 == z) || (x2 == x && y2 == y && z2 == z)
	(x1-x2)*(x1-x2) + (y1-y2)*(y1-y2) + (z1-z2)*(z1-z2) >= (x1-x)*(x1-x) + (y1-y)*(y1-y) + (z1-z)*(z1-z) + (x2-x)*(x2-x) + (y2-y)*(y2-y) + (z2-z)*(z2-z)

The method above gives 15 seconds on my machine.

Even if the point is on the line (so the method stops at the test of equality), it still takes 4 seconds.

This means that comparing ‘length’ is much slower than comparing floats.

In conclusion, better use the ‘Dan’ method, as it combines both performance and Sketchup tolerance. Personally I prefer this.