Sketchup internal matrix transformation error compensation ?
-
Greetings.
I've been doing some strange things to my poor Sketchup installation these past few days. Recently, I tried sending a few dozen transformation matrices obtained by external means, and appyling them to a component and here's what happened :
-These transformations are local, i.e. I need to move my component back to the origin, rotate it back to the last transformation I kept in memory, compensate once more so that the axes are aligned to the global axes, multiply by the transformation, and then multiply by the inverses of the first three matrices.
-I handled that in Sketchup, which is probably not the best choice. However, all the matrices except for the transformation generated from elsewhere, are created using transformation.new, whether it be a new axes transformation, a new translation, or a new rotation, each time with the corresponding constructor.
-After a few hundred, sometimes a few dozen only, transformations, the component instance's transformation matrix's rotation component (that was a mouthful) would completely stop being orthogonal, and the component would scale off to infinity in one direction and to zero in the others. I.e, numerical unstability, which I didn't think would happen.
-The rotation matrices are double precision. After multiplying a few hundred of them together outside of SU, the relative error I get is much much smaller than the one in SU. It is around 10^-4 mm , which is still almost negligible, and definitely not visible to the human eye.
So what did I do ? I added a simple method for compensating the 'deorthogonalisation' of the component instance transformation, and the error stays at minuscule amounts. I'm worried that some form of desynchronisation and slight numerical inaccuracy might happen if I apply thousands of transformations, but so far I haven't seen any major or even minor differences. It therefore seems not to be a problem anymore, for me anyway.
But, I'm a curious individual. So my question : Does SU handle this deorthogonalisation internally and if so, how ? I'm assuming this phenomenon can happen regardless of where the transformations come from, and is either compensated or made to never happen (using specific constraints, or a different internal representation, perhaps). If it is the former, then why does this desynchronisation happen when sending external transformations ?
I hope I'm being clear enough. Good day to ye, anyway.
-
Some more info would be helpful in figuring this out:
- In what form are you "sending a few dozen transformation matrices"?
- How are you applying these to SketchUp entities? Are you making Geom::Transformation objects from them? If so, how (what versions of Transformation#new)? If not, are you doing your own transformations somehow?
SketchUp will tolerate a skewed (non-orthogonal) transformation if you manage to create one; it does not automatically "repair" such because it doesn't know how or why you made it that way. But it doesn't do anything that should cause any greater numerical "drift" than any other computer math. That's why the questions above are important.
-
Do you have some code snippet to share the illustrate what you describe. It's otherwise hard to figure out exactly what is going on here .
-
I don't have any code right now, I will once I have access to it though, which should be in a couple of days.
The general procedure works like this though.
Before anything else, I store the initial orientation by making an axes type Transformation. Something like this if memory serves well :
xaxis_ = cInst.transformation.xaxis yaxis_ = cInst.transformation.yaxis zaxis_ = cInst.transformation.zaxis @transform = Geom;;Transformation.axes(Geom;;Point3d.new(0,0,0),Geom;;Vector3d.new(xaxis_.x,xaxis_.y,xaxis_.z),Geom;;Vector3d.new(yaxis_.x,yaxis_.y,yaxis_.z),Geom;;Vector3d.new(zaxis_.x,zaxis_.y,zaxis_.z))
The translations to move to and from the origin are created using the center of the bounds of the component.
The origin to object axes are also calculated with an axes type Transformation. I use the inverse to return from global to local.
The rotation part of the external transformation is created from an array, with indices 3, 7, 11, 12, 13, 14 set to 0 and index 15 set to 1. Said array comes from extracting numbers from a string. I thought there might be some bug or some accuracy loss here, but it's a double to float conversion on mostly small numbers, and checking the orthogonality of the rotation component gives no error before the 12th digit.
The translation part (which is global, not relative to the component, btw) is used to make a vector used to make a Transformation. I've had the skewing even when this was 0, though.
And then it goes like this :
-Store initial transformation.
When transformation is received :
-move to origin
-switch from object to origin axes
-Compensate the initial transformation if there is one.
-Apply rotation
-apply the inverse of the initial transformation
-go to object axes
-Apply translation (global)
-Move back from the originGranted, it's not the best workflow. However, given the accuracy I seem to have on the sole matrix that isn't created within SU, I don't understand how the skewing happens, particularly when multiplying all these external matrices together yields an error that is so tiny.
Advertisement