3D回転処理

 投稿者:lark12_long  投稿日:2014年 5月 8日(木)06時36分15秒
  動作図に示すプログラムを作成しました

プログラムソースは、グッチャリしてるので、掲示致しませんが、
下記疑問点を、解決できません

どなたか、スマートなプログラム事例を、示して頂けると、嬉しいです

左上の、x+~z-は、
マウス左クリックで、立方体及び座要軸を、各軸周りに回転
マウス右クリックで、立方体のみを、各座標軸周りに回転
させます

左下の、x+~z-は、
マウス右クリックで、立方体を各軸方向に平行移動させます

疑問点

 立方体のx、y、z軸周りの回転は、画面表示上の各軸周りに回転するが、
 座標系の回転に於いては、立方体、座標軸共に、x軸周り回転は
 画面表示上のx軸周りに回転するが、
 y、z軸周りの回転は、画面上の軸周りに、回転しない

 z軸周りの回転は、画面に対しての垂線周りに回転する

 立方体の各軸方向への平行移動は、画面上の各軸に沿って平行移動する

lark12_long
 

Re: 3D回転処理

 投稿者:山中和義  投稿日:2014年 5月 9日(金)20時39分8秒
  > No.3375[元記事へ]

lark12_longさんへのお返事です。

> どなたか、スマートなプログラム事例を、示して頂けると、嬉しいです

XYZ軸の形をした図形をワールド座標の原点で回転させて、
その図形をもとに、「任意軸での回転」と「方向ベクトルに沿う移動」で立方体の位置を求めています。


SET WINDOW -3,3,-3,3 !表示領域

DIM AX(3,4) !XYZ軸の形をした図形
DATA 1,0,0 !X
DATA 0,1,0 !Y
DATA 0,0,1 !Z
FOR i=1 TO 3
   FOR J=1 TO 3
      READ AX(i,J) !x,y,z
      LET AX(i,4)=1 !w
   NEXT J
NEXT i

DIM BX(8,4) !立方体の8頂点
DATA -1,-1, 1 !上面
DATA  1,-1, 1
DATA  1, 1, 1
DATA -1, 1, 1
DATA -1,-1,-1 !下面
DATA  1,-1,-1
DATA  1, 1,-1
DATA -1, 1,-1
FOR i=1 TO 8
   FOR J=1 TO 3
      READ BX(i,J) !x,y,z
      LET BX(i,4)=1 !w
   NEXT J
NEXT i

