I have the following codes to draw an unit circle
open System
open Microsoft.FSharp.Collections
open Microsoft.FSharp.Math
open System.Drawing
open System.Windows.Forms
let make_point (x:float) (y:float) = (fun bit -> if bit = 0.0 then x else y)
let x_of (point:float->float) = point 0.0
let y_of (point:float->float) = point 1.0
let unit_circle (t:float) =
make_point (sin <| 2.0 * Math.PI * t)
(cos <| 2.0 * Math.PI * t)
let draw_connected (curve:float->float->float) (values: float list)=
let form = new Form(Text = "Curve")
let drawCurve (g:Graphics) =
for t in values do
let p = curve t
g.DrawEllipse(Pens.Red,
float32 (x_of p * 50.0 + (float)form.ClientSize.Width / 2.0),
float32 (y_of p * 50.0 + (float)form.ClientSize.Height / 2.0),
float32 1,
float32 1)
form.Paint.Add(fun e -> drawCurve e.Graphics)
form.Show()
draw_connected unit_circle ([0.0 .. 0.01 .. 1.0])
I am not entirely satisfied because I have to manual "scale" the x and y coordinates by 50 to make the circle visible. Is there a way to get F# do the scaling automatically?
Thanks.
I think the code is representing a 2D point as a function taking 3 args - a flag, x & y. The flag indicates which of x and y to return. It would make (slightly) more sense for a start if the flag was a bool rather than a float. I'm guessing the code has been converted from another language which only has floats?
Here's a slightly more comprehensible version:
open System
open Microsoft.FSharp.Collections
open Microsoft.FSharp.Math
open System.Drawing
open System.Windows.Forms
open System.Threading
type Point = {x : float; y : float}
let unit_circle (angle : float) =
{
x = (sin <| 2.0 * Math.PI * angle)
y = (cos <| 2.0 * Math.PI * angle)
}
let draw_connected (curve : float -> Point) (radius : float) (angles : float list) =
let form = new Form(Text = "Curve")
let drawCurve (gfx : Graphics) =
for angle in angles do
let p = curve angle
gfx.DrawEllipse(Pens.Red,
float32 (p.x * radius + (float)form.ClientSize.Width / 2.0),
float32 (p.y * radius + (float)form.ClientSize.Height / 2.0),
float32 1,
float32 1)
form.Paint.Add (fun pntEvntArgs -> drawCurve pntEvntArgs.Graphics)
form.Show ()
form
let form = draw_connected unit_circle 50.0 ([0.0 .. 0.01 .. 1.0])
while form.Created do
Thread.Sleep (1)
Application.DoEvents ()
done
Not sure why the circle is rendered as a collection of 1 pixel ellipses.
In any case, as Tomas says, either the circle has to be scaled or the coordinate system does. Otherwise you'll end up with a 1 pixel circle.