POV-Ray : Newsgroups : povray.advanced-users : triangle centers Server Time
28 Jul 2024 22:24:48 EDT (-0400)
  triangle centers (Message 1 to 5 of 5)  
From: David Wallace
Subject: triangle centers
Date: 8 Jul 2003 16:30:42
Message: <3f0b29f2$1@news.povray.org>
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

From: Shay
Subject: Re: triangle centers
Date: 8 Jul 2003 16:37:22
Message: <3f0b2b82@news.povray.org>
"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

From:
Subject: Re: triangle centers
Date: 10 Jul 2003 22:30:26
Message: <3f0e2142$1@news.povray.org>
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

From: David Wallace
Subject: Re: triangle centers
Date: 11 Jul 2003 16:46:30
Message: <3f0f2226@news.povray.org>
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

From:
Subject: Re: triangle centers
Date: 20 Jul 2003 02:43:43
Message: <3f1a3a1f$1@news.povray.org>
// 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

Copyright 2003-2023 Persistence of Vision Raytracer Pty. Ltd.