この例題と次のDouble Torus(Tori)の作図は、コンピュータグラフィックスでは一種の古典的な例題です。トーラスそのものは位相幾何学では特別な意義があります。ここでの課題は立体図形を多面体で近似することと、その多面体の各面に注目し、この投影された領域を塗りつぶす処理を使って、隠れ線(または隠れ面)処理を簡単に行わせる作図法です。線図で隠れ線の計算をすると膨大な計算量が必要になります。この処理には、別の幾何モデリングのプログラムGEOMAPが扱っています。
領域の塗りつぶしの処理は、VBの基本メソッドには無くて、Win32APIのPolygonルーチンを使います。なお、立体図形の投影変換の技法も必要です。
Public Sub Proc14() 'single torus
Dim r1, r2, k1, k2, ip, lastp, zzzw, ippw
Dim th1, th2, xs1, ys1, xs2, ys2, xs3, ys3, xs4, ys4
Dim z, thz, thy, x1, y1
Dim xs(25, 17), ys(25, 17), zs(25, 17), zc(25, 17)
Dim zzz(), ipp()
Dim points(4) As POINTAPI
r1 = 150: r2 = 50: k1 = 24: k2 = 16: lastp = k1 * k2
ReDim zzz(lastp), ipp(lastp)
Select Case Ivar
Case 1: thy = 0.1
Case 2: thy = 0.6
Case 3: thy = 0.9
Case 4: thy = -0.6
Case Else: thy = 0.1
End Select
Dperas
Dpwind 0, 0, 640
'------ Camera Position
CamP(1) = 880
CamP(2) = 0
CamP(3) = 0
Dpcam 0.6, 0, Flen
Dpwind 0, 0, 640
N = 0
For th1 = 0 To 2 * pie + 0.1 Step 2 * pie / k1
N = N + 1: m = 0
For th2 = 0 To 2 * pie + 0.1 Step 2 * pie / k2
m = m + 1
Y = r1 + r2 * Cos(th2)
z = r2 * Sin(th2)
X = 0
thz = th1
Rotz X, Y, X, Y, thz
Roty z, X, z, X, thy
Projection X, Y, z
ys(N, m) = Gxxx
zs(N, m) = Gyyy
xs(N, m) = X
Next th2
Next th1
'
ip = 1
For N = 1 To k1
For m = 1 To k2
zc(N, m) = (xs(N, m) + xs(N + 1, m + 1)) / 2
zzz(ip) = zc(N, m): ipp(ip) = ip
ip = ip + 1
Next m
Next N
'sort---------------------------------
For i = 2 To lastp
For j = i - 1 To 1 Step -1
If zzz(j) > zzz(j + 1) Then
zzzw = zzz(j): zzz(j) = zzz(j + 1): zzz(j + 1) = zzzw
ippw = ipp(j): ipp(j) = ipp(j + 1): ipp(j + 1) = ippw
End If
Next j
Next i
'draw--------------------------------
For ip = 1 To lastp
N = Int((ipp(ip) - 1) / k2) + 1
m = (ipp(ip) - 1) Mod k2 + 1
xs1 = ys(N, m): ys1 = zs(N, m)
xs2 = ys(N + 1, m): ys2 = zs(N + 1, m)
xs3 = ys(N + 1, m + 1): ys3 = zs(N + 1, m + 1)
xs4 = ys(N, m + 1): ys4 = zs(N, m + 1)
If Int((ys4 - ys2) * (xs3 - xs1) + _
(ys3 - ys1) * (xs2 - xs4)) > 100 Then
points(1).X = Ipixelx(xs1)
points(2).X = Ipixelx(xs2)
points(3).X = Ipixelx(xs3)
points(4).X = Ipixelx(xs4)
points(1).Y = Ipixely(ys1)
points(2).Y = Ipixely(ys2)
points(3).Y = Ipixely(ys3)
points(4).Y = Ipixely(ys4)
Dpolyg points, 4
End If
Next ip
Dptext 150, 200, ("thy=" + CStr(thy))
End Sub