|
|
|
|
|
|
| |
| |
|
|
|
|
| |
| |
|
|
I am trying to inscribe a circle in a triangle. Please help me debug the
macro I made to carry it out:
#macro PointLineDist(ps, po, dr)
#local ptx = dr.z*(ps.y-po.y)-dr.y*(ps.z-po.z);
#local pty = dr.x*(ps.z-po.z)-dr.z*(ps.x-po.x);
#local ptz = dr.y*(ps.x-po.x)-dr.x*(ps.y-po.y);
(vlength(<ptx,pty,ptz>) / vlength(dr))
#end
#macro InCircle(p1, p2, p3, cen, rad) // cen, rad are center and radius I
want to calculate
// Radius calculation
#local ln1 = vlength(p2-p1);
#local ln2 = vlength(p3-p1);
#local ln3 = vlength(p3-p2);
#local hPer = (ln1+ln2+ln3)/2;
#local area = sqrt(hPer*(hPer-ln1)*(hPer-ln2)*(hPer-ln3));
#declare rad = 0+area/hPer;
// InCenter calculation
#local dr1 = vnormalize(p2-p1);
#local dr2 = vnormalize(p3-p1);
#local dr3 = vnormalize(p3-p2);
#local drb1 = vnormalize(dr1+dr2); // Bisects angle through p1
#local drb2 = vnormalize(dr3-dr1); // Bisects angle through p2
#declare cen = p2 + drb2*PointLineDist(p2, p1, drb1);
#end
When I instantiate the macro in the following code:
#declare odfRadI=0.0;
#declare odfCenI=<0,0,0>;
InCircle(< 0.01,-0.01, 0>, < 2.85,-0.01, 0>, < 0.01,-2.85, 0>, odfRadI,
odfCenI)
#declare odfBrace = union {
difference {
cylinder { < 0,-3.0,-0.02>, < 0,-3.0, 0.02>, 0.05 }
cylinder { < 0,-3.0,-0.03>, < 0,-3.0, 0.03>, 0.04 }
plane { x, 0 }
}
box { < 0.00,-2.96,-0.02>, < 0.01, 0.00, 0.02> }
box { < 0.00,-3.15,-0.02>, < 0.01,-3.04, 0.02> }
difference {
cylinder { < 3.0, 0.0, -0.02>, < 3.0, 0.0, 0.02>, 0.05 }
cylinder { < 3.0, 0.0, -0.03>, < 3.0, 0.0, 0.03>, 0.04 }
plane {-y, 0 }
}
difference {
cylinder { z*-.02, z*0.02, odfRadI+.01 } // error is here
cylinder { z*-.03, z*0.03, odfRadI }
translate odfCenI
}
box { < 0.00,-0.01,-0.02>, < 2.96, 0.00, 0.02> }
box { < 3.04,-0.01,-0.02>, < 3.15, 0.00, 0.02> }
box {
< 0.00,-2.86,-0.015>,< 2.85,-2.85, 0.015>
matrix <1, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0>
}
box {
< 0.00,-3.15,-0.015>,< 3.15,-3.14, 0.015>
matrix <1, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0>
}
ObjLine( odfRing, < 1.57,-1.43, 0>, < 0.14, 0.14,0>, 10 )
ObjLine( odfRing, < 1.43,-1.57, 0>, <-0.14,-0.14,0>, 10 )
texture { colWLamp }
}
POV-Ray complains that odfRadI is a vector. How did this happen?
Post a reply to this message
|
|
| |
| |
|
|
|
|
| |
| |
|
|
"David Wallace" <dar### [at] earthlinknet> wrote in message
news:3f0b29f2$1@news.povray.org...
Here is the problem:
#macro InCircle(p1, p2, p3, cen, rad)
InCircle(<.01,-.01,0>,<2.85,.01,0>,<.01,-2.85,0>,odfRadI,odfCenI)
^^^^^^^
-Shay
Post a reply to this message
|
|
| |
| |
|
|
|
|
| |
| |
|
|
Hi David,
you interchanged the last two parameters:
#macro InCircle(p1, p2, p3, cen, rad)
InCircle(<...>, <...>, <...>, odfRadI, odfCenI)
Your InCenter calculkation is buggy; correct and much easier is this:
#declare cen = (ln3*p1+ln2*p2+ln1*p3)/2/hPer;
The variables dr1, dr2, dr3, drb1, drb2 are not needed for this.
Here is a link to the formula:
http://mathforum.org/dr.math/faq/formulas/faq.ag2.html#twotriangles
Looking at the corners and the intersection of the circle and the
upper diagonal of
object { odfBrace scale <1, 1, 0.01> }
with one of these cameras:
camera { location -0.1*z look_at 0 translate 3.15*x }
camera { location -0.1*z look_at 0 translate -3.15*y }
camera { location -0.3*z look_at 0 translate 1.425*(x-y) }
I suppose you wanted these diagonals:
box {
< 0.00,-2.86-0.01*sqrt(2),-0.015>,< 2.85+0.01*sqrt(2),-2.86, 0.015>
matrix <1, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0>
clipped_by { plane { y, 0 } }
}
box {
< 0.01,-3.16,-0.015>,< 3.15,-3.16+0.01*sqrt(2), 0.015>
matrix <1, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0>
clipped_by { plane { y, 0 } }
}
or (much easier in my opinion):
// a box to the right and below the line <0, -2.86>--<2.86, 0>
box { -0.015*z, <sqrt(2*2.86*2.86), -0.01, 0.015>
rotate 45*z
translate -2.86*y
}
// a box to the left and above the line <0.01, -3.15>--<3.15, 0.01>
box { -0.015*z, <sqrt(2*3.14*3.14), 0.01, 0.015>
rotate 45*z
translate <0.01, -3.15, 0>
}
( sqrt(2*2.86*2.86) = distance(<0,-2.86>, <2.86,0>)
sqrt(2*3.14*3.14) = distance(<0.01,-3.15>, <3.15,-0.01>) )
Sputnik
P.S. I suggest to use well-named variables instead of the constants:
#declare Length = 3;
#declare Offset = 0.15; // Length+Offset=3.15; Length-Offset=2.85
#declare Thick = 0.01;
etc; then calculate everything else from this. This would make it VERY
easy to change the size and shape. A much bigger value for "Thick"
would help to check the correct alignment of all the elements, because
many errors would be easily visible. In your code, such a change would
require extensive re-calculation by hand; with a variable, POV-Ray does
the calculations, you only edit one declaration.
Post a reply to this message
|
|
| |
| |
|
|
|
|
| |
| |
|
|
Here is the solution I came up with:
#macro LineIntersect(p1, d1, p2, d2)
#local pSep = p2-p1;
#local pdCross = vcross(d1,d2);
#local pdLen = vlength(pdCross);
#local lDist = vdot(pSep,pdCross);
#local dist = vdot(vcross(pSep,d2),pdCross)/(pdLen*pdLen);
#local pnt = p1+d1*dist;
pnt
#end
#macro icRad(p1, p2, p3) // Inscribed circle radius
#local ln1 = vlength(p2-p1);
#local ln2 = vlength(p3-p1);
#local ln3 = vlength(p3-p2);
#local hPer = (ln1+ln2+ln3)*0.5;
#local area = sqrt(hPer*(hPer-ln1)*(hPer-ln2)*(hPer-ln3));
#declare rad = area/hPer;
rad
#end
#macro icCen(p1, p2, p3) // Inscribed circle center
#local dr1 = vnormalize(p3-p2);
#local dr2 = vnormalize(p3-p1);
#local dr3 = vnormalize(p2-p1);
#local drb1 = vnormalize(-dr2-dr3); // Bisects angle through p1
#local drb2 = vnormalize(dr3-dr1); // Bisects angle through p2
#declare cen = LineIntersect(p1, drb1, p2, drb2);
cen
#end
#macro ccRad(p1, p2, p3) // Circumscribed circle radius
#local ln1 = vlength(p2-p1);
#local ln2 = vlength(p3-p1);
#local ln3 = vlength(p3-p2);
#local hPer = (ln1+ln2+ln3)*0.5;
#local area = sqrt(hPer*(hPer-ln1)*(hPer-ln2)*(hPer-ln3));
#declare rad = ln1*ln2*ln3*0.25/area;
rad
#end
#macro ccCen(p1, p2, p3) // Circumscribed circle center
#local pNrm = vnormalize(vcross(p2-p1,p3-p1)); // Unit triangle plane
normal
#local mp1 = (p2+p3)*.5; // Midpoint of line opposite p1
#local mp2 = (p1+p3)*.5; // Midpoint of line opposite p2
#local dr1 = vnormalize(vcross(p3-p2,pNrm)); // Perpincular to line opp.
p1
#local dr2 = vnormalize(vcross(p3-p1,pNrm)); // Perpincular to line opp.
p2
#declare cen = LineIntersect(mp1, dr1, mp2, dr2);
cen
#end
My approach was simply set up the appropriate lines (angle bisectors for
incenter, perpendicular bisectors for circumcenter) and calculate the
intersection. I found the solutions at MathWorld
(http://mathworld.wolfram.com/). This approach is highly extensible and can
be used to calculate many triangle centers.
If anyone has a simpler solution that works in three dimensions (sorry,
Sputnik, your formula is for two), let me know.
Post a reply to this message
|
|
| |
| |
|
|
|
|
| |
| |
|
|
// Hi David,
//
// "my" solution (from mathforum.org) also works in 3D; the
// following scene will convince you!
//
// Sputnik
//=== 3D incircle demonstration =========================================
// +SP8 +EP8 +A0.1 +AM2 +R2 -FN
//=== calculate 3D-normal, 3D-midpoint and 3D-radius of 3D-triangle =====
#macro InCircle (P1, P2, P3, Normal, InMid, InRad)
#local L12 = vlength(P2-P1);
#local L13 = vlength(P3-P1);
#local L23 = vlength(P3-P2);
#local Peri = L12+L13+L23;
#local Normal = vcross(P2-P1,P3-P1); // not yet normalized
#local DoubleArea = vlength(Normal);
#local Normal = Normal/DoubleArea; // =vnormalize(Normal)
#declare InMid = (P1*L23+P2*L13+P3*L12)/Peri;
#declare InRad = DoubleArea/Peri;
#end//macro InCircle
//=======================================================================
// some initializations for demo scene
#declare T = 0.1; // thickness
#declare Shrink = 0; // also try 0.01 <=== !!!
#declare Rand = seed(154245648);
// dummy initialization (variables are used as macro parameter)
#declare N = <0,0,0>;
#declare M = <0,0,0>;
#declare R = 0;
// camera, light
#declare CamLoc = <0, 6, -4>;
#declare CamDir = vnormalize(CamLoc);
camera { location CamLoc look_at 0 }
light_source { <-2, 3, -4>*1000, rgb 1 }
// macro for random triangle without incircle
#macro RandomTriangle (Pos)
// search for a "good" triangle
#declare BadNormal = true;
#while (BadNormal)
// choose 3 random corner points
#local C1 = <rand(Rand), rand(Rand), rand(Rand)>-0.5;
#local C2 = <rand(Rand), rand(Rand), rand(Rand)>-0.5;
#local C3 = <rand(Rand), rand(Rand), rand(Rand)>-0.5;
// calculate normal, midpoint and radius of the incircle
InCircle (C1, C2, C3, N, M, R)
// reject if not rougly facing the camera
#declare BadNormal = ( abs(vdot(N, CamDir)) < .7 );
#end//while BadNormal
// create thick triangle, cut out its "incylinder"
difference {
intersection {
plane { N, T/2 translate C1 }
plane { -N, T/2 translate C1 }
plane { vcross(N, C1-C2), -Shrink*R translate C1 }
plane { vcross(N, C2-C3), -Shrink*R translate C2 }
plane { vcross(N, C3-C1), -Shrink*R translate C3 }
}
cylinder { M+N*T, M-N*T, R }
bounded_by { box {
<min(C1.x,C2.x,C3.x), min(C1.y,C2.y,C3.y), min(C1.z,C2.z,C3.z)>-T,
<max(C1.x,C2.x,C3.x), max(C1.y,C2.y,C3.y), max(C1.z,C2.z,C3.z)>+T
} }
texture {
pigment { color rgb <rand(Rand), rand(Rand), rand(Rand)>*.7+.3 }
finish { ambient .4 diffuse .6 }
}
no_shadow
translate Pos
}
#end//macro RandomTriangle
// a cloud of triangles
#declare X = -2;
#while (X<=2)
#declare Y = 0;
#while (Y<=3)
#declare Z = -2;
#while (Z<=0)
RandomTriangle (<X,Y,Z>)
#declare Z = Z+1;
#end//while Z
#declare Y = Y+1;
#end//while Y
#declare X = X+1;
#end//while X
//=== END ===============================================================
Post a reply to this message
|
|
| |
| |
|
|
|
|
| |
|
|