เป็นชุด ที่ถูกพัฒนาจาก Microsoft ครับ
หรืออยู่ในชุด Visual Studio 2010 ครับ น่าจะใช้ .NET Framework 3.5 # F, G, A, B are drawn as a move forward.
# + is a turn right.
# - is a turn right.
# X, Y and anything else is skipped during rendering.
open System.Windows
open System.Windows.Shapes
let rec internal applyRulesInOrder rules c =
match rules with
| [] -> string c
| rule::rules' ->
match rule c with
| None -> applyRulesInOrder rules' c
| Some result -> result
let internal step rules current =
current
|> String.collect (applyRulesInOrder rules)
let internal rotate (x,y) theta =
let x' = x * cos theta - y * sin theta
let y' = x * sin theta + y * cos theta
(x',y')
let rec internal render (x,y) (dx,dy) angle points system =
match system with
| [] -> (x,-y)::points
| 'A'::system' | 'B'::system' | 'F'::system' | 'G'::system' ->
let x',y' = x+dx,y+dy
render (x',y') (dx,dy) angle ((x,-y)::points) system'
| '+'::system' ->
let (dx',dy') = rotate (dx,dy) angle
render (x,y) (dx',dy') angle points system'
| '-'::system' ->
let (dx',dy') = rotate (dx,dy) (-angle)
render (x,y) (dx',dy') angle points system'
| _::system' ->
render (x,y) (dx,dy) angle points system'
let rec internal applyN f n x =
if n = 0 then x
else f (applyN f (n-1) x)
let internal normalize points =
let minX = points |> Seq.map (fun (x,_) -> x) |> Seq.min
let minY = points |> Seq.map (fun (_,y) -> y) |> Seq.min
points |> List.map (fun (x,y) -> new Point(x-minX, y-minY))
type LSystem(rulesString:string, start:string, angle:int, stepSize:int, n:int) =
let expanded,isError =
try
let rules =
rulesString.Split([|"\r";"\n"|], System.StringSplitOptions.RemoveEmptyEntries)
|> Array.map (fun line -> line.Split([|"->"|], System.StringSplitOptions.RemoveEmptyEntries))
|> Array.map (fun fromAndTo -> (fromAndTo.[0].[0], fromAndTo.[1]))
let ruleFunctions = [ for (c, s) in rules -> fun x -> if x = c then Some s else None]
applyN (step ruleFunctions) n start, false
with
| e -> "", true
member this.Render(polyline : Polyline) =
let points = render (0.0,0.0) (float stepSize,0.0) (float angle * System.Math.PI / 180.0) [] (List.of_seq expanded)
for pt in normalize points do polyline.Points.Add(pt)
isError