[Closed] Getting Negative Scale from Matrix3
Hi all,
I’m trying to get the Negative scale from a Matrix3. Now normally to get the Scale I use the function below, but the issue I’m having is that it alway makes the scale positive by the end of it. Is there anyway of getting it ?
Matrix3 cmat = node->GetNodeTM(t);
Matrix3 nodeRotTM = cmat;
nodeRotTM.NoTrans();
nodeRotTM.NoScale();
Matrix3 nodeScaleTM = cmat;
nodeScaleTM *= Inverse(nodeRotTM);
Point3 scale;
Point3 tempPos;
Quat tempQuat;
DecomposeMatrix(nodeScaleTM, tempPos, tempQuat, scale);
I’m not sure there’s a way to do it… I’m working these days in a Geometry3D API in C# and I’m just right now with matrix decomposing.
As I have read, the only thing we can know is if there’s an odd number of negative scaling (one axis or three axis) if the determinant is negative. But we can’t know what axis are they.
Searching for “SpectralDecomp” (thanks, DenisT) I have reached “Polar Matrix Decomposition” by Ken Shoemake, that seems to do the trick. You can find the C++ code in https://github.com/erich666/GraphicsGems/tree/master/gemsiv/polar_decomp but still not sure about it (I think there is not just one way to get a transform matrix as negative scales can be performed by a combination of rotations). I’ll try to convert this code to C# and see what I get.
For the scaling part without its sign, you can just find the length of the three matrix rows:
scaleX = length matrix3.Row1
scaleY = length matrix3.Row2
scaleZ = length matrix3.Row3
After some searching and tests…
The 3dsMax SDK gives at least 3 matrix decomposing methods: DecomposeMatrix, SpectralDecomp and DecompAffine.
- DecomposeMatrix: gives good scale but always positive. Rotation doesn’t match (by far) the maxscript result with Matrix3.rotationPart that seems to be the correct one.
- SpectralDecomp: gives good sign for scale, but bad values for both scale and rotation. With ‘bad values’ I mean that they don’t match at all maxscript results nor for scale, nor for rotation
- DecompAffine: this method uses the “Polar Matrix Decomposition” by Ken Shoemake. It gives good scale values but always positive (same as DecomposeMAtrix and maxscript) and the determinant sign (which is negative if there are odd negative scales). Rotation part fits maxscript too.
When trying SDK Matrix3.NoScale() I get a rotation matrix without scale part that:
- fits rotation with DecompAffine and maxscript when there aren’t negatives scales, but not if there are negative scales. This method fits exactly the one I have developped after my research that finds rotation part by iterating until the matrix ‘N = (transpose(inv(M)) + M)/2; M = N’ doesn’t change.
Now, really, I don’t know what to think… But I would like to find the SpectralDecomp algorithm as it seems to be the only one that gives correct signs to scale values… and only that!
Hi Guys,
Thanks for all the help, unfortunately as aaandres sayes, SpectralDecomp gives bad values depending on the rotation of the object. I’ll keep looking into it, and if I find anything I’ll post it up here. Surely there has gotta be a way xD
Does this mean that we can’t rely on the scale property of matrices?
It’s worse than that, Jorge. We can’t rely nor in the scale (its sign), nor in rotation. The only truth is that their combination gives the same result.
It’s easy to see: create a Teapot and scale it -1 in the Z axis (vertical mirror) then -1 in the X axis (XZ mirror). The result of both scales is exactly the same than rotating it 180 degrees around the Y axis.
It’s impossible to know how you’ve got to this situation. Was it a rotation or was it two negative scales? The same applies in all cases where negative scaling is possible/allowed.
I see. I was concerned because I have an old tool that splits an algorithm based on the scale of the object But it was surprising that I never had a problem, which could be just a matter of luck. I thought the scale property was returning wrong values sometimes.
I guess if the object has negative scales on 2 axis it would be the “same” as looking at it as a rotated object? Not really the same though.
That is. Or three negative scales the same than one negative scale plus a rotation. More than this, you can put the negative scale in any of the three axis and find a rotation that fits with it.
By chance, absolute scale values are OK for each axis.
“For the scaling part without its sign, you can just find the length of the three matrix rows:
scaleX = length matrix3.Row1
scaleY = length matrix3.Row2
scaleZ = length matrix3.Row3”
By the way, this is only true if the matrix is orthogonal (each vector row is perpendicular to each other), not for stretched/skewed matrix.