3)曲線の生成

 円の一部を接続して曲線を生成します。
//**********************************************************************************
入力 Lw:曲線の線の太さとなる半径
   Px1:接続する始めの点のx座標値 Pz1:接続する始めの点のz座標値
   Px2:接続する終りの点のx座標値 Pz2:接続する終りの点のz座標値
   Ox0:円の中心となるx座標値   Oz0:円の中心となるz座標値
出力 Ox0:次の円の中心となるx座標値 Oz0:次の円の中心となるz座標値
//**********************************************************************************
 #macro Curve_element(Lw,Px1,Pz1,Px2,Pz2,Ox0,Oz0)
 #local Mrc=(Px1-Ox0)*(Pz2-Pz1)-(Pz1-Oz0)*(Px2-Px1);
 #local Mvc=(Px1-Ox0)*(Px2-Px1)+(Pz1-Oz0)*(Pz2-Pz1);
 #local Ltype=3;
 #if(Mrc!=0 & Mvc!=0)
  #local A=2*(Px2-Px1)*(Px1-Ox0)+2*(Pz2-Pz1)*(Pz1-Oz0);
  #local B=2*(Pz1-Pz2)*(Px1*Oz0-Pz1*Ox0);
  #local C=(Px1-Ox0)*(pow(Px1,2)-pow(Px2,2)+pow(Pz1,2)-pow(Pz2,2));
  #local Ox=(B-C)/A; // center x
  #local Oz=( (Pz1-Oz0)/(Px1-Ox0) )*(Ox-Px1)+Pz1; // center z
  #local Tr=sqrt(pow(Px2-Ox,2)+pow(Pz2-Oz,2)); // radius r
  #local Ra1=degrees(atan2(Pz1-Oz,Px1-Ox));
  #local Ra2=degrees(atan2(Pz2-Oz,Px2-Ox));
  #local Mc=Px1-Ox; #local Ms=Pz1-Oz;
  #if(Mc!=0) #local Mtan=Ms/Mc; #else #local Mtan=tan(pi/2); #end
  #local Vxv=(pow(Mtan,2)*Px2+Mtan*(Pz1-Pz2)+Px1)/(pow(Mtan,2)+1);
  #local Vzv=(pow(Mtan,2)*Pz1+Mtan*(Px1-Px2)+Pz2)/(pow(Mtan,2)+1);
  #local Vs=Vzv-Pz1; #local Vc=-(Vxv-Px1);
  #if(Mc!=0)
  #if(Mc*Vs>0) #local Ltype=1; #end
  #if(Mc*Vs<0) #local Ltype=2; #end
  #else
  #if(Ms*Vc>0) #local Ltype=1; #end
  #if(Ms*Vc<0) #local Ltype=2; #end
  #end
 #end
 #switch(Ltype)
  #case(1)
  torus { Tr,Lw
   clipped_by { plane { z, 0 } rotate -(Ra1+180)*y }
   clipped_by { plane { z, 0 } rotate -(Ra2)*y }
  translate < Ox, 0, Oz > }
  #break
  #case(2)
  torus { Tr,Lw
   clipped_by { plane { z, 0 } rotate -(Ra1)*y }
   clipped_by { plane { z, 0 } rotate -(Ra2+180)*y }
  translate < Ox, 0, Oz > }
  #break
  #case(3)
  cylinder { < Px1, 0, Pz1 >,< Px2, 0, Pz2 >,Lw open }
  #local Ox=Ox0+(Px2-Px1);
  #local Oz=Oz0+(Pz2-Pz1);
  #break
 #end
 #local Ox0=Ox; #local Oz0=Oz;
 #end
//**********************************************************************************