樹木曲線

 投稿者:しばっち  投稿日:2011年 8月14日(日)23時30分48秒
  LET L=500 !'幹の長さ
LET LL=40 !'幹の太さ
LET AX=0 !'初期ベクトル
LET AY=L
LET AZ=0
LET OX=0
LET OY=0
LET OZ=0
INPUT  PROMPT "LEVEL=":LEV
FILE GETSAVENAME F$,"dxfファイル|*.dxf"
IF F$="" THEN STOP
IF RIGHT$(F$,1)="!" THEN LET F$=F$(1:LEN(F$)-1) & "樹木曲線" & STR$(LEV)
IF POS(UCASE$(F$),".DXF")=0 THEN LET F$=F$ & ".dxf"
OPEN #1:NAME F$
ERASE #1
PRINT #1:"0"
PRINT #1:"SECTION"
PRINT #1:"2"
PRINT #1:"ENTITIES"
CALL TREE(LEV,AX,AY,AZ,OX,OY,OZ,L,LL,#1)
PRINT #1:"0"
PRINT #1:"ENDSEC"
PRINT #1:"0"
PRINT #1:"EOF"
CLOSE #1
END

EXTERNAL  SUB TREE(N,AX,AY,AZ,OX,OY,OZ,L,LL,#1) !'※枝の伸び方(角度)がおかしい
IF N>0 THEN
   CALL SPHERE(#1,AX,AY,AZ,LL) !'関節部に球を配置
   CALL TUBE(#1,OX,OY,OZ,AX,AY,AZ,LL)
   LET  A=AY*OZ-AZ*OY !'外積
   LET  B=AZ*OX-AX*OZ
   LET  C=AX*OY-AY*OX
   IF OX=0 AND OY=0 AND OZ=0 THEN
      LET A=0
      LET B=1
      LET C=0
   END IF
   LET P=ACOS(COSINE(0,1,0,AX-OX,AY-OY,AZ-OZ))
   LET XX=COS(30*PI/180)*COS(0)
   LET YY=SIN(30*PI/180)
   LET ZZ=COS(30*PI/180)*SIN(0)
   CALL ROTATE(XX,YY,ZZ,AX-OX+A,AY-OY+B,AZ-OZ+C,P+30,X1,Y1,Z1)
   LET S=SQR(X1^2+Y1^2+Z1^2)
   LET X1=X1/S*L*.8
   LET Y1=Y1/S*L*.8
   LET Z1=Z1/S*L*.8
   CALL TREE(N-1,AX+X1,AY+Y1,AZ+Z1,AX,AY,AZ,L*.8,LL*.6,#1)
   LET XX=COS(30*PI/180)*COS(120*PI/180)
   LET YY=SIN(30*PI/180)
   LET ZZ=COS(30*PI/180)*SIN(120*PI/180)
   CALL ROTATE(XX,YY,ZZ,AX-OX+A,AY-OY+B,AZ-OZ+C,P+30,X2,Y2,Z2)
   LET S=SQR(X2^2+Y2^2+Z2^2)
   LET X2=X2/S*L*.8
   LET Y2=Y2/S*L*.8
   LET Z2=Z2/S*L*.8
   CALL TREE(N-1,AX+X2,AY+Y2,AZ+Z2,AX,AY,AZ,L*.8,LL*.6,#1)
   LET XX=COS(30*PI/180)*COS(240*PI/180)
   LET YY=SIN(30*PI/180)
   LET ZZ=COS(30*PI/180)*SIN(240*PI/180)
   CALL ROTATE(XX,YY,ZZ,AX-OX+A,AY-OY+B,AZ-OZ+C,P+30,X3,Y3,Z3)
   LET S=SQR(X3^2+Y3^2+Z3^2)
   LET X3=X3/S*L*.8
   LET Y3=Y3/S*L*.8
   LET Z3=Z3/S*L*.8
   CALL TREE(N-1,AX+X3,AY+Y3,AZ+Z3,AX,AY,AZ,L*.8,LL*.6,#1)
END IF
END SUB

EXTERNAL  SUB TUBE(#1,X0,Y0,Z0,X1,Y1,Z1,LL) !'チューブ(蓋なし)
LET NN=8 !'分割数
LET X=X1-X0 !'回転軸
LET Y=Y1-Y0
LET Z=Z1-Z0
LET A0=1 !'線分(X0,Y0,Z0)-(X1,Y1,Z1)に垂直で適当なベクトル(A0,B0,C0)
LET B0=1
LET C0=1
IF X<>0 THEN !'内積 0より X*A0+Y*B0+Z*C0=0
   LET A0=(-B0*Y-C0*Z)/X
ELSEIF Y<>0 THEN
   LET B0=(-A0*X-C0*Z)/Y
ELSEIF Z<>0 THEN
   LET C0=(-A0*X-B0*Y)/Z
END IF
LET  SS=SQR(A0*A0+B0*B0+C0*C0)
LET  TX=A0*LL/SS
LET  TY=B0*LL/SS
LET  TZ=C0*LL/SS
FOR K=0 TO NN-1
   CALL ROTATE(TX,TY,TZ,X,Y,Z,K*360/NN,XA,YA,ZA)
   CALL ROTATE(TX,TY,TZ,X,Y,Z,(K+1)*360/NN,XB,YB,ZB)
   PRINT #1:"0"
   PRINT #1:"3DFACE"
   PRINT #1:"8"
   PRINT #1:"LAYER1"
   PRINT #1:"62"
   PRINT #1:"1"
   PRINT #1:"10"
   PRINT #1:XA+X0
   PRINT #1:"20"
   PRINT #1:YA+Y0
   PRINT #1:"30"
   PRINT #1:ZA+Z0
   PRINT #1:"11"
   PRINT #1:XB+X0
   PRINT #1:"21"
   PRINT #1:YB+Y0
   PRINT #1:"31"
   PRINT #1:ZB+Z0
   PRINT #1:"12"
   PRINT #1:XB+X1
   PRINT #1:"22"
   PRINT #1:YB+Y1
   PRINT #1:"32"
   PRINT #1:ZB+Z1
   PRINT #1:"13"
   PRINT #1:XA+X1
   PRINT #1:"23"
   PRINT #1:YA+Y1
   PRINT #1:"33"
   PRINT #1:ZA+Z1
NEXT  K
END SUB

EXTERNAL  SUB SPHERE(#1,XX,YY,ZZ,RR) !'球
LET  N=8 !'分割数
LET  ALPHA=0
LET  BETA=0
LET  X0=-RR*SIN(ALPHA*PI/180)*COS(BETA*PI/180)+XX
LET  Y0=RR*COS(ALPHA*PI/180)+YY
LET  Z0=RR*SIN(ALPHA*PI/180)*SIN(BETA*PI/180)+ZZ
LET ALPHA=180/N
FOR BETA=0 TO 359 STEP 360/N
   LET  X1=-RR*SIN(ALPHA*PI/180)*COS(BETA*PI/180)+XX
   LET  Y1=RR*COS(ALPHA*PI/180)+YY
   LET  Z1=RR*SIN(ALPHA*PI/180)*SIN(BETA*PI/180)+ZZ
   LET  X2=-RR*SIN(ALPHA*PI/180)*COS((BETA+360/N)*PI/180)+XX
   LET  Y2=RR*COS(ALPHA*PI/180)+YY
   LET  Z2=RR*SIN(ALPHA*PI/180)*SIN((BETA+360/N)*PI/180)+ZZ
   PRINT #1:"0"
   PRINT #1:"3DFACE"
   PRINT #1:"8"
   PRINT #1:"LAYER1"
   PRINT #1:"62"
   PRINT #1:"1"
   PRINT #1:"10"
   PRINT #1:X0
   PRINT #1:"20"
   PRINT #1:Y0
   PRINT #1:"30"
   PRINT #1:Z0
   PRINT #1:"11"
   PRINT #1:X2
   PRINT #1:"21"
   PRINT #1:Y2
   PRINT #1:"31"
   PRINT #1:Z2
   PRINT #1:"12"
   PRINT #1:X1
   PRINT #1:"22"
   PRINT #1:Y1
   PRINT #1:"32"
   PRINT #1:Z1
NEXT  BETA
FOR ALPHA=180/N TO 180-180/N STEP 180/N
   FOR BETA=0 TO 359 STEP 360/N
      PRINT #1:"0"
      PRINT #1:"3DFACE"
      PRINT #1:"8"
      PRINT #1:"LAYER1"
      PRINT #1:"62"
      PRINT #1:"1"
      LET  X1=-RR*SIN((ALPHA+180/N)*PI/180)*COS(BETA*PI/180)+XX
      LET  Y1=RR*COS((ALPHA+180/N)*PI/180)+YY
      LET  Z1=RR*SIN((ALPHA+180/N)*PI/180)*SIN(BETA*PI/180)+ZZ
      LET  X2=-RR*SIN((ALPHA+180/N)*PI/180)*COS((BETA-360/N)*PI/180)+XX
      LET  Y2=RR*COS((ALPHA+180/N)*PI/180)+YY
      LET  Z2=RR*SIN((ALPHA+180/N)*PI/180)*SIN((BETA-360/N)*PI/180)+ZZ
      LET  X3=-RR*SIN(ALPHA*PI/180)*COS((BETA-360/N)*PI/180)+XX
      LET  Y3=RR*COS(ALPHA*PI/180)+YY
      LET  Z3=RR*SIN(ALPHA*PI/180)*SIN((BETA-360/N)*PI/180)+ZZ
      LET  X4=-RR*SIN(ALPHA*PI/180)*COS(BETA*PI/180)+XX
      LET  Y4=RR*COS(ALPHA*PI/180)+YY
      LET  Z4=RR*SIN(ALPHA*PI/180)*SIN(BETA*PI/180)+ZZ
      PRINT #1:"10"
      PRINT #1:X1
      PRINT #1:"20"
      PRINT #1:Y1
      PRINT #1:"30"
      PRINT #1:Z1
      PRINT #1:"11"
      PRINT #1:X2
      PRINT #1:"21"
      PRINT #1:Y2
      PRINT #1:"31"
      PRINT #1:Z2
      PRINT #1:"12"
      PRINT #1:X3
      PRINT #1:"22"
      PRINT #1:Y3
      PRINT #1:"32"
      PRINT #1:Z3
      PRINT #1:"13"
      PRINT #1:X4
      PRINT #1:"23"
      PRINT #1:Y4
      PRINT #1:"33"
      PRINT #1:Z4
   NEXT BETA
NEXT ALPHA
LET  ALPHA=180
LET  BETA=0
LET  X0=-RR*SIN(ALPHA*PI/180)*COS(BETA*PI/180)+XX
LET  Y0=RR*COS(ALPHA*PI/180)+YY
LET  Z0=RR*SIN(ALPHA*PI/180)*SIN(BETA*PI/180)+ZZ
LET  ALPHA=180-180/N
FOR BETA=0 TO 359 STEP 360/N
   LET  X1=-RR*SIN(ALPHA*PI/180)*COS(BETA*PI/180)+XX
   LET  Y1=RR*COS(ALPHA*PI/180)+YY
   LET  Z1=RR*SIN(ALPHA*PI/180)*SIN(BETA*PI/180)+ZZ
   LET  X2=-RR*SIN(ALPHA*PI/180)*COS((BETA+360/N)*PI/180)+XX
   LET  Y2=RR*COS(ALPHA*PI/180)+YY
   LET  Z2=RR*SIN(ALPHA*PI/180)*SIN((BETA+360/N)*PI/180)+ZZ
   PRINT #1:"0"
   PRINT #1:"3DFACE"
   PRINT #1:"8"
   PRINT #1:"LAYER1"
   PRINT #1:"62"
   PRINT #1:"1"
   PRINT #1:"10"
   PRINT #1:X0
   PRINT #1:"20"
   PRINT #1:Y0
   PRINT #1:"30"
   PRINT #1:Z0
   PRINT #1:"11"
   PRINT #1:X1
   PRINT #1:"21"
   PRINT #1:Y1
   PRINT #1:"31"
   PRINT #1:Z1
   PRINT #1:"12"
   PRINT #1:X2
   PRINT #1:"22"
   PRINT #1:Y2
   PRINT #1:"32"
   PRINT #1:Z2
NEXT BETA
END SUB
 

Re: 樹木曲線

 投稿者:しばっち  投稿日:2011年 8月14日(日)23時31分35秒
  > No.1640[元記事へ]

続き

EXTERNAL  SUB ROTATE(XX,YY,ZZ,X0,Y0,Z0,TH,NX,NY,NZ) !'任意軸回転(ロドリグの公式)
!'(X0,Y0,Z0)と原点を通る回転軸
!'点 P(XX,YY,ZZ)をTH度回転 P'(NX,NY,NZ)
DIM A(3,3)
LET  S=SQR(X0*X0+Y0*Y0+Z0*Z0)
LET  X=X0/S
LET  Y=Y0/S
LET  Z=Z0/S
LET  A(1,1)=X*X*(1-COS(TH*PI/180))+COS(TH*PI/180)
LET  A(1,2)=X*Y*(1-COS(TH*PI/180))+Z*SIN(TH*PI/180)
LET  A(1,3)=X*Z*(1-COS(TH*PI/180))-Y*SIN(TH*PI/180)
LET  A(2,1)=Y*X*(1-COS(TH*PI/180))-Z*SIN(TH*PI/180)
LET  A(2,2)=Y*Y*(1-COS(TH*PI/180))+COS(TH*PI/180)
LET  A(2,3)=Y*Z*(1-COS(TH*PI/180))+X*SIN(TH*PI/180)
LET  A(3,1)=Z*X*(1-COS(TH*PI/180))+Y*SIN(TH*PI/180)
LET  A(3,2)=Z*Y*(1-COS(TH*PI/180))-X*SIN(TH*PI/180)
LET  A(3,3)=Z*Z*(1-COS(TH*PI/180))+COS(TH*PI/180)
LET  NX=XX*A(1,1)+YY*A(1,2)+ZZ*A(1,3)
LET  NY=XX*A(2,1)+YY*A(2,2)+ZZ*A(2,3)
LET  NZ=XX*A(3,1)+YY*A(3,2)+ZZ*A(3,3)
END SUB

EXTERNAL  FUNCTION COSINE(AX,AY,AZ,BX,BY,BZ)
LET  COSINE=(AX*BX+AY*BY+AZ*BZ)/SQR(AX^2+AY^2+AZ^2)/SQR(BX^2+BY^2+BZ^2)
END FUNCTION
 

戻る