|
![](/i/fill.gif) |
"Timothy R. Cook" wrote:
>
> Is there a way to rotate an object around its local coordinate
> axes? What I have is this:
>
> Box
> scale [ 34.000 10.000 60.000]
> rotate [ 5.000 -53.975 0.000]
> transl [-44.000 21.000 -8.000]
> local coords
> scale [ 1.000 1.000 1.000]
> rotate [ 0.000 0.000 0.000]
> transl [ -1.000 1.000 0.000]
>
> I am trying to make it intersect points
> A [-32.000 0.000 76.000]
> B [-88.000 16.000 -40.000]
> C [ 0.000 26.000 24.000]
> to difference it from an object. I have it rotated to where
> I want it XY, but when I try rotating it around its Z axis,
> it rotates around the WORLD axis, not its own, and the local
> coordinate rotation just shears the box at whatever angle,
> not at all what I want.
>
> So, what do I do to get the effect I want? If I need to
> rotate it on the real-world axes, what formulas do I use
> to figure out all 3 angles at the same time?
I saw this post at the news web-pages at the POV-
Ray server (messages digest) and then made a
script file in order to try to solve your problem.
Unfortunately I realized too late that this was a
moray-related question. =(
But I'll post the code anyway in case anyone is
interested.
Tor Olav
// ===== 1 ======= 2 ======= 3 ======= 4 ======= 5 ======= 6 ======= 7
// Copyright 2001 by Tor Olav Kristensen
// Email: tor### [at] hotmail com
// http://www.crosswinds.net/~tok
// ===== 1 ======= 2 ======= 3 ======= 4 ======= 5 ======= 6 ======= 7
#version 3.5;
#include "colors.inc"
// ===== 1 ======= 2 ======= 3 ======= 4 ======= 5 ======= 6 ======= 7
// The camera equipment
camera {
location <-50, -10, 300>
look_at <0, 0, 0>
}
light_source {
<-1, -1, 1>*1000
color White
shadowless
}
// ===== 1 ======= 2 ======= 3 ======= 4 ======= 5 ======= 6 ======= 7
// Some useful macros
#macro AxisRotateMatrix(vAxis, Angle)
#local Phi = radians(Angle);
#local Cos = cos(Phi);
#local Sin = sin(Phi);
#local vL = vnormalize(vAxis);
#local vM = vL*(1 - Cos);
matrix <
vM.x*vL.x + Cos, vM.y*vL.x + vL.z*Sin, vM.z*vL.x - vL.y*Sin,
vM.x*vL.y - vL.z*Sin, vM.y*vL.y + Cos, vM.z*vL.y + vL.x*Sin,
vM.x*vL.z + vL.y*Sin, vM.y*vL.z - vL.x*Sin, vM.z*vL.z + Cos,
0, 0, 0
>
#end // macro AxisRotateMatrix
#macro ReorientMatrix(vAxis1, vAxis2)
#local v1 = vnormalize(vAxis1);
#local v2 = vnormalize(vAxis2);
#local vU = vcross(v1, v2);
#local Dot = vdot(v1, v2);
#local v0 = vnormalize(vU);
#local vW = (1 - Dot)*v0;
#local vA = v0.x*vW;
#local vB = v0.y*vW;
#local vC = v0.z*vW;
matrix <
vA.x + Dot, vA.y + vU.z, vA.z - vU.y,
vB.x - vU.z, vB.y + Dot, vB.z + vU.x,
vC.x + vU.y, vC.y - vU.x, vC.z + Dot,
0, 0, 0
>
#end // macro ReorientMatrix
#macro vTransform(v0, Transform)
#local Fn = function { transform { Transform } }
Fn(v0.x, v0.y, v0.z)
#end // macro vTransform
// ===== 1 ======= 2 ======= 3 ======= 4 ======= 5 ======= 6 ======= 7
// Now work with the problem (as I understood it)
// Deifne a box
#declare InitialBox = box { -<2, 0.1, 1.5>, <2, 0.1, 1.5> }
// And it's centre
#local pCtr = <0, 0, 0>;
// Decide how to transform it in world coordinates
#declare WorldTrans =
transform {
scale <34.000, 10.000, 60.000>
rotate <5.000, -53.975, 0.000>
translate <-44.000, 21.000, -8.000>
}
// DoItToIt
#declare OnceTransformedBox =
object {
InitialBox
transform { WorldTrans }
}
// Decide how to transform it locally
#declare LocalTrans =
transform {
scale <1, 1, 1>
rotate <0, 0, 0>
translate <-1, 1, 0>
}
// DoItToIt
#declare TwiceTransformedBox =
object {
OnceTransformedBox
transform { WorldTrans inverse }
transform { LocalTrans }
transform { WorldTrans }
}
// Uncomment to see it now:
//object { TwiceTransformedBox pigment { color White } }
// Calculate the complete transformation it has gone through
// until now:
#declare TotalTrans = transform { LocalTrans WorldTrans }
// Find it's new centre and which direction it's y-axis is pointing:
#declare pNewCtr =
vTransform(pCtr, transform { TotalTrans });
#declare vNewY =
vTransform(pCtr + y, transform { TotalTrans }) - pNewCtr;
// Now that we know it's new centre and y-axis we can forget all
// about the transformations it has gone through up til now.
// The next task is to make the transformed box "intersect" with
// these three points:
#declare pA = <-32, 76, 0>;
#declare pB = <-88, -40, 16>;
#declare pC = < 0, 24, 26>;
// Show the points
sphere { pA, 5 pigment { color Cyan*2 } }
sphere { pB, 5 pigment { color Magenta*2 } }
sphere { pC, 5 pigment { color Yellow*2 } }
// Find two non paralell vectors for the plane they lie within:
#declare vCA = pA - pC;
#declare vCB = pB - pC;
// Note that although vCA and vCB seems to be perpendicular,
// they are not. I.e.: vdot(vCA, vCB) != 0
// And a normal vector for that plane:
#declare vUp = vcross(vCA, vCB);
// Also find a point that lies in the middle of these
// three points:
#declare pMid = (pA + pB + pC)/3;
// Then calculate the complete transform needed to make the box
// "intersect" with the three spheres:
#declare IsecPtsTrans =
transform {
translate -pNewCtr
ReorientMatrix(vNewY, vUp)
// AxisRotateMatrix(vUp, 45)
translate pMid
}
// If the box is to be rotated within the plane that the three
// spheres lie in, then uncomment the line above.
// Transform it to it's final position and show it:
object {
TwiceTransformedBox
transform { IsecPtsTrans }
pigment { color Yellow }
}
// ===== 1 ======= 2 ======= 3 ======= 4 ======= 5 ======= 6 ======= 7
/*
// Uncomment this region if you want to see the new local axes
// for the box in its final state.
// Finding its new (now old) x and z axes in the same way as we
// found the y axis above:
#declare vNewX =
vTransform(pCtr + x, transform { TotalTrans }) - pNewCtr;
#declare vNewZ =
vTransform(pCtr + z, transform { TotalTrans }) - pNewCtr;
// Calculate were its final centre is:
#declare pFinalCtr =
vTransform(pNewCtr, transform { IsecPtsTrans });
// And the direction of its final local x, y, z axes:
#declare vFinalX =
vTransform(pNewCtr + vNewX, transform { IsecPtsTrans }) - pFinalCtr;
#declare vFinalY =
vTransform(pNewCtr + vNewY, transform { IsecPtsTrans }) - pFinalCtr;
#declare vFinalZ =
vTransform(pNewCtr + vNewZ, transform { IsecPtsTrans }) - pFinalCtr;
// Maybe we want to specify a length for the axes ?
//#declare vFinalX = 60*vnormalize(vFinalX);
//#declare vFinalY = 60*vnormalize(vFinalY);
//#declare vFinalZ = 60*vnormalize(vFinalZ);
// A simple macro to show an axis
#macro Axis(v0, pCenter, Radius, Colour)
union {
sphere { -v0, Radius }
cylinder { -v0, v0, Radius }
sphere { v0, Radius }
translate pCenter
pigment { color Colour }
}
#end // macro Axis
// Show them
Axis(vFinalX, pFinalCtr, 2, Red)
Axis(vFinalY, pFinalCtr, 2, Green)
Axis(vFinalZ, pFinalCtr, 2, Blue)
*/
// ===== 1 ======= 2 ======= 3 ======= 4 ======= 5 ======= 6 ======= 7
// If we hadn't done all the world and local transformations to
// the box, then these few lines of code would have done something
// similar to it as the code above. (One of the sides of the box
// would even be aligned with two of the spheres.)
#declare vPlY = vnormalize(vUp);
#declare vPlZ = vnormalize(vcross(vCB, vPlY));
#declare vPlX = vcross(vPlY, vPlZ);
#declare OneSingleTrans =
transform {
matrix <
vPlX.x, vPlX.y, vPlX.z,
vPlY.x, vPlY.y, vPlY.z,
vPlZ.x, vPlZ.y, vPlZ.z,
0, 0, 0
>
}
// Uncomment to see the effect:
/*
object {
InitialBox // box { -<2, 0.1, 1.5>, <2, 0.1, 1.5> }
scale <34, 10, 60> // It's very small so scale it
transform OneSingleTrans
// AxisRotateMatrix(vPlY, 45)
translate pMid
pigment { color Orange + White }
}
*/
// Also have a look at this:
// (Lines up the edges along the spheres.)
/*
object {
InitialBox // box { -<2, 0.1, 1.5>, <2, 0.1, 1.5> }
scale <34, 10, 60>
transform OneSingleTrans
translate pC + 2*34*vPlX + 0.1*10*vPlY + 1.5*60*vPlZ
pigment { color Orange + Yellow }
}
*/
// And this:
// (Same result as from the one above.)
/*
object {
box { <0, 0, 0>, 2*<2, 0.1, 1.5> }
scale <34, 10, 60>
transform OneSingleTrans
translate pC
pigment { color Orange + Red }
}
*/
// ===== 1 ======= 2 ======= 3 ======= 4 ======= 5 ======= 6 ======= 7
/*
// Finally:
// If vCA and vCB had been perpendicular to each other, this
// would have been a quite nice solution to the problem:
// (The box made from the code below is a little bit skewed.)
#declare vPlZ = vCA;
#declare vPlX = vCB;
#declare vPlY = 4*vnormalize(vcross(vCA, vCB));
object {
box { <0, 0, 0>, <1, 1, 1> }
matrix <
vPlX.x, vPlX.y, vPlX.z,
vPlY.x, vPlY.y, vPlY.z,
vPlZ.x, vPlZ.y, vPlZ.z,
pC.x, pC.y, pC.z
>
pigment { color Grey }
}
*/
// ===== 1 ======= 2 ======= 3 ======= 4 ======= 5 ======= 6 ======= 7
Post a reply to this message
|
![](/i/fill.gif) |