Test Point3d position tolerance?
-
I'm comparing 2 point 3ds trying to determine if they are the same 3d location or not. They are each within different groups with different transformations applied to them. So they sometimes are off by some tiny little decimal or something.
So how do I accurately test the 3d position of points like this? I though there was some tolerance intelligence built into SU. But I didn't see anything in the API 9plus its 03:00 in the morning here, so my eyes are blurry).
Anyone know how to handle this correctly? Thanks!
Chris
-
After transformations you do indeed get minor flakiness in points.
Try converting them to arrays and processing each array's x/y/z so it's rounded by by a d.p.
Then compare the arrays - they'll probably come out equal ?
You need to decide the level of accuracy
pt1.x=0.0001 pt1.x=sprintf("%.3f",pt1.x).to_f etc to make it 0.0 to 3dp
This is clunky and you could write a faster way like
pt1.x=(100.0*pt1.x).round/0.01
or even make your own method to call passing the xyz floats and the dp as arguments - something like this...
def re_dp(n,p) n=n.to_f; p=p.to_i return ((n*10**p).round.to_f/10**p).to_f end
Usage:
points.each{|pt| pt.x=re_dp(pt.x, 3) pt.y=re_dp(pt.y, 3) pt.z=re_dp(pt.z, 3) }
etc to process an array of points to 3dp accuracy -
Chris,
Because of finite precision math computers use, this is a common problem.
Generally you compare positions by checking that the length of a vector between the 2 points is shorter than an epsilon of your choosing since you don't know whether errors are bumping you to -inf or +inf.
delta = pointa - pointb
if (delta.dot(delta) < 1e-4)
..same position
endThe really scary thing that many people don't realise is that the finite precision used by computer floating point means that multiply isn't always Commutative. ie you can get a different answer for ab than ba! This causes huge problems for systems that need to be able to exactly repeat a simulation etc.
-
Thanks TIG, I was trying to compare arrays and it was not working. I had tried comparing lengths, letting SU do the converting and raounding, but that seemed to turn things into strings which would slow me down. In the end, Adam's got a nifty method here.
Adam, that is awesome. Thank you for the simple example. It fit into my code very nicely.
-
@chris fullmer said:
Thanks TIG, I was trying to compare arrays and it was not working.
Convert to Point3d objects and compare them. Should be using the SketchUp precision.
-
sure, but if the transform bumps you out of the SU tolerance, you're hosed.
Advertisement