遠近感のある透視投影で立方体の投影図を描きます。
プログラムは平行投影変換とほぼ同じで、透視変換式が追加されています。
透視変換をプロシージャ化しようと思ったのですが、ちょっと面倒です。
ベタなやり方ですが各軸の回転変換の下にそれぞれ置いています。
spの値で遠近感が変わって来ます。
変換式は
sp:投影面と視点との距離
x1=sp*x/sp+z
y1=sp*y/sp+z
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101 %!PS-Adobe-3.0 EPSF-3.0
%%BoundingBox: 0 0 240 240
%%Title:立方体の投影
/yr -30 def % Y軸周りの回転角度
/xr -30 def % X軸周りの回転角度
/zr -30 def % Z軸周りの回転角度
/sp -800 def % 投影面と視点との距離
% 回転と描画プロシージャ
/rotation {
/sw exch def % 始点を置くかどうかを取得
% Y軸周りの回転
/x2 x1 yr cos mul z1 yr sin mul sub def
/y2 y1 def
/z2 x1 yr sin mul z1 yr cos mul add def
/x2 sp x2 mul sp z1 add div def % 透視投影変換
/y2 sp y2 mul sp z1 add div def % 透視投影変換
% X軸周りの回転
/x3 x2 def
/y3 z2 xr sin mul y2 xr cos mul add def
/z3 z2 zr cos mul y2 xr sin mul sub def
/x3 sp x3 mul sp z2 add div def % 透視投影変換
/y3 sp y3 mul sp z2 add div def
% Z軸周りの回転
/x4 y3 zr sin mul x3 zr cos mul add def
/y4 y3 zr cos mul x3 zr sin mul sub def
/x4 sp x4 mul sp z3 add div def % 透視投影変換
/y4 sp y4 mul sp z3 add div def
% 0なら始点、1なら線を引く、それ以外は線を引いた後、始点と線を繋ぐ
sw 0 eq { x4 y4 moveto } {
sw 1 eq { x4 y4 lineto }
{ x4 y4 lineto closepath } ifelse } ifelse
} def
% 立方体の座標
/a [-50 50 50 ] def /b [ 50 50 50 ] def
/c [ 50 -50 50 ] def /d [-50 -50 50 ] def
/e [-50 50 -50 ] def /f [-50 -50 -50 ] def
/g [ 50 50 -50 ] def /h [ 50 -50 -50 ] def
% 座標データを取得
/readdata { % ポイントの配列からデータを取り出し、それぞれの座標に入れる
/po exch def % 座標の配列名を取得
/x1 po 0 get def
/y1 po 1 get def
/z1 po 2 get def
} def
0 0 240 240 rectstroke % 黒背景
120 120 translate % 座標の原点を中央に移動
newpath
% 底面(オレンジ)
d readdata % 座標のポイント名を渡す
0 rotation % 始点か線を引くか(0 or 1)を渡し、回転して描画する
c readdata 1 rotation
h readdata 1 rotation
f readdata 2 rotation
1 .5 0 setrgbcolor fill % 色設定
% 奥面(赤)
e readdata 0 rotation
g readdata 1 rotation
h readdata 1 rotation
f readdata 2 rotation
1 0 0 setrgbcolor fill
% 左側面(青)
a readdata 0 rotation
e readdata 1 rotation
f readdata 1 rotation
d readdata 2 rotation
0 .6 1 setrgbcolor fill
% 右側面
g readdata 0 rotation
b readdata 1 rotation
c readdata 1 rotation
h readdata 2 rotation
1 0 1 setrgbcolor fill
% 上面(黄)
a readdata 0 rotation
b readdata 1 rotation
g readdata 1 rotation
e readdata 2 rotation
1 1 0 setrgbcolor fill
% 正面(紫)立法体の中を見せたいので描画しない
%a readdata 0 rotation
%b readdata 1 rotation
%c readdata 1 rotation
%d readdata 2 rotation
%.8 0 .8 setrgbcolor fill
コメント