Click here to Skip to main content
Click here to Skip to main content

Processing4Net

, 4 Jun 2012 CPOL
Rate this:
Please Sign up or sign in to vote.
Release the random artist inside you

Introduction

Processing4Net is a simple ASP.NET wrapper around processing.js, a port of the processing programming language to JavaScript made by John Resig back in 2008. Processing is a programming language created by Casey Reas and Benjamin Fry for the electronic arts and visual design communities.

Processing was initially developed to serve as a software sketchbook and to teach fundamentals of computer programming within a visual context. Since then Processing has evolved into a tool for generating finished professional work, and these days there are tens of thousands of artists, designers, researchers, students, and hobbyists who use Processing for learning, prototyping, and production.

I first came across the Processing project a couple of years ago, and found it to be an excellent tool for creating pleasing graphics that punched a lot of power.

The image above is from Exit, a half-hour immersive visualization of human migration data is an excellent example of how powerful the full Processing system can be: http://stewd.io/w/exit/

Processing is a programming language designed to make it easy to create images, animations and interactions. The idea behind Processing was to create something that allowed students to learn programming using a tool that provided instant gratification. Add a line of code and a circle shows up on the screen, add a few more lines and the circle follows the mouse, then change the color of the circle by adding just a few more lines of code.

This was called sketching with code, and a program written in Processing is often called a sketch.

While the Processing is based on Java, Processing.js allows Processing code to be run by any HTML5 compatible browser, including current versions of Firefox, Safari, Chrome, Opera, and Internet Explorer. Even if Processing.js has a few limitations compared to its sibling project, it’s still one of the most powerful HTML5 based environments for graphics programming.

Below is a screenshot of the classic asteroids game, by Benjamin Blundell, implemented using processing.js.

Processing4Net implementation

As of this writing, the current version of processing.js is 1.3.6 and hence Processing4Net is an implementation of an ASP.NET server control that allows us to easily embed processing files (*.pde) on our web pages.  The idea is that it would be kind of nice to write something as simple as:

<cc1:Processing ID="Processing1" runat="server" Sources="curves11.pde">
</cc1:Processing>

when we want to add processing.js functionality to our page – without having to think about the canvas or the JavaScript stuff.

It turns out that creating an ASP.NET server control for processing.js is pretty easy as long as all we want is to load a Processing file into the browser. First we create a c# class library called Processing4Net, and then we create our control called Processing.

[ToolboxData(@"<{0}:Processing runat=""server"" > </{0}:Processing>")]
public class Processing : Panel
{
}

I chose to derive Processing control from Panel, but don’t treat it as a fully functional panel yet, as child controls will not be handled correctly. The ToolboxData attribute defines the markup code that will be added to an ASP.NET page when you drop the control on the page’s design surface. Next we need a property for the Processing file:

[
 Bindable(true),
 DefaultValue("")
]
public String Sources
{
 get
  {
   return ToString(ViewState["data-processing-sources"]);
  }
 set
  {
   ViewState["data-processing-sources"] = value;
  }
}

Now we need to add processing-1.3.6.js to the root of the project, and set the ‘Build Action’ to ‘Embedded Resource’. The next thing to do is to open AssemblyInfo.cs, in the properties folder of the project, and add two attributes:

[assembly: WebResource("Processing4Net.processing-1.3.6.js", "text/javascript")]
[assembly: ScriptResource("Processing4Net.processing-1.3.6.js", "Processing4Net.Processing", "Processing4Net.Resource")]

This defines the JavaScript file as a Web Resource allowing the WebResource.axd HttpHandler to work in conjunction with the ClientScriptManager class to dynamically output the embedded resource, making it accessible from <script …> tags on the client.

Now we are ready to register the script with the ClientScriptManager of the page, which we perform during the pre-render stage of the control.

protected override void OnPreRender(EventArgs e)
{
 base.OnPreRender(e);
 string resourceName = "Processing4Net.processing-1.3.6.js";

 ClientScriptManager cs = this.Page.ClientScript;
 cs.RegisterClientScriptResource(typeof(Processing4Net.Processing), resourceName);
}

