Created
November 6, 2015 00:19
-
-
Save mastoj/2eb06a39bc3de503f7a3 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
open System | |
open System.Drawing | |
open System.Windows.Forms | |
// Create a form to display the graphics | |
let width, height = 1000, 1000 | |
let form = new Form(Width = width, Height = height) | |
let box = new PictureBox(BackColor = Color.White, Dock = DockStyle.Fill) | |
let image = new Bitmap(width, height) | |
let graphics = Graphics.FromImage(image) | |
//The following line produces higher quality images, | |
//at the expense of speed. Uncomment it if you want | |
//more beautiful images, even if it's slower. | |
//Thanks to https://twitter.com/AlexKozhemiakin for the tip! | |
graphics.SmoothingMode <- System.Drawing.Drawing2D.SmoothingMode.HighQuality | |
let brush = new SolidBrush(Color.FromArgb(0, 0, 0)) | |
box.Image <- image | |
form.Controls.Add(box) | |
// Compute the endpoint of a line | |
// starting at x, y, going at a certain angle | |
// for a certain length. | |
let endpoint x y angle length = | |
x + length * cos angle, | |
y + length * sin angle | |
let flip x = (float)height - x | |
// Utility function: draw a line of given width, | |
// starting from x, y | |
// going at a certain angle, for a certain length. | |
let drawLine (target : Graphics) (brush : SolidBrush) | |
(x : float) (y : float) | |
(angle : float) (length : float) (width : float) | |
(color: Color) = | |
use brush2 = new SolidBrush(color) | |
let x_end, y_end = endpoint x y angle length | |
let origin = new PointF((single)x, (single)(y |> flip)) | |
let destination = new PointF((single)x_end, (single)(y_end |> flip)) | |
let pen = new Pen(brush2, (single)width) | |
target.DrawLine(pen, origin, destination) | |
let draw x y angle length width color = | |
drawLine graphics brush x y angle length width color | |
let pi = Math.PI | |
// Now... your turn to draw | |
// The trunk | |
//draw 250. 50. (pi*(0.5)) 100. 4. | |
//let x, y = endpoint 250. 50. (pi*(0.5)) 100. | |
//// first and second branches | |
//draw x y (pi*(0.5 + 0.3)) 50. 2. | |
//draw x y (pi*(0.5 - 0.4)) 50. 2. | |
let random = System.Random() | |
//let drawTree angle1Delta angle2Delta iterations = | |
let rec tree x y angle length width length1Div length2Div length3Div angle1Delta angle2Delta angle3Delta = | |
if length < 1.5 then () | |
else | |
let r = (random.Next(200/int length)) | |
let g = (random.Next(200/int length)) | |
let b = (random.Next(200/int length)) | |
let color = Color.FromArgb(r, g, b) | |
draw x y (pi*angle) length width color | |
let x', y' = endpoint x y (pi*angle) length | |
let chaosAngle1 = (random.NextDouble()*2. - 1.)/10. | |
let chaosAngle2 = (random.NextDouble()*2. - 1.)/10. | |
let chaosAngle3 = (random.NextDouble()*2. - 1.)/10. | |
tree x' y' (angle + (angle1Delta + chaosAngle1)) (length*length1Div) (width*length1Div) length1Div length2Div length3Div angle1Delta angle2Delta angle3Delta | |
tree x' y' (angle + (angle2Delta + chaosAngle2)) (length*length2Div) (width*length2Div) length1Div length2Div length3Div angle1Delta angle2Delta angle3Delta | |
tree x' y' (angle + (angle2Delta + chaosAngle3)) (length*length3Div) (width*length3Div) length1Div length2Div length3Div angle1Delta angle2Delta angle3Delta | |
//tree 250. 50. (pi*(0.5)) 100. 4. iterations | |
let rec forest numberOfTrees = | |
if numberOfTrees = 0 then () | |
else | |
let startX, startY = (random.Next(width/2)+250, 200+random.Next(height/3)) | |
let startLength = (random.Next(200) + 20) | |
let randDouble lower upper = random.NextDouble()*(upper-lower)+lower | |
let start1LengthDiv = randDouble 0.3 0.75 | |
let start2LengthDiv = randDouble 0.3 0.55 | |
let start3LengthDiv = randDouble 0.3 0.75 | |
let chunk = 1. + random.NextDouble()*7. | |
tree (float startX) (float startY) (0.5) (float startLength) chunk start1LengthDiv start2LengthDiv start3LengthDiv 0.3 -0.2 0.1 | |
forest (numberOfTrees-1) | |
forest 20 | |
form.ShowDialog() | |
(* To do a nice fractal tree, using recursion is | |
probably a good idea. The following link might | |
come in handy if you have never used recursion in F#: | |
http://en.wikibooks.org/wiki/F_Sharp_Programming/Recursion | |
*) | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment