|
|
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
|
|