All that’s left is to add the canvas to the page:

protected override void RenderChildren(HtmlTextWriter writer)
{
 if (DesignMode == false)
 {
  string sources = Sources;
  sources = this.Page.ResolveClientUrl(sources);

  writer.Write("<canvas data-processing-sources=\"" + 
    sources + "\"></canvas>");
 }
 base.RenderChildren(writer);
}

That’s really all that’s required to implement the ASP.NET server control for processing.js and we are now ready to create beautiful, interactive, visualizations using the Processing programming language.

A very short introduction to processing.js

Included with the source code for the project is a small ASP.NET web application that allows you to create an infinite number of more or less pleasing visualizations. All the images at the top of this article were generated by this application, so feel free to release the random artist inside you.

If you take it for a spin you’ll notice that you can alter a visualization by dragging the mouse across its surface – and you’ll hopefully also notice that transitions are animated.

First we define the setup() function. This function is called once when the program is started. This is where we define initial environment properties such as screen size, background color, loading images, etc. before the draw() begins executing. There can only be one setup() function for each Processing program and it should not be called again after its initial execution.

void setup() 
{
 size(600,600);
 smooth();
 frameRate(24);
 initialize();
}

So the size of this visualization will be 600 by 600 pixels, smooth() tells processing to use anti-aliased drawing, and frameRate(24) specifies the number of frames to be displayed every second. If the processor is not fast enough to maintain the specified rate, it will not be achieved. Our initialize() function looks like:

void initialize() 
{
 if (frequency.random) 
 {
  fx = (int) random(frequency.x.min,frequency.x.max);
  fy = (int) random(frequency.y.min,frequency.y.max);
  phix = (int) random(frequency.phase_x.min,frequency.phase_x.max);
  phiy = (int) random(frequency.phase_y.min,frequency.phase_y.max);
 }
 else 
 {
  fx = (int) frequency.x.value;
  fy = (int) frequency.y.value;
  phix = (int) frequency.phase_x.value;
  phiy = (int) frequency.phase_y.value;
 }
	
 if (modulation.random)
 {
  mfx = (int) random(modulation.x.min,modulation.x.max);
  mfy = 0;
 }
 else 
 {
  mfx = (int) modulation.x.value;
  mfy = (int) modulation.y.value;
 }

 numberOfPoints = (int) random(200,1000);
 span = random(numberOfPoints*0.4,numberOfPoints*0.9);

 r = random(width/4,width/2);
 b = (int)random(60);
 factor = width*(random(0.25,0.375));
 points = new PVector[numberOfPoints];

 for (int p = 0; p <= numberOfPoints; p++) 
 {
  PVector l = calculateLissajousPoint(p);
  points[p] = new AnimatedPoint(l.x,l.y,l.z);
 }
    
 backgroundColor = color(0,0,0);
 lissajousColor =  color(random(100,255),random(100,255),random(100,255));

 noFill();
}

initialize() sets up global variables for our visualization that will later be used by our draw function:

void draw() 
{  
 // update animation
 for (int i=0; i<=numberOfPoints; i++)
 {
  points[i].animate();
 }
        
 background(backgroundColor);

 stroke(lissajousColor);
        
 strokeWeight(1);
 beginShape();
 for (int i=0; i<=numberOfPoints; i++)
 {
  float d = PVector.dist(points[i].position, new PVector(width/2.0,height/2.0));
  float a = pow(1/(d/r+1), 3);
  stroke(lissajousColor,a*255);
  vertex(points[i].position.x, points[i].position.y);
 }
 endShape();
            
 for (int i = 0; i < span; i++) 
 {
  int i1 = (int) i;
  int i2 = (int)((i1+span)%numberOfPoints);
  int c1 = (int) ((i1+b)%numberOfPoints);
  int c2 = (int) ((i2+b)%numberOfPoints);
  float d = PVector.dist(points[i1].position, points[i2].position);
  float a = pow(1/(d/r+1), 3);
  stroke(lissajousColor,a*255);
  strokeWeight((i/span)*2);
  bezier(points[i1].position.x, points[i1].position.y,points[c1].position.x, 
    points[c1].position.y, points[i2].position.x, points[i2].position.y, 
    points[c2].position.x, points[c2].position.y);
 }
}

