Gloss を使った Turtle Graphics です。Gloss については こちら の記事が参考になる と思います。
app / Main.hs -- 実験用 sample ├ circleDance.hs -- 複数の円を同時に描く ├ dragonCurve.hs -- dragon 曲線を描く ├ kochCurve.hs -- Koch 曲線を描く ├ graph.hs -- 関数のグラフを描く └ star.hs -- 星を描く sample / L-system ├ dragonCurveL.hs -- L-system で dragon 曲線を描く └ kochCurveL.hs -- L-system で Koch 曲線を描く src / Graphics ├ Turtle.hs -- Turtle Graphics 本体 └ L_system.hs -- L-System
stack build
を実行することで sample ディレクトリ以下にあるファイルがコン パイルされ、CircleDance, DragonCurve, KochCurve, Graph, Star, DragonCurveL, KochCurveL
といったファイルが作られます。stack exec CircleDance
やstack exec DragonCurveL
を実行すると図形が 描画されます。
使用例を示します。
import Graphics.Gloss
import Graphics.Turtle
main :: IO ()
main = runTurtle window white 20 [(st, cmdLst)]
where
window = initWindow
st = initST
cmdLst = [forward 200, left 120, forward 200, left 120, forward 200]
runTurtle
の型は次のようになってます。
runTurtle :: WinConfig -- ^ 画面の状態
-> Color -- ^ 背景色
-> Int -- ^ 1 秒あたりのステップ数
-> [(TurtleST, [Command])] -- ^ [ ( 亀の初期値, [ コマンド ] ) ]
-> IO ()
Color
は gloss
の simulate
関数に渡すものです。詳しくは こちら を参照し
てください。
WinConfig
は画面の設定を保持しています。
data WinConfig = WinConfig { title :: String -- ^ Window のタイトル
, winSize :: (Int, Int) -- ^ Window のサイズ
, winPos :: (Int, Int) -- ^ Window の位置
, zoom :: Float -- ^ 画像の拡大率
, shiftXY :: (Float, Float) -- ^ 画像の移動量
} deriving Show
initWindow
で既定値に設定することが可能です。
initWindow :: WinConfig
initWindow = WinConfig { title = "Turtle Graphics"
, winSize = (800, 600)
, winPos = (10, 10)
, zoom = 1
, shiftXY = (0, 0)
}
TurtleST
は亀の状態を保持します。
data TurtleST = Non | TurtleST { headinig :: Float -- ^ 亀の向き
, point :: Point -- ^ 亀の位置
, penColor :: Color -- ^ ペンの色
, thickness :: Float -- ^ 線の太さ
, pen :: Bool -- ^ up or down
, mark :: Bool -- ^ 亀のマーク
, stack :: TurtleST
} deriving Show
TurtleST
は initST
で既定値を設定できます。
initST = TurtleST { angle = 0
, point = (0, 0)
, thickness = 0
, penColor = black
, pen = True
, mark = True
, stack = Non
}
Command
は亀に実行させる命令です。
各コマンドの型は次のようになっています。
type PrimitiveCommand = TurtleST -> (Picture, TurtleST)
type Command = [PrimitiveCommand]
PrimitiveCommand
は TurtleST
を受け取り、図形 (Picture) とコマンド実行後の
TurtleST
を返します。
Command
は PrimitiveCommand
のリストになっており、通常はこちらを使用します。
コマンド | 省略形 | 動作 |
---|---|---|
forward n | fd n | 亀が n だけ前進する。 |
quickForward n | qf n | 亀が高速に前進する。 |
backward n | bk n | 亀が n だけ後退する。 |
left th | lt th | 亀が th 度だけ左旋回する。 |
quickLeft th | ql th | 亀が高速に左旋回する。 |
right th | rt th | 亀が th 度だけ右旋回する。 |
quickRight th | qr th | 亀が高速に右旋回する。 |
goto p | – | 亀が p の位置へ移動する。亀は進行方向を向く。 |
setHeading th | – | 亀の向きを th 度に設定する。 |
setPoint p | – | 亀の位置を p に設定する。 |
setThickness t | – | 線の太さを t に設定する。 |
setColor c | – | 亀のペンの色を c に設定する。 |
penDown | pd | 亀のペンを下げる。亀が移動すると線が描かれる。 |
penUp | pu | 亀のペンを上げる。亀が移動しても線は描かれない。 |
push | – | 亀の状態を Push する。 |
pop | – | 亀の状態を Pop する。 |
nop | – | 何もしない。 |
nopN n | – | n 回 nop を繰り返す。 |
drawPicture pic | – | 画像 pic を描く。 |
dot | – | 亀の位置に点を打つ。 |
drawCircle r | – | 亀の位置を中心に、半径 r の円を描く。 |
drawCircleSolid r | – | 亀の位置を中心に、半径 r の Solid な円を描く。 |
drawArcL th r | – | 中心角 th , 半径 r の円弧を左回りに描く。 |
quickDrawArcL th r | – | 中心角 th , 半径 r の円弧を左回りに高速に描く。 |
drawArcR th r | – | 中心角 th , 半径 r の円弧を右回りに描く。 |
quickDrawArcR th r | – | 中心角 th , 半径 r の円弧を右回りに高速に描く。 |
drawPolygon [Command] | – | 亀の描いた線を元に solid な Polygon を描く。 |
drawGraph fx domain | – | y = f(x) の陽関数のグラフを描く。 |
drawGraph’ ft gt domain | – | x = f(t), y = g(t) の関数のグラフを描く。 |
grid | – | grid’ 500 10 |
grid’ range size | – | -size ~ size の範囲に目盛サイズ size の方眼を表示する。 |
updateHeading f | – | 亀の向きを関数 f に従って更新する。 |
updatePoint f | – | 亀の位置を関数 f に従って更新する。 |
updateThickness f | – | 線の太さを関数 f に従って更新する。 |
updateColor fr fg fb fa | – | ペンの色の成分を関数 fr fg fb fa に従って更新する。 |
repCommand n [command] | – | 複数のコマンドの繰り返しを1つのコマンドにする |