|
|
I want to join Archimedian mesh2 objects precisely to one another (think
Magnetix). Is there a way to fish normal and vertex data out of a
declared mesh2 given a face index or will I have to create a separate
vertex array?
Is there a variant of ReorientCenter that takes 6 points, 3 from one
triangle and three from the other, that will line up the first triangle
to exactly fit the other?
#macro ReorientTriangle(p1,p2,p3,p4,p5,p6)
#local tr1 = transform { matrix <p1.x,p1.y,p1.z, p2.x,p2.y,p2.z,
p3.x,p3.y,p3.z, 0,0,0> inverse }
#local tr2 = transform { matrix <p4.x,p4.y,p4.z, p5.x,p5.y,p5.z,
p6.x,p6.y,p6.z, 0,0,0> }
transform tr1
transform tr2
#end
// Tetrahedron (Tetrad)
#declare aTetrad = sqrt(2);
#declare Tetrad = mesh2 {
vertex_vectors { 4,
<-.5, -.5, -.5>,
<0.5, -.5, 0.5>,
<-.5, 0.5, 0.5>,
<0.5, 0.5, -.5>
}
face_indices { 4,
<0,1,2>,<0,2,3>,<0,3,1>,<3,2,1>
}
//Reorient(<-1,-1,-1>,y)
}
#declare vTetrad = array[4] {
<-.5, -.5, -.5>,
<0.5, -.5, 0.5>,
<-.5, 0.5, 0.5>,
<0.5, 0.5, -.5>
}
// Cuboctahedron (Cuboct)
#declare aCuboct = sqrt(0.5);
#declare Cuboct = mesh2 {
vertex_vectors { 18,
<0,-0.5,-0.5>,
<0, 0.5,-0.5>,
<0,-0.5, 0.5>,
<0, 0.5, 0.5>,
<-0.5, 0,-0.5>,
< 0.5, 0,-0.5>,
<-0.5, 0, 0.5>,
< 0.5, 0, 0.5>,
<-0.5,-0.5, 0>,
< 0.5,-0.5, 0>,
<-0.5, 0.5, 0>,
< 0.5, 0.5, 0>,
<-0.5, 0.0, 0.0>,
< 0.5, 0.0, 0.0>,
< 0.0,-0.5, 0.0>,
< 0.0, 0.5, 0.0>,
< 0.0, 0.0,-0.5>,
< 0.0, 0.0, 0.5>
}
face_indices { 32,
<8,4,0>,<1,4,10>,<11,5,1>,<0,5,9>,
<2,6,8>,<9,7,2>,<3,7,11>,<10,6,3>,
<4,8,12>,<8,6,12>,<6,10,12>,<10,4,12>,
<9,5,13>,<7,9,13>,<11,7,13>,<5,11,13>,
<0,8,14>,<8,2,14>,<2,9,14>,<9,0,14>,
<10,1,15>,<3,10,15>,<11,3,15>,<1,11,15>,
<0,4,16>,<4,1,16>,<1,5,16>,<5,0,16>,
<6,2,17>,<3,6,17>,<7,3,17>,<2,7,17>,
}
}
#declare vCuboct = array[18] {
<0,-0.5,-0.5>,
<0, 0.5,-0.5>,
<0,-0.5, 0.5>,
<0, 0.5, 0.5>,
<-0.5, 0,-0.5>,
< 0.5, 0,-0.5>,
<-0.5, 0, 0.5>,
< 0.5, 0, 0.5>,
<-0.5,-0.5, 0>,
< 0.5,-0.5, 0>,
<-0.5, 0.5, 0>,
< 0.5, 0.5, 0>,
<-0.5, 0.0, 0.0>,
< 0.5, 0.0, 0.0>,
< 0.0,-0.5, 0.0>,
< 0.0, 0.5, 0.0>,
< 0.0, 0.0,-0.5>,
< 0.0, 0.0, 0.5>
}
#declare _aspect = image_width/image_height;
light_source { x*50, rgb <1,0,0> }
light_source { y*50, rgb <0,1,0> }
light_source { z*50, rgb <0,0,1> }
camera {
location <-2.0, 2.0, 0.0>
look_at <0.0, 0.0, 0.0>
rotate y*20
}
object { Cuboct scale 1 pigment { rgb 1 } }
object { Tetrad
ReorientTriangle(
vTetrad[0],vTetrad[2],vTetrad[1],vCuboct[1],vCuboct[4],vCuboct[10] )
pigment { rgb 0.75 }
}
I tested this and got an unexpected result... the fourth point in the
tetrahedron is way off course while the first three points are spot on.
I need a set of translations and rotations that have the normals
facing each other, the face centers and first points matching.
Ideas are welcome.
Post a reply to this message
|
|
|
|
I wrote these macros ages ago as a kind of poor-man's uv-map. They basically
fit one triangle to another in 3D space. Hope they work for you.
/* -------------------- Fit Macro -------------------------------
Macro takes 6 vectors: 3 points (P1, P2, P3) on object to move, P;
3 points (Q1, Q2, Q3) for position to move it to.
There are two versions of this macro. The rotation method is slower but
more precise than the matrix formula derived from John van Sickle.
*/
/*------------- [1] Rotation Method ------------------*/
#macro Normal (V1, V2, V3) vcross(V2-V1, V3-V1); #end
#macro XAngle (X, Y)
#local q = sqrt((X*X) + (Y*Y));
#if (q = 0)
#local aX = 0;
#else
#local aX = acos(X / q);
#end
#if (Y < 0)
#local aX = (2*pi) - aX;
#end
aX
#end
#macro Fit1 (P1, P2, P3, Q1, Q2, Q3)
#local deg = 180/pi;
#local nP = Normal (P1, P2, P3)
#local nQ = Normal (Q1, Q2, Q3)
//----- Translate to Origin -------
#local tP = -P1;
#local tQ = -Q1;
#local P2 = P2 + tP;
#local Q2 = Q2 + tQ;
//--------- Rotate Y------------
#local aP = XAngle(nP.x, nP.z) * deg;
#local aQ = XAngle(nQ.x, nQ.z) * deg;
#local nP = vaxis_rotate(nP, y, aP);
#local nQ = vaxis_rotate(nQ, y, aQ);
#local P2 = vaxis_rotate(P2, y, aP);
#local Q2 = vaxis_rotate(Q2, y, aQ);
//---------- Rotate Z-----------
#local bP = -XAngle(nP.x, nP.y) * deg;
#local bQ = -XAngle(nQ.x, nQ.y) * deg;
#local P2 = vaxis_rotate(P2, z, bP);
#local Q2 = vaxis_rotate(Q2, z, bQ);
//---------- Rotate X-----------
#local XAngleP = XAngle(P2.z, P2.y) * deg;
#local XAngleQ = XAngle(Q2.z, Q2.y) * deg;
#local cQ = -(XAngleQ - XAngleP);
translate tP
rotate aP*y
rotate bP*z
rotate cQ*x
rotate -bQ*z
rotate -aQ*y
translate -tQ
#end
/*------------- [2] Matrix Method ------------------*/
#macro Fit2 (pA, pB, pC, pD, pE, pF)
#local vXa = (pB-(pA));
#local vYa = (pC-(pA));
#local vZa = vcross(vXa, vYa);
#local vXb = (pE-(pD));
#local vYb = (pF-(pD));
#local vZb = vcross(vXb, vYb);
#local sDET = vdot(vZa,vcross(vXa,vYa));
//-- Values for the inverted matrix:
#local vCX = vcross(vYa, vZa)/sDET;
#local vCY = vcross(vZa, vXa)/sDET;
#local vCZ = vcross(vXa, vYa)/sDET;
// These two steps take the triangle at (A,B,C) and move it to
(<0,0,0>,x,y).
translate -(pA)
matrix < vCX.x, vCY.x, vCZ.x,
vCX.y, vCY.y, vCZ.y,
vCX.z, vCY.z, vCZ.z,
0, 0, 0 >
// This matrix takes the triangle at (<0,0,0>,x,y) and moves it to
(D,E,F).
matrix < vXb.x, vXb.y, vXb.z,
vYb.x, vYb.y, vYb.z,
vZb.x, vZb.y, vZb.z,
pD.x, pD.y, pD.z >
#end
/*---------------------------------------------------------------*/
#macro Fit (P1, P2, P3, Q1, Q2, Q3)
Fit1 (P1, P2, P3, Q1, Q2, Q3)
#end
Post a reply to this message
|
|