Re Posting this article from hanselman blog. he is my Google+ friend
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 generics 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. ;)
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); |
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.
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:
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.
No comments:
Post a Comment