POV-Ray : Newsgroups : povray.advanced-users : A couple of questions about matrix transformations : Re: A couple of questions about matrix transformations Server Time
29 Jul 2024 02:20:10 EDT (-0400)
  Re: A couple of questions about matrix transformations  
From: Tor Olav Kristensen
Date: 1 Apr 2003 18:08:30
Message: <Xns9351BE217AE5torolavkhotmailcom@204.213.191.226>
"Johannes Dahlstrom" <sad### [at] tkukoulufi> 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

Copyright 2003-2023 Persistence of Vision Raytracer Pty. Ltd.