POV-Ray : Newsgroups : povray.text.tutorials : How to transform a triangle into another Server Time
28 Mar 2024 10:37:29 EDT (-0400)
  How to transform a triangle into another (Message 1 to 2 of 2)  
From: Tor Olav Kristensen
Subject: How to transform a triangle into another
Date: 2 Oct 2002 19:41:55
Message: <3D9B843D.E5392CD0@hotmail.com>
My first post to this group !

Peter Popov mentioned in this thread;
http://news.povray.org/povray.advanced-users/27685/
(25. September 2002. Subject: Re: Align box to splines)
- the existence of a macro that transforms a triangle into another one.

I thought his was an interesting problem, so I just had to try to make
such a macro. Below are the results.

The code shows the macro and how it can be used. I have also shown how
to find a transformation that will transform a pyramid into another one.

Note that the transformation returned by the macro(s) can be used to
transform any POV object (not only triangles and pyramids.)

Comments or questions are welcome.


Tor Olav


// ===== 1 ======= 2 ======= 3 ======= 4 ======= 5 ======= 6 ======= 7
// Copyright 2002 by Tor Olav Kristensen
// Email: t o r _ o l a v _ k [ a t ] h o t m a i l. c o m
// http://home.no/t-o-k/povray
// ===== 1 ======= 2 ======= 3 ======= 4 ======= 5 ======= 6 ======= 7

#version 3.5;
#include "colors.inc"
#include "transforms.inc"

// ===== 1 ======= 2 ======= 3 ======= 4 ======= 5 ======= 6 ======= 7

// Macro for finding the transformation that will transform triangle A
// into triangle B
#macro Triangle2Triangle_Trans(pA0, pA1, pA2, pB0, pB1, pB2)

  #local vFx = pA1 - pA0;
  #local vLx = pB1 - pB0;
  #local vFy = vcross(vFx, pA2 - pA0);
  #local vLy = vcross(vLx, pB2 - pB0);
  #local vFz = vcross(vFx, vFy);
  #local vLz = vcross(vLx, vLy);
  #local TransF = Matrix_Trans(vFx, vFy, vFz, pA0)
  #local TransL = Matrix_Trans(vLx, vLy, vLz, pB0)
  #local InvTransF = transform { TransF inverse }
  #local InvTransL = transform { TransL inverse }
  #local p1F = vtransform(pA1, InvTransF);
  #local p1L = vtransform(pB1, InvTransL);
  #local p2F = vtransform(pA2, InvTransF);
  #local p2L = vtransform(pB2, InvTransL);
  #local Trans = transform { scale <p1L.x/p1F.x, 1, p2L.z/p2F.z> }
  #local SXZ = (p2L - vtransform(p2F, Trans)).x/p2L.z;
  #local Trans = transform { Trans Shear_Trans(x, y, z + SXZ*x) }

  transform { InvTransF Trans TransL }

#end // macro Triangle2Triangle_Trans


// Macro for finding transformation that will transform Pyramid A
// into Pyramid B
#macro Pyramid2Pyramid_Trans(pA0, pA1, pA2, pA3, pB0, pB1, pB2, pB3)

  #local vFx = pA1 - pA0;
  #local vLx = pB1 - pB0;
  #local vFy = vcross(vFx, pA2 - pA0);
  #local vLy = vcross(vLx, pB2 - pB0);
  #local vFz = vcross(vFx, vFy);
  #local vLz = vcross(vLx, vLy);
  #local TransF = Matrix_Trans(vFx, vFy, vFz, pA0)
  #local TransL = Matrix_Trans(vLx, vLy, vLz, pB0)
  #local InvTransF = transform { TransF inverse }
  #local InvTransL = transform { TransL inverse }
  #local p1F = vtransform(pA1, InvTransF);
  #local p1L = vtransform(pB1, InvTransL);
  #local p2F = vtransform(pA2, InvTransF);
  #local p2L = vtransform(pB2, InvTransL);
  #local p3F = vtransform(pA3, InvTransF);
  #local p3L = vtransform(pB3, InvTransL);
  #local Trans =
    transform { scale <p1L.x/p1F.x, p3L.y/p3F.y, p2L.z/p2F.z> }
  #local SXZ = (p2L - vtransform(p2F, Trans)).x/p2L.z;
  #local Trans = transform { Trans Shear_Trans(x, y, z + x*SXZ) }
  #local SZY = (p3L - vtransform(p3F, Trans)).z/p3L.y;
  #local Trans = transform { Trans Shear_Trans(x, y + z*SZY, z) }
  #local SXY = (p3L - vtransform(p3F, Trans)).x/p3L.y;
  #local Trans = transform { Trans Shear_Trans(x, y + x*SXY, z) }

  transform { InvTransF Trans TransL }

#end // macro Pyramid2Pyramid_Trans

// ===== 1 ======= 2 ======= 3 ======= 4 ======= 5 ======= 6 ======= 7
// Example problem

// Initial position of triangle/pyramid
#declare pA0 = <2, 3, 1>;
#declare pA1 = <4, 3,  1>;
#declare pA2 = <5, 0, -2>;
#declare pA3 = <8, 7, -1>/2;

