Recently I’ve found one more nice method for vector fields visualization. What is a vector field and how to visualize it you can find in my previous posts:

Now let’s introduce new concept based on vectors’ angles. Angle can be calculated easily using function.

So let’s define:

or

where is input vector and is vector field function ie. to function.

Having that and are from the range we can scan vector field, calculate angles and draw points. It will be kind of heat map of all possible pairs of angles given vector field can generate.

Let’s see how the code looks like:

void setup() { size(800, 800); smooth(8); noStroke(); background(240); fill(10, 10); } void draw() { for (int i=0; i<10000; i++) { // draw 10000 points at once PVector v = new PVector(random(-1, 1), random(-1, 1)); // random input vector PVector fv = popcorn(v); // vector field //fv.sub(v); // subtract trick float alpha = v.heading(); float beta = fv.heading(); float x = map(alpha, -PI, PI, 50, width-50); float y = map(beta, -PI, PI, 50, height-50); rect(x, y, 1, 1); } } void keyPressed() { if (keyCode == 32) saveFrame("######.jpg"); } float popcorn_c = random(-0.8, 0.8); float popcorn_f = random(-0.8, 0.8); PVector popcorn(PVector p) { float x = p.x + popcorn_c * sin(tan(3.0 * p.y)); float y = p.y + popcorn_f * sin(tan(3.0 * p.x)); return new PVector(x, y); }

Result of the code on vector field called popcorn.

To get different variety let’s uncomment line 13 to use difference of vector field result and input.

Lovely, what about another vector field – waves?

float waves_b = random(-0.8, 0.8); float waves_e = random(-0.8, 0.8); float waves_c = random(-0.8, 0.8); float waves_f = random(-0.8, 0.8); PVector waves(PVector p) { float x = p.x + waves_b * sin(p.y * (1.0 / (waves_c * waves_c) )); float y = p.y + waves_e * sin(p.x * (1.0 / (waves_f * waves_f) )); return new PVector(x, y); }

I called result as surfaces since somtimes it looks like 3d surface folded in the space.

What can be done more here?

Add noise

Let’s add some distortion to our angles based on noise function. This will break too much symmetry in the image.

Replace draw() with new one:

void draw() { for (int i=0; i<50000; i++) { PVector v = new PVector(random(-1, 1), random(-1, 1)); PVector fv = waves(popcorn(v)); fv.sub(v); float alpha = v.heading(); float beta = fv.heading(); float nalpha = 0.5 * (noise(v.x,fv.y,alpha)-0.5); float nbeta = 0.5 * (noise(fv.x,v.y,beta)-0.5); float x = map(alpha+nalpha, -PI, PI, 50, width-50); float y = map(beta+nbeta, -PI, PI, 50, height-50); rect(x, y, 1, 1); } }

And results!

Yeah!

Two vector fields

You can of course use two vector fields and calculate from a vector field not from input vector.

Color and log-density rendering

Using different rendering method (log-density) and color taken from vector magnitude we can achive following results.

More can be seen on folds2d site

Enjoy!