This Processing script goes a bit beyond the usual hello world program, but then the visualization is perhaps a bit more interesting.

History

  • 4th of June 2012 – Initial posting.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Espen Harlinn
Architect Powel AS
Norway Norway
Chief Architect - Powel AS.
 
Specializing in integrated operations and high performance computing solutions.
 
I’ve been fooling around with computers since the early eighties, I’ve even done work on CP/M and MP/M.
 
Wrote my first “real” program on a BBC micro model B based on a series in a magazine at that time. It was fun and I got hooked on this thing called programming ...
 
A few Highlights:
  • High performance application server development
  • Model Driven Architecture and Code generators
  • Real-Time Distributed Solutions
  • C, C++, C#, Java, TSQL, PL/SQL, Delphi, ActionScript, Perl, Rexx
  • Microsoft SQL Server, Oracle RDBMS, IBM DB2, PostGreSQL
  • AMQP, Apache qpid, RabbitMQ, Microsoft Message Queuing, IBM WebSphereMQ, Oracle TuxidoMQ
  • Oracle WebLogic, IBM WebSphere
  • Corba, COM, DCE, WCF
  • AspenTech InfoPlus.21(IP21), OsiSoft PI
 
More information about what I do for a living can be found at: harlinn.com or LinkedIn
 
You can contact me at espen.harlinn@powel.no

Comments and Discussions

 
GeneralMy vote of 5 PinprofessionalPrasad Khandekar14-Sep-13 7:31 
GeneralRe: My vote of 5 PinmvpEspen Harlinn14-Sep-13 11:22 
QuestionHow big is Thor Heyerdahl in Norway? PinmemberFatCatProgrammer22-Aug-13 7:56 
AnswerRe: How big is Thor Heyerdahl in Norway? PinmvpEspen Harlinn22-Aug-13 9:55 
GeneralRe: How big is Thor Heyerdahl in Norway? PinmemberFatCatProgrammer27-Aug-13 18:38 
GeneralMy vote of 5 PinmemberPaul Conrad12-Jun-12 18:09 
GeneralRe: My vote of 5 PinmvpEspen Harlinn12-Jun-12 19:53 
QuestionMy vote of 5 PinmemberFilip D'haene6-Jun-12 3:25 
AnswerRe: My vote of 5 PinmvpEspen Harlinn6-Jun-12 9:46 
QuestionNicely done PinmemberMike Hankey5-Jun-12 6:10 
AnswerRe: Nicely done PinmvpEspen Harlinn5-Jun-12 6:23 
GeneralMy vote of 5 PinmvpMarcelo Ricardo de Oliveira4-Jun-12 4:41 
GeneralRe: My vote of 5 PinmvpEspen Harlinn4-Jun-12 4:50 
QuestionNice PinmemberManas Bhardwaj4-Jun-12 2:04 
AnswerRe: Nice PinmvpEspen Harlinn4-Jun-12 2:38 
QuestionWinforms support Pinmemberwvd_vegt3-Jun-12 23:41 
AnswerRe: Winforms support PinmvpEspen Harlinn4-Jun-12 0:07 
GeneralMy vote of 5 PinmemberSergio Andrés Gutiérrez Rojas3-Jun-12 19:21 
GeneralRe: My vote of 5 PinmvpEspen Harlinn3-Jun-12 22:59 
GeneralMy vote of 5 PinmemberJF20153-Jun-12 18:55 
GeneralRe: My vote of 5 PinmvpEspen Harlinn3-Jun-12 22:58 
GeneralMy vote of 5 PinmvpMika Wendelius3-Jun-12 18:41 
GeneralRe: My vote of 5 PinmvpEspen Harlinn3-Jun-12 22:58 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Terms of Use | Mobile
Web03 | 2.8.1411023.1 | Last Updated 5 Jun 2012
Article Copyright 2012 by Espen Harlinn
Everything else Copyright © CodeProject, 1999-2014
Layout: fixed | fluid