|
FullBASICでは、3D仕様の文・関数がありません。
2Dの絵定義を、副プログラムなどを使って、擬似的に拡張することを考えてみました。
●稜線モデル
!立体図の表現
PUBLIC NUMERIC T(4,4) !変換行列 ※TRANSFORM関数の値に相当
MAT T=IDN
PUBLIC NUMERIC D(4,4) !投影法の変換行列
MAT D=IDN
PUBLIC NUMERIC XX(20),YY(20) !描画する点列
DIM W(4,4),WW(4,4) !DRAW pict WITH ~ 算出用
DIM TT(4,4) !スタック領域
!---
!家の頂点の定義(ワイヤーフレーム)
DATA 8
DATA 80,50,100 !0
DATA 0,50,100 !1
DATA 0, 0,100 !2
DATA 80, 0,100 !3
DATA 80, 0, 0 !4
DATA 80,50, 0 !5
DATA 80,50,100 !6
DATA 80, 0,100 !7
DATA 4
DATA 0,50,100 !8
DATA 0,50, 0 !9
DATA 0, 0, 0 !10
DATA 0, 0,100 !11
DATA 2
DATA 0,50, 0 !12
DATA 80,50, 0 !13
DATA 2
DATA 0, 0, 0 !14
DATA 80, 0, 0 !15
DATA 3
DATA 0,50,100 !16
DATA 40,80,100 !17
DATA 80,50,100 !18
DATA 3
DATA 0,50, 0 !19
DATA 40,80, 0 !20
DATA 80,50, 0 !21
DATA 2
DATA 40,80,100 !22
DATA 40,80, 0 !23
DATA 8
DATA 50,72,100 !24
DATA 50,90,100 !25
DATA 65,90,100 !26
DATA 65,61,100 !27
DATA 65,61, 80 !28
DATA 65,90, 80 !29
DATA 50,90, 80 !30
DATA 50,90,100 !31
DATA 2
DATA 65,90,100 !32
DATA 65,90, 80 !33
DATA 3
DATA 50,90, 80 !34
DATA 50,72, 80 !35
DATA 65,61, 80 !36
DATA 2
DATA 50,72,100 !37
DATA 50,72, 80 !38
DATA -1 !EOF
!--- SET PROJECTION WINDOW x1,x2,y1,y2
SET WINDOW -120,120,-120,120 !投影面の表示領域 ※
!---
!--- SET PROJECTION MODE isometric
!!CALL orthographic(1, 40,50,50, D)
!!CALL axonometric(RAD(20),RAD(-45),RAD(0), D)
CALL isometric(D)
!!CALL cabinet(D)
!!CALL perspective2p(RAD(-25),0,50,0,-300, D)
!---
!--- DRAW house
CALL house
!---
!--- PICTURE house
SUB house
local TT(4,4) !スタック領域
!---
!--- DRAW D3GRID(150,100,150) !ローカル座標
CALL D3GRID(150,100,150)
!---
READ N !データ列を読み込む
DO WHILE N>0 !最後なら、終了
FOR i=1 TO N
READ x,y,z
!--- PLOT LINES: x,y,z; !折れ線
CALL L2WV(1, x,y,z)
PLOT LINES: XX(1),YY(1);
!---
NEXT i
!--- PLOT LINES
PLOT LINES
!---
READ N !次へ
LOOP
!--- END PICTURE
END SUB
!---
END
!立体図の表現
!
!投影法と投影図
! 透視投影法(Perspective projection、中心投影法)
! 1点投影法
! 2点投影法
! 3点投影法
! 平行投影法(Parallel projection)
! 垂直(直角)投影法
! 正投影法(Orthographic projection) → 正投影図(三面図)
! 第一角法
! 第三角法
! 軸測投影法(アクソノメトリック投影法、Axonometric projection)
! 等角投影法(アイソメトリック投影法、Isometric projection、等軸測投影法)→ 等角図(アイソメトリック図)
! 二等角投影法(ダイメトリック投影法、Dimetric projection)
! 不等角投影法(トリメトリック投影法、Trimetric projection)
! 斜投影法(Oblique projection)
! → キャビネット図、カバリエ図
EXTERNAL SUB L2WV(k, x,y,z) !座標変換 (x' y' z' w')=(x y z 1)*T[n]* … *T[3]*T[2]*T[1]*T[0]
DIM P(4) !同次座標系
LET P(1)=x
LET P(2)=y
LET P(3)=z
LET P(4)=1 !w
MAT P=P*T !変換
MAT P=P*D
LET XX(k)=P(1)/P(4) !(x'[k]/w', y'[k]/w')
LET YY(k)=P(2)/P(4)
END SUB
EXTERNAL SUB D3ROTATE(a,Vx,Vy,Vz, M(,)) !任意軸(位置ベクトル(Vx,Vy,Vz) )まわりの回転
LET l=SQR(Vx*Vx+Vy*Vy+Vz*Vz) !単位ベクトルへ
LET x=Vx/l
LET y=Vy/l
LET z=Vz/l
MAT M=ZER
LET c=COS(a)
LET s=SIN(a)
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 D3SHEAR(a,b,c, M(,)) !傾ける(せん断)
MAT M=IDN
LET M(1,2)=TAN(a)
LET M(1,3)=TAN(a)
LET M(2,1)=TAN(b)
LET M(2,3)=TAN(b)
LET M(3,1)=TAN(c)
LET M(3,2)=TAN(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
!共通ルーチン
EXTERNAL SUB D3GRID(x,y,z) !XYZ座標軸を表示する
ASK LINE COLOR c1 !save it
ASK TEXT COLOR c2
SET LINE COLOR 4 !X軸
!--- PLOT LINES: 0,0,0; x,0,0
CALL L2WV(1, 0,0,0)
CALL L2WV(2, x,0,0)
PLOT LINES: XX(1),YY(1); XX(2),YY(2) !線分
!---
!--- PLOT TEXT ,AT x,0,0: "X"
SET TEXT COLOR 4
PLOT TEXT ,AT XX(2),YY(2): "X"
!---
SET LINE COLOR 3 !Y軸
!--- PLOT LINES: 0,0,0; 0,y,0
CALL L2WV(1, 0,0,0)
CALL L2WV(2, 0,y,0)
PLOT LINES: XX(1),YY(1); XX(2),YY(2) !線分
!---
!--- PLOT TEXT ,AT 0,y,0: "Y"
SET TEXT COLOR 3
PLOT TEXT ,AT XX(2),YY(2): "Y"
!---
SET LINE COLOR 2 !Z軸
!--- PLOT LINES: 0,0,0; 0,0,z
CALL L2WV(1, 0,0,0)
CALL L2WV(2, 0,0,z)
PLOT LINES: XX(1),YY(1); XX(2),YY(2) !線分
!---
!--- PLOT TEXT ,AT 0,0,z: "Z"
SET TEXT COLOR 2
PLOT TEXT ,AT XX(2),YY(2): "Z"
!---
SET LINE COLOR c1 !restore it
SET TEXT COLOR c2
END SUB
!投影図
!右手座標系
! X軸…親指、Y軸…人差し指、Z軸…中指、指のさす方向が正(プラス)。
! 右手系 Y
! │
! ・─X
! /
! Z X軸…右方向、Y軸…高さ、Z軸…奥行き。(XZ平面は床)
EXTERNAL SUB orthographic(i, l,m,n, W(,)) !正投影図(三面図) ※第三角法
DIM WW(4,4)
CALL D3SHIFT(-l,-m,-n, W) !図面の中心 ※(l,m,n)→(0,0)
SELECT CASE i
CASE 0 !正面図
!nop
CASE 1 !平面図
CALL D3ROTATE(RAD(90),1,0,0, WW) !X軸
MAT W=W*WW
CASE 2 !右側面図
CALL D3ROTATE(RAD(-90),0,1,0, WW) !Y軸
MAT W=W*WW
CASE ELSE
PRINT "引数が不正です。"
STOP
END SELECT
END SUB
EXTERNAL SUB axonometric(ax,ay,az, W(,)) !軸測投影図
DIM WW(4,4)
MAT W=IDN
CALL D3ROTATE(ay,0,1,0, WW) !Y軸
MAT W=W*WW
CALL D3ROTATE(ax,1,0,0, WW) !X軸
MAT W=W*WW
CALL D3ROTATE(az,0,0,1, WW) !Z軸
MAT W=W*WW
END SUB
EXTERNAL SUB isometric(W(,)) !等角投影(アイソメトリック)図
DIM WW(4,4)
MAT W=IDN
CALL D3ROTATE(RAD(-45),0,1,0, WW) !Y軸 ※方位角45度
MAT W=W*WW
CALL D3ROTATE(ATN(SQR(2)/2),1,0,0, WW) !X軸 ※天頂角54.7356度
MAT W=W*WW
END SUB
EXTERNAL SUB cabinet(W(,)) !キャビネット図
DIM WW(4,4)
MAT W=IDN
CALL D3SCALE(1,1,SQR(2)/4, WW) !Z軸を1/2
MAT W=W*WW
CALL D3SHEAR(RAD(0),RAD(0),RAD(-45), WW) !Z軸で傾ける
MAT W=W*WW
END SUB
EXTERNAL SUB perspective2p(ay, l,m,n, vp, W(,)) !2点透視投影図
DIM WW(4,4)
MAT W=IDN
CALL D3SHIFT(-l,-m,-n, WW) !平行移動 ※図面の中心 (l,m,n)→(0,0)
MAT W=W*WW
CALL D3ROTATE(ay,0,1,0, WW) !Y軸
MAT W=W*WW
!投影の中心(消失点)を(0,0,-VP)、投影面z=0(XY平面)とする。
MAT WW=IDN !ビュー変換
LET WW(4,3)=vp !視点を原点にする(平行移動)
MAT W=W*WW
MAT WW=ZER !透視投影
LET WW(1,1)=vp
LET WW(2,2)=vp
LET WW(3,4)=1
MAT W=W*WW
END SUB
●回転体モデル
!立体図の表現
PUBLIC NUMERIC T(4,4) !変換行列 ※TRANSFORM関数の値に相当
MAT T=IDN
PUBLIC NUMERIC D(4,4) !投影法の変換行列
MAT D=IDN
PUBLIC NUMERIC XX(20),YY(20) !描画する点列
DIM W(4,4),WW(4,4) !DRAW pict WITH ~ 算出用
DIM TT(4,4) !スタック領域
!---
!回転体モデル
!ワイングラスの頂点の定義(ワイヤーフレーム)
DATA 8
DATA 180,100 !高さ(0,y,0)、半径(r*cosθ,0,r*sinθ)
DATA 140, 55
DATA 100, 10
DATA 60, 10
DATA 20, 10
DATA 10, 50
DATA 4, 80
DATA 0, 80
!--- SET PROJECTION WINDOW x1,x2,y1,y2
SET WINDOW -150,150,-150,150 !投影面の表示領域 ※
!---
!--- SET PROJECTION MODE isometric
CALL isometric(D)
!!CALL perspective2p(RAD(-35),10,-30,0,-500, D)
!---
!--- DRAW model WITH D3ROTATEX(RAD(10))*D3SHIFT(0,-80,-20)
MAT TT=T !save it
MAT W=IDN
CALL D3ROTATE(RAD(10),1,0,0, WW)
MAT W=W*WW
CALL D3SHIFT(0,-80,-20, WW)
MAT W=W*WW
MAT T=W *T !変換行列を算出する
CALL model
MAT T=TT !restore it
!---
!--- PICTURE model
SUB model
local TT(4,4) !スタック領域
!---
!--- DRAW D3GRID(150,260,150) !ローカル座標
CALL D3GRID(150,260,150)
!---
READ N !データ列を読み込む
FOR i=1 TO N
READ y,r
FOR a=0 TO 360 STEP 5 !Y軸まわりに回転させる
LET th=RAD(a)
!--- PLOT LINES: r*COS(th),y,r*SIN(th); !折れ線による近似で円を描く
CALL L2WV(1, r*COS(th),y,r*SIN(th))
PLOT LINES: XX(1),YY(1);
!---
NEXT a
!--- PLOT LINES
PLOT LINES
!---
IF i>1 THEN
FOR a=0 TO 360 STEP 60 !稜線
LET th=RAD(a)
!--- PLOT LINES: r0*COS(th),y0,r0*SIN(th); r*COS(th),y,r*SIN(th)
CALL L2WV(1, r0*COS(th),y0,r0*SIN(th))
CALL L2WV(2, r*COS(th),y,r*SIN(th))
PLOT LINES: XX(1),YY(1); XX(2),YY(2)
!---
NEXT a
END IF
LET y0=y !次へ
LET r0=r
NEXT i
!--- END PICTURE
END SUB
!---
END
※サブルーチン部分は省略しています。
|
|