|
■No99644 (魔界の仮面弁士 さん) に返信
> あるいは普通の PC 向けサイトの方が良いかと。
> http://rexpit.blog29.fc2.com/blog-entry-94.html
OpenTK というライブラリは知らなかったので、試しに上記サイトを VB に翻訳してみました。
一部、古い表記があったので、現行バージョン向けの記述に修正してあります。
フォームに GLControl を貼っておき、デザイン時にその Dock プロパティを
「Top, Left」から「Top, Bottom, Left, Right」に変更しておいてください。
Option Strict On
Imports OpenTK
Imports OpenTK.Graphics.OpenGL
Public Class Form1
' 表示領域の縦幅
Private ReadOnly _height As Double = 4.0
' 注視点
Private _centralPoint As Vector2 = Vector2.Zero
' マンデルブロ集合描画時の色リスト
Private ReadOnly _colorList As New List(Of Color)()
''' <summary>
''' コンストラクタ
''' </summary>
Public Sub New()
' この呼び出しはデザイナーで必要です。
InitializeComponent()
' InitializeComponent() 呼び出しの後で初期化を追加します。
' 色リストの初期化
InitializeColorList()
End Sub
''' <summary>
''' GL コントロールのロードイベント
''' </summary>
''' <remarks>Form の Load イベントと混同しないように注意</remarks>
Private Sub GlControl1_Load(sender As Object, e As EventArgs) Handles GlControl1.Load
GlControl1.MakeCurrent()
' 背景色の設定
GL.ClearColor(GlControl1.BackColor)
' Projection の設定
SetProjection()
End Sub
''' <summary>
''' GL コントロールのリサイズイベント
''' </summary>
Private Sub GlControl1_Resize(sender As Object, e As EventArgs) Handles GlControl1.Resize
GlControl1.MakeCurrent()
SetProjection()
GlControl1.Refresh()
End Sub
''' <summary>
''' GL コントロールの描画イベント
''' </summary>
Private Sub GlControl1_Paint(sender As Object, e As PaintEventArgs) Handles GlControl1.Paint
GlControl1.MakeCurrent()
GL.Clear(ClearBufferMask.ColorBufferBit)
GL.PointSize(1.0F)
Dim sideY = _height * 0.5R
Dim sideX = sideY * CDbl(GlControl1.AspectRatio)
DrawMandelbrot(_centralPoint.X - sideX, _centralPoint.X + sideX, _centralPoint.Y - sideY, _centralPoint.Y + sideY, GlControl1.Width, GlControl1.Height)
GlControl1.SwapBuffers()
End Sub
''' <summary>
''' 投影の設定
''' </summary>
Private Sub SetProjection()
' ビューポートの設定
GL.Viewport(0, 0, GlControl1.Width, GlControl1.Height)
' 変換行列の初期化
GL.LoadIdentity()
' 描画領域の設定
Dim sideY = _height * 0.5R
Dim sideX = sideY * GlControl1.AspectRatio
GL.Ortho(_centralPoint.X - sideX, _centralPoint.X + sideX, _centralPoint.Y - sideY, _centralPoint.Y + sideY, -1.0R, 1.0R)
End Sub
''' <summary>
''' 色リストの初期化
''' </summary>
Private Sub InitializeColorList()
_colorList.Add(Color.Black)
For i = 1 To 16
Dim x = 31 + 14 * i
_colorList.Add(Color.FromArgb(x, x, x))
Next
End Sub
''' <summary>
''' ある複素数がマンデルブロ集合の元かを調べる
''' </summary>
''' <param name="re">実部</param>
''' <param name="im">虚部</param>
''' <param name="nMax">漸化式を調べる回数</param>
''' <returns>複素数がマンデルブロ集合の元ならば0、そうでなければ0より大きい値</returns>
Private Function Mandelbrot(re As Double, im As Double, Optional nMax As Integer = 16) As Integer
Dim x = 0.0R, y = 0.0R, x1, y1 As Double
For n = 0 To nMax - 1
x1 = x * x - y * y + re
y1 = 2.0R * x * y + im
If x1 * x1 + y1 * y1 > 4.0R Then
Return n + 1
End If
x = x1
y = y1
Next
Return 0
End Function
''' <summary>
''' マンデルブロ集合を描画する。
''' </summary>
''' <param name="xMin">描画領域左端</param>
''' <param name="xMax">描画領域右端</param>
''' <param name="yMin">描画領域下端</param>
''' <param name="yMax">描画領域上端</param>
''' <param name="screenWidth">スクリーン横幅</param>
''' <param name="screenHeight">スクリーン縦幅</param>
Private Sub DrawMandelbrot(xMin As Double, xMax As Double, yMin As Double, yMax As Double, screenWidth As Integer, screenHeight As Integer)
Dim xDiff = xMax - xMin, yDiff = yMax - yMin
screenWidth += 1
screenHeight += 1
' 元記事ではこの記法が使われていましたが、これは古い書き方です。
' GL.Begin(BeginMode.Points)
' 現在は代わりに、PrimitiveType のオーバーロードを使用します。
GL.Begin(PrimitiveType.Points)
For i = 0 To screenWidth - 1
Dim x = xMin + xDiff * i / screenWidth
For j = 0 To screenHeight - 1
Dim y = yMin + yDiff * j / screenHeight
GL.Color3(_colorList(Mandelbrot(x, y, 16)))
GL.Vertex2(x, y)
Next
Next
GL.End()
End Sub
End Class
|