// Position to transform it into
#declare pB0 = <1, 5, 2>;
#declare pB1 = <-2, -2, -2>;
#declare pB2 = <-2, 3, -1>;
#declare pB3 = <1, 6, -5>/2;

// Indicate where it should end up
sphere { pB0, 0.1 pigment { color Red } }
sphere { pB1, 0.1 pigment { color Green } }
sphere { pB2, 0.1 pigment { color Blue } }
sphere { pB3, 0.1 pigment { color Black } }


#declare pAmid = (pA0 + pA1 + pA2)/3;

#declare RingTexture =
  texture {
    pigment {
      object {
        difference {
          sphere { pAmid, 0.42 }
          sphere { pAmid, 0.37 }
        }
        color White
        color Blue
      }
    }
  }


#declare TriangleA =
  union {
    triangle {
      pA0, pA1, pA2
      texture { RingTexture }
    }
    sphere {
      pAmid, 0.2
      pigment { color Blue + Grey }
    }
  }

TriangleA


#declare TriangleB = 
  object {
    TriangleA
    Triangle2Triangle_Trans(
      pA0, pA1, pA2,
      pB0, pB1, pB2
    )
  }

TriangleB


#declare PyramidA =
  union {
    sphere { pA0, 0.04 }
    sphere { pA1, 0.04 }
    sphere { pA2, 0.04 }
    sphere { pA3, 0.04 }
    cylinder { pA0, pA3, 0.04 }
    cylinder { pA1, pA3, 0.04 }
    cylinder { pA2, pA3, 0.04 }
    pigment { color White*2 } 
  }

PyramidA


#declare PyramidB =
  object {
    PyramidA
    Pyramid2Pyramid_Trans(
      pA0, pA1, pA2, pA3,
      pB0, pB1, pB2, pB3
    )
  }

PyramidB

// ===== 1 ======= 2 ======= 3 ======= 4 ======= 5 ======= 6 ======= 7

light_source {
  <10, 5, -10>
  color White
  shadowless
}

background { color Gray30 }

cylinder { 0*x, 10*x, 0.03 pigment { color Red } }
cylinder { 0*y, 10*y, 0.03 pigment { color Green } }
cylinder { 0*z, 10*z, 0.03 pigment { color Blue } }

camera {
  location <4, 2, -8>
  look_at <1, 1, 0>
  
}

// ===== 1 ======= 2 ======= 3 ======= 4 ======= 5 ======= 6 ======= 7
/*

// Macro for solving system of 3 equations with 3 unknowns
#macro S3E3U(vA, vB, vC, vD)

  (<vdot(vD, vcross(vB, vC)),
    vdot(vA, vcross(vD, vC)),
    vdot(vA, vcross(vB, vD))>/
    vdot(vA, vcross(vB, vC)))

#end // macro S3E3U


// Macro for finding the transformation that will transform triangle A
// into triangle B (Does only work properly on _flat_ triangles)
#macro TriangleToTriangle_Trans(pA0, pA1, pA2, pB0, pB1, pB2)

  #local vX = <pA0.x, pA1.x, pA2.x>;
  #local vY = <pA0.y, pA1.y, pA2.y>;
  #local vZ = <pA0.z, pA1.z, pA2.z>;
  #local v0 = S3E3U(vX, vY, vZ, <pB0.x, pB1.x, pB2.x>);
  #local v1 = S3E3U(vX, vY, vZ, <pB0.y, pB1.y, pB2.y>);
  #local v2 = S3E3U(vX, vY, vZ, <pB0.z, pB1.z, pB2.z>);

  transform {
    matrix <
      v0.x, v1.x, v2.x,
      v0.y, v1.y, v2.y,
      v0.z, v1.z, v2.z,
         0,    0,    0
    >
  }

#end // macro TriangleToTriangle_Trans

*/
// ===== 1 ======= 2 ======= 3 ======= 4 ======= 5 ======= 6 ======= 7


Post a reply to this message

From: Tor Olav Kristensen
Subject: Re: How to transform a triangle into another
Date: 2 Oct 2002 19:54:05
Message: <3D9B8717.54BED636@hotmail.com>
Tor Olav Kristensen wrote:
> 
> My first post to this group !
> 
> Peter Popov mentioned in this thread;
> http://news.povray.org/povray.advanced-users/27685/
> (25. September 2002. Subject: Re: Align box to splines)
> - the existence of a macro that transforms a triangle into another one.
> 
> I thought his was an interesting problem, so I just had to try to make
> such a macro. Below are the results.
>...

I just noticed that it was not wise of me to remove the vnormalize()
expressions from the 4 first lines in the Triangle2Triangle_Trans()
macro. Here's how these lines should be:

#local vFx = vnormalize(pA1 - pA0);
#local vLx = vnormalize(pB1 - pB0);
#local vFy = vcross(vFx, vnormalize(pA2 - pA0));
#local vLy = vcross(vLx, vnormalize(pB2 - pB0));


Tor Olav


Post a reply to this message

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