Sunday, 14 November 2010

Visualizing a complete graph

Kean Walmsley posted an article describing how AutoCAD can be used to visualize a complete graph using vector graphics. This prompted Cay Horstmann to publish an article describing how the SPDE framework makes it possible to visualize the same thing using only 12 lines of Scala code. Here's how you can do the same thing in F# out-of-the-box in only 10 lines of code:

> #r "PresentationCore.dll";; > #r "PresentationFramework.dll";; > #r "System.Xaml.dll";; > #r "WindowsBase.dll";; > open System.Windows;; > let n = 24;; val n : int = 24 > let p i = let t = float(i % n) / float n * 2.0 * System.Math.PI Point(1.0 + sin t, 1.0 + cos t);; val p : int -> Point > let shape = Shapes.Polyline(Stroke=Media.Brushes.Black, StrokeThickness=0.001);; val shape : Shapes.Polyline > for i=0 to n-1 do for j=i+1 to n do Seq.iter shape.Points.Add [p i; p j];; val it : unit = () > Window(Content=Controls.Viewbox(Child=shape)) |> Application().Run |> ignore;;

When run from an F# interactive session, this program produces the following output:

Being able to solve simple problems simply and scale it up to sophisticated commercial software is why I love F#!


Cameron Taggart said...

I used your code to make a Silverlight demo application here:

Anonymous said...

5 lines in R for a direction translation:

n <-24
x <- (0:(n-1))/n *2 * pi
x0 <- rbind(1+ sin(x), 1+cos(x))

for (i in 1:(n-1))
for (j in (i+1):n){

Anonymous said...

we can remove the double loop in the above code to make it more R like:

n <-24

plot(1,1,xlim = c(0,2),ylim = c(0,2))

points <- lapply((0:(n-1))/n *2 * pi, function(x){c(1+ sin(x), 1+cos(x))})

combn(points,2,function(x){lines(c(x[[1]][1],x[[2]][1]),c(x[[1]][2],x[[2]][2]))},simplify = FALSE)

Art said...


Art said...

Re: Cameron's SL demo ... why the slow down towards the 48 end? And if it's cpu bound ... would there be a parallel speed up?


Jon Harrop said...

@Art: The slowdown is indeed CPU bound and parallelism would help enormously. However, the problem lies inside WPF itself (which is extremely inefficient) so there is nothing we can do.