|
![](/i/fill.gif) |
"Johannes Dahlstrom" <sad### [at] tkukoulu fi> wrote in
news:web.3e89ee318267de92f7cbce3c0@news.povray.org:
...
> I'd also like some insight into how to invert a transformation (4x4)
> matrix. I did a bit googling but didn't come by anything too relevant.
Below is some code that will do this for you.
A good phrase for searching texts about inversion
of matrices will be:
elementary linear algebra
Tor Olav
// ===== 1 ======= 2 ======= 3 ======= 4 ======= 5 ======= 6 ======= 7
// How to invert 3x3 and 4x4 matrices with POV SDL.
// By Tor Olav Kristensen
#macro printMatrix(MM)
#local DimR = dimension_size(MM, 1);
#local DimC = dimension_size(MM, 2);
#debug concat("array[", str(DimR, 0, 0), "]")
#debug concat("[", str(DimC,0, 0), "] {\n")
#local CntR = 0;
#while (CntR < DimR)
#debug " { "
#local CntC = 0;
#while (CntC < DimC)
#debug str(MM[CntR][CntC], 0, -1)
#if (CntC < DimC - 1)
#debug ", "
#end // if
#local CntC = CntC + 1;
#end // while
#debug " }"
#if (CntR < DimR - 1)
#debug ","
#end // if
#debug "\n"
#local CntR = CntR + 1;
#end // while
#debug "}\n"
#end // macro printMatrix
#macro det3D(v0, v1, v2)
vdot(v0, vcross(v1, v2))
#end // macro det3D
#macro invertMatrix33(MM)
#local vX = <MM[0][0], MM[0][1], MM[0][2]>;
#local vY = <MM[1][0], MM[1][1], MM[1][2]>;
#local vZ = <MM[2][0], MM[2][1], MM[2][2]>;
#local Det = det3D(vX, vY, vZ);
#local v0 = vcross(vY, vZ)/Det;
#local v1 = -vcross(vX, vZ)/Det;
#local v2 = vcross(vX, vY, vT)/Det;
array[3][3] {
{ v0.x, v1.x, v2.x }
{ v0.y, v1.y, v2.y }
{ v0.z, v1.z, v2.z }
}
#end // macro invertMatrix33
#macro vdot4D(vA, vB)
(vA.x*vB.x + vA.y*vB.y + vA.z*vB.z + vA.t*vB.t)
#end // macro vdot4D
#macro vcross4D(vA, vB, vC)
#local v00 = <vA.y, vA.z, vA.t>;
#local v01 = <vB.y, vB.z, vB.t>;
#local v02 = <vC.y, vC.z, vC.t>;
#local v10 = <vA.x, vA.z, vA.t>;
#local v11 = <vB.x, vB.z, vB.t>;
#local v12 = <vC.x, vC.z, vC.t>;
#local v20 = <vA.x, vA.y, vA.t>;
#local v21 = <vB.x, vB.y, vB.t>;
#local v22 = <vC.x, vC.y, vC.t>;
#local v30 = <vA.x, vA.y, vA.z>;
#local v31 = <vB.x, vB.y, vB.z>;
#local v32 = <vC.x, vC.y, vC.z>;
<
det3D(v00, v01, v02),
-det3D(v10, v11, v12),
det3D(v20, v21, v22),
-det3D(v30, v31, v32)
>
#end // macro vcross4D
#macro det4D(v0, v1, v2, v3)
vdot4D(v0, vcross4D(v1, v2, v3))
#end // macro det4D
#macro invertMatrix44(MM)
#local vX = <MM[0][0], MM[0][1], MM[0][2], MM[0][3]>;
#local vY = <MM[1][0], MM[1][1], MM[1][2], MM[1][3]>;
#local vZ = <MM[2][0], MM[2][1], MM[2][2], MM[2][3]>;
#local vT = <MM[3][0], MM[3][1], MM[3][2], MM[3][3]>;
#local Det = det4D(vX, vY, vZ, vT);
#local v0 = vcross4D(vY, vZ, vT)/Det;
#local v1 = -vcross4D(vX, vZ, vT)/Det;
#local v2 = vcross4D(vX, vY, vT)/Det;
#local v3 = -vcross4D(vX, vY, vZ)/Det;
array[4][4] {
{ v0.x, v1.x, v2.x, v3.x }
{ v0.y, v1.y, v2.y, v3.y }
{ v0.z, v1.z, v2.z, v3.z }
{ v0.t, v1.t, v2.t, v3.t }
}
#end // macro invertMatrix44
// ===== 1 ======= 2 ======= 3 ======= 4 ======= 5 ======= 6 ======= 7
//Examples:
#declare M33 =
array[3][3] {
{ 1, 3, -2 },
{ -7, 2, 6 },
{ 2, -1, 2 }
}
printMatrix(M33)
printMatrix(invertMatrix33(M33))
#declare M44 =
array[4][4] {
{ 1, 3, -2, 4 },
{ -7, 2, 6, 5 },
{ 2, -1, 2, -3 },
{ -3, -6, 4, 5 }
}
printMatrix(M44)
printMatrix(invertMatrix44(M44))
// ===== 1 ======= 2 ======= 3 ======= 4 ======= 5 ======= 6 ======= 7
Post a reply to this message
|
![](/i/fill.gif) |