This sketch is created with an older version of Processing,

and doesn't work on browsers anymore.

Click Record or

press 'R' to save 3 secs of animation

by
Jerome Herr

type letters or numbers in order to change the output of the sketch (you have to click into the window first)

eg. "mouse, keyboard"

eg. "visualization, fractal, mouse"

learn more about Creative Commons

won't be published on feeds but still accessible on your profile

won't be accessible by anyone

source code won't be available on the page, however it will still be accessible via browser console

## generateme

a) change 'd' to 15

b) in draw() instead of background() use filter(ERODE)

Effect will be like soap bubbles stretched on the frame.

## Jerome Herr

## Ale

I think you shouldn't compute distances to make this one, use squared distances or even, if you want a more efficient approach, manhattan distances (less precise but you don't need much precision to get this kind of effect).

: )

## Jerome Herr

## Jerome Herr

## Ale

float distance = loc.dist(other.loc);

To:

float distance = abs(loc.x - other.loc.x) + abs(loc.y - other.loc.y);

With regular distance computation I get ~14 fps and with manhattan distance I get ~22 fps.

And there's another tweak to get higher framerates, using integer coordinates and this code:

//Manhattan distance of integer values

int distance = fastAbs(loc.x - other.loc.x) + fastAbs(loc.y - other.loc.y);

//Hack to get absolute value of an integer without branching

int fastAbs(int n) { return n*(n>>255|1) }

With this one I get ~26 fps.

: )

## Jerome Herr

Just for the record:

dist() gets me a framerate of 23fps

abs() 30fps

fastAbs() 28fps

## Ale

:D

## Ale

## Jerome Herr

I used this code: "int distance = fastAbs(int(loc.x - other.loc.x)) + fastAbs(int(loc.y - other.loc.y));"

But I've run it again and now I've got 32 fps ... maybe something else was running in the background last time?

## Jerome Herr

## Ale

float ang = theta*dir+offset;

x = orgx + int(cos(ang)*radius);

y = orgy + int(sin(ang)*radius);

...

int distance = fastAbs(x - other.x) + fastAbs(y - other.y);

This way you cast two floats per particle at each frame in the update phase. You're playing with 2000 particles, so 4000 casting operations per frame.

If you do it the other way:

for (int i=0; i<ballCollection.size(); i++) {

...

int distance = fastAbs(int(loc.x - other.loc.x)) + fastAbs(int(loc.y - other.loc.y))

...

}

you're performing 2000*2000*2 cast operations, because you're iterating over all particles, that's it 8,000,000 casting operations per frame.

There's a difference! : ) The drawback is that the output would be different, and in some cases enough to make it an undesirable approach. That's your choice! : )

And the hack is and old hack, some obscure binary maths I don't understand fully. ; )

Check this, for example:

http://graphics.stanford.edu/~seander/bithacks.html

## Jerome Herr

## caden partida

http://www.openprocessing.org/sketch/388952

## janosch

## empwilli

So I thougth that's an easy one and ended researching for half an hour and learning lots of things:

So first of, this formular is highly implementation specific, starting in the language and going down to the processor. But maybe start with how negative integers work:

Negative integers are represented in computing mostly using something called twos complement [1]. Effectively, you take the numberspace of all numbers you can represent with 32 bits and divide them by two, interpreting the first half (2^31 numbers) as positive and the (2^31 numbers) other half as negative numbers. The sign of the number is determined by the leftmost bit, also called the most significant bit (MSB). Thus, if we want to know whether a number is negative or positive, we have to take a look at (number >> 31) & 1. If this is 1, the number is negative, otherwise it's positive.

But how does this play together with the above formular. First of: Shifting to the left / right by more than 31 bits means we shift out all bits from our integer (1 << 32 results in 2^32, which is not in the range 0 - 4294967296). So what does this mean? E.g. the C standard says this is undefined / implementation defined behavior. This is where the Intel processors does something strange [2]: It masks the shift operand to 5 the least significant five bits. This means our 255 becomes 31 and everything becomes more clear (in fact, at least on my machine with C, the algorithm also works with 31 bits). So our formular becomes: n * (n >> 31 | 1).

So put together what we have right now: We multiply our number by its MSB (= its sign bit) | 1. This should always be 1. Doesn't make any sense so far.

Here comes the second thing I've learned today. This is the case for C / C++ and I expect it ot be analoge to Java Script. The language specifications are open on what happens if you perform right shifts on negative values (remember: A negative value has a one as a MSB, if we shift right and fill with a 0, the negative value will become positive. if we fill with a 1, it stays negative (and devided by two, as expected, since this is how the twos complement is constructed)). The Intel processors distinguish here logic shifts (where always 0s will be filled in) and arithmetic shifts (where the number filled in depends on the sign of the number = the MSB)). As a matter of fact, right shifts are frequently implemented as arithmetic shifts.

This means: If our number is negative, after n >> 31 results in something like (I shortened int width to 8 bit for this example):

11111111 | 1 = 11111111

This is -1 by definition of the 2s complement.

If our number however is positive, we end up with:

00000000 | 1 = 00000001

This is +1 by definition of the 2s complement.

And tada, our formular is explained. However, this magic is highly implementation / spec dependent on: Language, compiler and processor and thus its most likly not portable. However, I find this by far more understandable than the magic inverse squareroot from Quake 3 [4].

tl;dr: We look for the sign bit, construct +/- 1 via that and multiply the result with that :).

References:

[1] https://en.wikipedia.org/wiki/Two%27s_complement

[2] http://x86.renejeschke.de/html/file_module_x86_id_285.html

[3] https://en.wikipedia.org/wiki/Arithmetic_shift

[4] https://en.wikipedia.org/wiki/Fast_inverse_square_root

## Guest User