由于Tomas说你可以使用缩放转换。如果要使用较小的曲线来绘制一个圆,你可以使用多个DrawCurve
电话:)
我已经改变了一下乔恩的代码用于该目的:
下面的代码:
module Seq =
/// Split a sequence into pieces, each n items long
/// repeating elements between start and end of subsequences.
let splitRepeatEvery (count : int) (source : seq<'T>) =
if not (count > 1) then failwith "count must be superior to 1"
seq { use e = source.GetEnumerator()
let hasNext = ref (e.MoveNext())
while !hasNext do
let (block:option<'T>[]) = Array.create count None
for i in 0 .. count - 1 do
do block.[i] <- if !hasNext then Some(e.Current) else None
if (i <> count - 1) then do hasNext := e.MoveNext()
yield seq { yield! block }
|> Seq.filter (fun x -> x.IsSome)
|> Seq.map (function Some(e) -> e | _ -> failwith "") }
let unit_circle (angle : float) =
(sin <| 2.0 * Math.PI * angle), (cos <| 2.0 * Math.PI * angle)
let draw_connected curve radius (seqOfAngles : float seq seq) knotsCount =
let form = new Form(Text = "Curve")
let computeBoundingBox points =
let search f acc array =
Array.fold (fun (x,y) (p:Point) -> f p.X x, f p.Y y) acc array
let minX, minY = search min (form.ClientSize.Width, form.ClientSize.Height) points
let maxX, maxY = search max (0,0) points
new Rectangle(minX, minY, abs(minX-maxX), abs(minY-maxY))
let drawCurves (gfx : Graphics) =
// Create a buffer for storing our knots
let buffer = Array.create knotsCount (new Point())
let mutable i = 0
for angles in seqOfAngles do
for angle in angles do
let x, y = curve angle
let X = int(x * radius + (float)form.ClientSize.Width/2.0)
let Y = int(y * radius + (float)form.ClientSize.Height/2.0)
let P = new Point(X, Y)
buffer.[i] <- P
i <- i + 1
let knots = buffer.[0..(i-1)]
// Draw spline only if we have one or more knots
if knots.Length <> 1 then
gfx.DrawCurve(Pens.Red, knots)
// For debug: compute BBox of an array of points and draw it
let debugRect = computeBoundingBox knots
gfx.DrawRectangle(Pens.Black, debugRect)
// Don't forget to reset position in buffer between each spline draw call
i <- 0
form.Paint.Add (fun pntEvntArgs -> drawCurves pntEvntArgs.Graphics)
form.Show()
form
// Define constants
let STEP = 0.050
let N = 4
// Define a new sequence of sequence of angles
let s = {0.0 .. STEP .. 1.0} |> Seq.splitRepeatEvery N
let form = draw_connected unit_circle 120.0 s N
// For debug: print sequence of sequence of angles
s |> Seq.iter (fun s -> Seq.iter (fun x -> printf "%f " x) s; printfn "")
while form.Created do
Thread.Sleep (1)
Application.DoEvents()
done
您可以用N
(数量的结对花键)和STEP
不同的值发挥(但要注意STEP
应该选择1.0f是STEP
的倍数或浮点数,以便最后一个序列的最后一个元素关闭en到1.0f else,最后的样条将不会连接到第一个样条!)。瞧!
alt text http://img818.imageshack.us/img818/9765/circles3.png