Welcome to the Onshape forum! Ask questions and join in the discussions about everything Onshape.
First time visiting? Here are some places to start:- Looking for a certain topic? Check out the categories filter or use Search (upper right).
- Need support? Ask a question to our Community Support category.
- Please submit support tickets for bugs but you can request improvements in the Product Feedback category.
- Be respectful, on topic and if you see a problem, Flag it.
If you would like to contact our Community Manager personally, feel free to send a private message or an email.
Invalid Normal Until a More-Distant Point is Used

What is going on here?
I have 3 points that are co-linear (start, mid, end) that produce an invalid normal when used with this code. If I make a 4th co-linear point that is farther away, it works fine.
It seems that when too close together it is for some reason "close to parallel". Why does OnShape let this sort of inconsistency occur?
var scaleLength = 24.75*inch; var stringHeightAtFirstHarmonic = 1*millimeter; const start_point is Vector = vector( 0*inch, scaleLength / 2, 0*inch ); const mid_point is Vector = vector( 0*inch, 0*inch, -stringHeightAtFirstHarmonic ); const end_point is Vector = vector( 0*inch, -scaleLength / 2, -2*stringHeightAtFirstHarmonic); // For some reason OnShape produces a 0 normal if mid_point is used in place of other_point. const other_point is Vector = vector( 0*inch, -scaleLength, -4*stringHeightAtFirstHarmonic); const origin = mid_point; const normal = cross( start_point - end_point, start_point - other_point ); var neckReliefPlane = plane( origin, normal ); // create fret relief sketch on side plane definition.neckReliefSketch = newSketchOnPlane(context, id + "neckReliefSketch", { "Name" : "Neck Relief Sketch", "sketchPlane" : neckReliefPlane });
Best Answer
-
EvanReese Member, Mentor Posts: 2,478 ✭✭✭✭✭
I'll kinda sidestep your question a bit to get at your goals. The cross product of parallel vectors should be a zero vector with no direction, so the case where it works seems like the odd one out. Might be a floating point precision thing making the second case just off enough to get a result from cross()? In any case, if you just need any perpendicular vector try perpendicularVector() instead of cross(). If you need to know for sure which direction that normal will go, then you could align it to something else known.
1
Answers
I think the problem is simply that it can't figure it out if they're on the same line? But why does it work then with another point on the same line?
If the points are indeed collinear, why do you expect a cross product of two parallel vectors to produce a valid normal?
I'll kinda sidestep your question a bit to get at your goals. The cross product of parallel vectors should be a zero vector with no direction, so the case where it works seems like the odd one out. Might be a floating point precision thing making the second case just off enough to get a result from cross()? In any case, if you just need any perpendicular vector try perpendicularVector() instead of cross(). If you need to know for sure which direction that normal will go, then you could align it to something else known.
The Onsherpa | Reach peak Onshape productivity
www.theonsherpa.com
@Granny Game That’s a fascinating observation — especially about how mid_point seems to break the normal.
I’m curious, could this be due to floating point precision issues in the cross() function when vectors become nearly co-linear?
Have you tried introducing a small epsilon offset in the Z or X direction to test how sensitive normal is in this case?
Also, is there any documentation on how Onshape handles degenerate or near-degenerate vector calculations in FeatureScript?
(I should also remark that
other_point
isn't collinear with the others, which is why it produces a nonzero cross product.)As for vector calculations, we don't do anything special; that's on the FS author. If three points are on the same line, you can't expect them to define a plane, so you rightly get a zero-length normal. Floating-point artifacts can give an illusion of a valid result, so you can use
parallelVectors
to test for invalid inputs, which does a tolerant comparison. You can read the math here: https://cad.onshape.com/documents/12312312345abcabcabcdeff/v/b61084c68a86eaf27d3b94ce/e/b81f3a02f1e34b7dab9d239c