Let M
be an invertible 2x2 matrix. Let C
be a circle of radius 1 centered at (0,0). Let E
be the ellipse M*C
with semi-major axis s1
and semi-minor axis s2
. (Then s1 >= s2
.) I need to find sx
, the horizontal scale applied to C
by M
, and sy
, the vertical scale applied to C
by M
.
I can measure s1
and s2
by performing singular value decomposition on M
. (The algorithm I use is based on Pedro Gimeno's answer to Robust algorithm for 2x2 SVD. s1
is the bigger singular value and s2
is the smaller singular value.) I know that <sx,sy>
equals either <s1,s2>
or <s2,s1>
, but I don't know which one; however, if I can determine that sx > sy
, (by implementing the scalesMoreInXAxis(mat2)
function below), then I can conclude that <sx,sy> = <s1,s2>
(and vice versa if sx <= sy
).
Here is my GLSL code:
bool scalesMoreInXAxis(mat2 m){
// TODO: implement
return false;
}
void main(){
float a = M[0][0];
float b = M[1][0];
float c = M[0][1];
float d = M[1][1];
float e = (a + d) / 2.0;
float f = (a - d) / 2.0;
float g = (c + b) / 2.0;
float h = (c - b) / 2.0;
float q = sqrt(e*e + h*h);
float r = sqrt(f*f + g*g);
float s1 = q + r; // Semi major axis
float s2 = abs(q - r); // Semi minor axis
vec2 s = scalesMoreInXAxis(M) ? vec2(s1,s2) : vec2 (s2,s1);
}
What do you want to achieve? I don't understand what do you mean by semi-x axis.
However, here's what I think, how can you calculate semi axises:
let M=U*s*V (SVD decomposition)
V*C will be C, as V is just a rotation (rotating a circle wouldn't change it).
So, we left with U*s. This transformation is angle preserving. U*s will first scale the circle (so it becomes an ellipse with semi axises s*[1 0]' and s*[0 1]'), and then rotate it. So, the final semi axises are U*s*[1 0]' and U*s*[0 1]', which are the columns of U*s.
Note: for a general matrix, there is no such question that "how does it scale in the horizontal direction". All one can say is how much scale happened for the original x-axis (I mean, how long become the original x-axis after the transformation), which is just the length of M*[1 0]', the length of the first column.