     POV-Ray : Newsgroups : povray.text.tutorials : How to transform a triangle into another Server Time 6 Dec 2023 20:28:20 EST (-0500) 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>    ```
{
"@context": "https://schema.org",
"@type": "DiscussionForumPosting",
"@id": "#3D9B843D.E5392CD0%40hotmail.com",
"headline": "How to transform a triangle into another",
"dateCreated": "2002-10-02T23:41:55+00:00",
"datePublished": "2002-10-02T23:41:55+00:00",
"author": {
"@type": "Person",
"name": "Tor Olav Kristensen"
}
}
My first post to this group !

Peter Popov mentioned in this thread;
(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.)

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
}

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
```    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>    ```
{
"@context": "https://schema.org",
"@type": "DiscussionForumPosting",
"@id": "#3D9B8717.54BED636%40hotmail.com",
"headline": "Re: How to transform a triangle into another",
"dateCreated": "2002-10-02T23:54:05+00:00",
"datePublished": "2002-10-02T23:54:05+00:00",
"author": {
"@type": "Person",
"name": "Tor Olav Kristensen"
}
}
Tor Olav Kristensen wrote:
>
> My first post to this group !
>
> Peter Popov mentioned in this thread;
> (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
```        