DIM T(8,4) !(x',y',z')
DIM M(4,4)

DATA "+X","-X","+Y","-Y","+Z","-Z" !ボタン
DIM BTN$(6)
MAT READ BTN$

DO

   SET DRAW mode hidden !ちらつき防止(開始)
   CLEAR

   CALL button(-2.8,2.8, 0.6,0.3, 6, BTN$,S) !軸の回転メニュー
   SELECT CASE S
   CASE 0 !+x
      CALL D3ROTATE(RAD(5),AX(1,1),AX(1,2),AX(1,3), M) !5度ずつ
   CASE 1 !-x
      CALL D3ROTATE(RAD(-5),AX(1,1),AX(1,2),AX(1,3), M)
   CASE 2 !+y
      CALL D3ROTATE(RAD(5),AX(2,1),AX(2,2),AX(2,3), M)
   CASE 3 !-y
      CALL D3ROTATE(RAD(-5),AX(2,1),AX(2,2),AX(2,3), M)
   CASE 4 !+z
      CALL D3ROTATE(RAD(5),AX(3,1),AX(3,2),AX(3,3), M)
   CASE 5 !-z
      CALL D3ROTATE(RAD(-5),AX(3,1),AX(3,2),AX(3,3), M)
   CASE ELSE
      MAT M=IDN
   END SELECT
   MAT T=AX*M
   MAT AX=T
   MAT T=BX*M
   MAT BX=T


   CALL button(-2.0,2.8, 0.6,0.3, 6, BTN$,S) !図形の回転メニュー
   SELECT CASE S
   CASE 0 !+x
      CALL D3ROTATE(RAD(5),AX(1,1),AX(1,2),AX(1,3), M) !5度ずつ
   CASE 1 !-x
      CALL D3ROTATE(RAD(-5),AX(1,1),AX(1,2),AX(1,3), M)
   CASE 2 !+y
      CALL D3ROTATE(RAD(5),AX(2,1),AX(2,2),AX(2,3), M)
   CASE 3 !-y
      CALL D3ROTATE(RAD(-5),AX(2,1),AX(2,2),AX(2,3), M)
   CASE 4 !+z
      CALL D3ROTATE(RAD(5),AX(3,1),AX(3,2),AX(3,3), M)
   CASE 5 !-z
      CALL D3ROTATE(RAD(-5),AX(3,1),AX(3,2),AX(3,3), M)
   CASE ELSE
      MAT M=IDN
   END SELECT
   MAT T=BX*M
   MAT BX=T


   CALL button(-2.0,0.0, 0.6,0.3, 6, BTN$,S) !図形の平行移動メニュー
   SELECT CASE S
   CASE 0 !+x
      CALL VEC3NORMALIZE(AX(1,1),AX(1,2),AX(1,3), xx,yy,zz) !方向ベクトル
   CASE 1 !-x
      CALL VEC3NORMALIZE(-AX(1,1),-AX(1,2),-AX(1,3), xx,yy,zz)
   CASE 2 !+y
      CALL VEC3NORMALIZE(AX(2,1),AX(2,2),AX(2,3), xx,yy,zz)
   CASE 3 !-y
      CALL VEC3NORMALIZE(-AX(2,1),-AX(2,2),-AX(2,3), xx,yy,zz)
   CASE 4 !+z
      CALL VEC3NORMALIZE(AX(3,1),AX(3,2),AX(3,3), xx,yy,zz)
   CASE 5 !-z
      CALL VEC3NORMALIZE(-AX(3,1),-AX(3,2),-AX(3,3), xx,yy,zz)
   CASE ELSE
      LET xx=0
      LET yy=0
      LET zz=0
   END SELECT
   CALL D3SHIFT(xx*0.05,yy*0.05,zz*0.05, M) !0.05ずつ
   MAT T=BX*M
   MAT BX=T


   !XYZ軸を描く

   ! (x,y,z) → (x,y)
   !  Y
   !  ↑
   !  Z→X
   ! のXY平面へ投影する。

   SET LINE COLOR 4 !X軸
   PLOT LINES: AX(1,1),AX(1,2); 0,0
   PLOT TEXT, AT AX(1,1),AX(1,2): "x"
   SET LINE COLOR 3 !Y軸
   PLOT LINES: AX(2,1),AX(2,2); 0,0
   PLOT TEXT, AT AX(2,1),AX(2,2): "y"
   SET LINE COLOR 2 !Z軸
   PLOT LINES: AX(3,1),AX(3,2); 0,0
   PLOT TEXT, AT AX(3,1),AX(3,2): "z"


   !立方体を描く
   SET LINE COLOR 1
   FOR i=1 TO 3 !上面
      PLOT LINES: BX(i,1),BX(i,2); BX(i+1,1),BX(i+1,2)
   NEXT i
   PLOT LINES: BX(4,1),BX(4,2); BX(1,1),BX(1,2)
   FOR i=1 TO 4 !側面
      PLOT LINES: BX(i,1),BX(i,2); BX(i+4,1),BX(i+4,2)
   NEXT i
   FOR i=5 TO 7 !下面
      PLOT LINES: BX(i,1),BX(i,2); BX(i+1,1),BX(i+1,2)
   NEXT i
   PLOT LINES: BX(8,1),BX(8,2); BX(5,1),BX(5,2)


   SET DRAW mode explicit !ちらつき防止(終了)

   WAIT DELAY 0.1

LOOP

SUB button(x,y, dx,dy, n, btn$(),s) !左上位置(x,y)、大きさdx,dy、n個のボタン
   LET xx=x
   LET yy=y
   FOR i=1 TO n
      PLOT LINES: xx,yy; xx+dx,yy !枠を描く
      PLOT LINES: xx+dx,yy; xx+dx,yy-dy
      PLOT LINES: xx+dx,yy-dy; xx,yy-dy
      PLOT LINES: xx,yy-dy; xx,yy
      PLOT TEXT ,AT xx+dx/3,yy-4*dy/5: btn$(i) !名前 ※調整が必要
      LET yy=yy-dy
   NEXT i

   mouse poll mx,my,left,right !マウスポインタの位置を得る

   LET s=-1
   FOR K=0 TO 6-1
      IF ABS(mx-(x+dx/2))<dx/2 AND ABS(my-((y-dy*K)-dy/2))<dy/2 THEN LET s=K !k番目のボタン内なら
   NEXT K
   !!!PRINT s !debug
END SUB

END


EXTERNAL SUB VEC3NORMALIZE(Vx,Vy,Vz, x,y,z) !単位ベクトルへ
LET l=SQR(Vx*Vx+Vy*Vy+Vz*Vz)
IF l<>0 THEN
   LET x=Vx/l
   LET y=Vy/l
   LET z=Vz/l
END IF
END SUB

EXTERNAL SUB D3ROTATE(a,Vx,Vy,Vz, M(,)) !任意軸(位置ベクトル(Vx,Vy,Vz) )まわりの回転
CALL VEC3NORMALIZE(Vx,Vy,Vz, x,y,z)
LET c=COS(a)
LET s=SIN(a)
MAT M=ZER
LET M(1,1)=x*x*(1-c)+c
LET M(1,2)=x*y*(1-c)+z*s
LET M(1,3)=z*x*(1-c)-y*s
LET M(2,1)=x*y*(1-c)-z*s
LET M(2,2)=y*y*(1-c)+c
LET M(2,3)=y*z*(1-c)+x*s
LET M(3,1)=z*x*(1-c)+y*s
LET M(3,2)=y*z*(1-c)-x*s
LET M(3,3)=z*z*(1-c)+c
LET M(4,4)=1
END SUB


EXTERNAL SUB D3SCALE(a,b,c, M(,)) !拡大・縮小
MAT M=IDN
LET M(1,1)=a
LET M(2,2)=b
LET M(3,3)=c
END SUB


EXTERNAL SUB D3SHIFT(l,m,n, A(,)) !平行移動
MAT A=IDN
LET A(4,1)=l
LET A(4,2)=m
LET A(4,3)=n
END SUB


 

3D回転処理

 投稿者:lark12_long  投稿日:2014年 5月12日(月)05時18分45秒
  山中和義様
早速、模範プグラム提示いただき有難うございました
任意の単位ベクトル周りにθ回転する行列を使う事しりました

横長の広角画面表示に改造しました
今後、これを使用して、3D空間の運動等の、シミュレーション実験を、しようと思ってます
 

戻る