Quantcast
Channel: Scott Hanselman's Blog
Viewing all articles
Browse latest Browse all 1148

Generating complex math visualizations in SVG using C# and ILNumerics

$
0
0

I was recently turned on to the ILNumerics library. It's a high performance math library for .NET developers that my math skills can barely comprehend. It has a clean and elegant syntax, but more importantly, it's visualization graphics engine is thoughtful, flexible, and well-factored.

Having worked on a lot of websites, including ones that do a lot of backend image generation, resizing and analysis (like check imaging almost 10 years ago) I was impressed at how easily I was able to get an equation onto a basic website with ILNumerics and SVG.

Of course, it's not just a web library, in fact, most of the samples are WPF and WinForms, so it's an engine that you can use anywhere. Regardless, as a web person, I wanted to see how quickly I could get something into my browser.

The ILNumerics website has a cool sample 3D graph on their home page that was generated with this code:

var scene = new ILScene {
new ILPlotCube(twoDMode: false) {
new ILSurface(ILSpecialData.sincf(40, 60, 2.5f)) {
}
}
};
scene.First<ILPlotCube>().Rotation = Matrix4.Rotation(
new Vector3(1f,0.23f,1), 0.7f);
scene;

However, you'll notice in their sample they just end with the variable "scene." That's a no-op there, but it's their coder way of saying "at this point, the scene variable holds a representation of our plot. Do with it as you will."

NOTE:Do check out their home page...the little sample there is deeper than you'd think. The dropdown shows they can generate PNGs, JPGs, JPG HD, SVG, but also "EXE." Hm, download a random EXE from the internet? Yes please! ;) Take a risk and you'll get a nice self-contained EXE visualizer that not only renders the graph but lets you rotate it. You can download the ILView 3D viewer and play around, it's harmless - all the code for ILView is on GitHub! The best part is that it has a built in REPL so you can type your C# right there and see the results! It even runs on Linux and uses Mono. ;)

ILNumeric

Back to my goal. I want to use the library on a basic website and dynamically generate an SVG of this plot.

Here's the same plot, put inside an ASP.NET HttpHandler (which could also be made routable and used in ASP.NET MVC/Web Forms, etc.)

public void ProcessRequest(HttpContext context)
{
var scene = new ILScene {
new ILPlotCube(twoDMode: false) {
new ILSurface(ILSpecialData.sincf(40, 60, 2.5f)) {
}
}
};
scene.First<ILPlotCube>().Rotation = Matrix4.Rotation(
new Vector3(1f, 0.23f, 1), 0.7f);

var driver = new ILSVGDriver(context.Response.OutputStream, 1200, 800, scene, Color.White);
driver.Render();
}

Here I'm passing context.Response.OutputStream to their ILSVGDriver and saving the result not to a file, but directly out to the browser. I could certainly save it to cloud blob storage or a local file system for caching, reuse or email.

using (FileStream fs = new FileStream(@"test.svg", FileMode.Create)) {
new ILSVGDriver(fs, scene: whateveryoursceneis).Render();
}

While a SVG is preferable, one could also make a PNG.

var driver = new ILGDIDriver(1280, 800, whateveryoursceneis); 
driver.Render();
driver.BackBuffer.Bitmap.Save("whatever", System.Drawing.Imaging.ImageFormat.Png);

Their docs are excellent and many include a similar interactive viewer within the website itself.

It's so much more than a plot visualizer, though. It reminds me a little of D3.js, except more math focused and less live-data binding. It's almost as flexible though, with many kinds of visualizations beyond what you'd expect.

3D graph that looks like a mountainDonut graph

Three 3D graphs in one plotTopographical plot

Infinite TrianglesHalf a sphere intersected by a blue gear

Here's the code to show a green sphere that's composed of triangles, but has the top chopped off, as an example. This is just 10 lines of code, and could be made less.

var scene = new ILScene(); 
// create a new sphere
var sphere = new ILSphere();
// the sphere is a group containing the Fill (ILTriangles)
// and the Wireframe (ILLines) of the sphere. Both shapes
// share the same vertex positions buffer. Hence, we only
// need to alter one of them:
using (ILScope.Enter()) {
// take the vertex positions from the Fill.Positions buffer
ILArray<float> pos = sphere.Fill.Positions.Storage;
// set all vertices with a Y coordinate larger than 0.3 to 0.3
pos[1, pos[1, ":"] > 0.3f] = 0.3f;
// write all values back to the buffer
sphere.Fill.Positions.Update(pos);
}
// add the "sphere" to the scene
scene.Camera.Add(sphere);
// add another light (for niceness only)
scene.Add(new ILPointLight() {
Position = new Vector3(-0, 1, -2)
});
// move the camera upwards
scene.Camera.Position = new Vector3(0,3,-10);
// display the scene
scene;

And this gives you:

Half a green sphere

It's a really amazing project. ILNumerics is GPL3 and also uses OpenTK for OpenGL bindings, and Mono.CSharp for C# compiling and evaluation. ILView is under the MIT/X11 license.

You can get it via NuGet with just "Install-Package ILNumerics." Check it out and tell your friends, scientists, and friends of Edward Tufte.


Sponsor: Thanks to Red Gate for sponsoring the feed this week! Check out a simpler way to deploy with Red Gate’s Deployment Manager. It can deploy your .NET apps, services, and databases in a single, repeatable process. Get your free Starter edition now.



© 2013 Scott Hanselman. All rights reserved.
     

Viewing all articles
Browse latest Browse all 1148

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>