How to visualize forces of a particle system?

I’ve got a particle system with particles that attract and repel each other based on their distance. What i need now is a way to make the forces of those particles visible. Something like a magnetic field visualization. All particles have their own force variable, which i tried to get the magnitude from for each pixel for each particle, but turns out, the amount is equal for each pixel (who would have thought :sweat_smile:). And finding the closest one to adopt its force doesn’t feel like a good idea… Does anyone know how i could approach this? I really have no clue at all… All i got till now is this :

void visualize() {
  float vMin = 0f;
  float vMax = 0f;
  for (int x = 0; x < width; x++) {
    for (int y = 0; y < height; y++) {
      float stroke = 0;
      for (int p = 0; p < part.length; p++) {
        stroke += part[p].force.mag()/dist(part[p].pos.x, part[p].pos.y, x, y);
      }
      if (vMin > stroke) vMin = stroke;
      if (vMax < stroke) vMax = stroke;
      stroke(map(stroke*5, visualMin, visualMax > 0 ? visualMax : 1, 0, 255));
      point(x, y);
    }
  }
  visualMin = vMin;
  visualMax = vMax;
}

And even though it is pretty nice, it is not very stable, because my particles have to reset their forces at the end of every movement. Though the major problem with the visualization might be the resetting of the vMin/vMax floats each frame, but that can’t be helped, since otherwise it’s pretty obsolete.

Now, i can’t change anything about the particle only having a force PVector to get that gets deleted each frame. Also, there is a pos PVector for the position of the particle. But thats basically all there is to it.

Would it be possible to get the full code?

I’m a bit confused right now on what the end result should be. Do you want to show each individual particles force, or some sort of combined force?

What i‘m trying to get is an image that basically looks like this :

Which would be perfect, But since i have no idea at all on how to do it, so i tried to settle with something like this :

which seems simpler. Though i can‘t seem to get it to work the right way… and since i can only access each particles force and position i don‘t Know what the best (Or any) approach Would be… if the forces were just based on distance i could just get the distance to each particle, But since they aren’t, i don‘t know… and it seems too difficult to do the Same calculation i did for the forces for each pixel for each particle and add them together. (With too difficult i mean that it Would cause a massive performance drop… if it Even works)

So the layers of colors represent the effect of the force on that area, and the black dots are the particles?

Well, that was just an example Image i found online, since what i Would like to achive… Well, i don‘t have an example of it, since i didn‘t get it done yet :sweat_smile: But yes, although the dots don‘t necessarily Need to be drawn extra, and i think the layers in the example just seem like layers, But are actually just a colored reppresentation of the forces, just with rounded values (which causes such an effect if i‘m not mistaken).

But in general yes. Basically the more force there is where a specific pixel is, the brigther it’s Color (Or redder in this case), while if the force is low it gets darker/greener.

The Problem is that i don‘t know how to get the force for each pixel relative to the others, except calculating the Same math the particles do, for each particle, for each loop… and since i have 200 particles and size 600,400 that Would be equivalent to having 600* 400* 200 particles, or 48mil in a loop…

I think that would be quite hard to visualize because if there were “real” particles attracting or repelling there would be a field around them you could visualize, but with this the force is just a vector, which makes it quite hard to visualize. (Unless just representing it in a line)

Hmm Yeah, seems like i‘ll have to do the whole Math for each pixel… Or maybe i‘ll try to get the closest particle to each pixel and just calculate it‘s force, relative to the Position of the pixel relative to the particle… That way i at least don‘t have to do the whole Math and could save some Time per pxl.

Edit: Ok, so i just did the math for all particles per pixel and as expected it’s 1.8 frames per second… but at least it shows something and it’s more or less what i hoped to see… though some performance increase would be much appreciated :sweat_smile:

Instead of rendering thousands of particles every frame, you should be able to optimize it by accessing the pixels[] array directly.

Here’s an example of that:

loadPixels();
for (int x = 0; x < width; x++) {
  for (int y = 0; y < height; y++) {
    // Calculate color here
    pixels[x + y * width] = color(stroke);
  }
}
updatePixels();
1 Like

I am thinking about this :

For each particle, since you have its coordinates in the canvas, you can check the pixels around it (in a circle around its position) and change the pixel color by an amount of value (which correspond to the force of the vector).

Is the code too big? Otherwise could you provide it ?

Although that Would save some time, that Would also cause blank Spots where there is no particle nearby, But i‘d Need the whole canvas to be visualized… Well, i don‘t Need it, But it looks better and Makes more sense to Look at :sweat_smile:

Actually, it‘s just 200 particles, But i have to do the Math in each particle for each pixel, which Makes (i made the size a lot smaller) 200200200, which is still enough to get only 1.8 Frames… But i‘ll use the pixels[] method :sweat_smile: should at least save some Time.

You could also save the frames at low fps and make a video with the correct fps afterwards, as an alternative:

Tutorial: How to render Processing sketch as a movie - YouTube

Thanks, i already thought about that, but the problem is that i wanted to move one of the particle on the screen manually, just to see it’s immidiate changes :sweat_smile:
Though i could just make a PVector array that tracks the mouse movements beforehand and then applies that inside the sketch while it’s running (at a slower pace) that would also mean that i don’t have the ability to react to changes… Anyway, i can also look at the screen and move the mouse while it’s going at 2 frames a second(makes accurate movements easier, but takes long) to get that, but it would just feel better with a stable (or at least bearable) frameRate.

Edit: Just changed it to pixels[] and now it goes at around 10-15 frames per second. Awesome :blush:

I think (?) that the PixelFlow library also has some tools for these kinds of problems, and they are tuned to be quite fast.

1 Like

Thanks, but i figured, i’ll not be able to visualize it in a more efficient way the way the code works at the moment (probably some optimization possible) because the particles only interact with each other, so i have in any way to calculate for each particle… Though i could get the code to run faster if i were to optimize the math and interactions between particles, i think that’s just overkill, since 10 frames a second is acceptable to make “realtime” changes and react to things…

Also, i took a look at PixelFlow, but i don’t see anything that really could solve the problem, although there are ways to visualize, they are made for fields, not calculations for each field for the visualization (not sure if i said that right :sweat_smile: goes down to them having vectors in each pixel (or close) while i have particles that don’t interact with such a vector field that that could be displayed but have to display for each pixel individually).

Another thing i could do, would probably be to apply my math to the Fluid simulations of PixelFlow (obviously change them a bit, but since fluid behaviour is close to magnetic field behaviour if only looked at the visualization) and hope that it still does what it should.

(Not related, just talking to myself :sweat_smile:)
Also, thanks for mentioning PixelFlow. Wanted to implement that (or i think it was something like that) in an UE4 project some year ago, but was totally unable to get how that could be done (had virtually no knowledge of code, only some BPS from UE4). But now i’ll take a look and try it out in Processing, and hope it’s gonna be awesome :sweat_smile:. Oh… and i might also try to make an AI with fluid dynamics. Would be awesome if it works… unlike my normal one…
(Turns out, the simulator for UE4 was not even close to being called PixelFlow, but oh well :sweat_smile:)

If you want to make it even more efficient, you can run it through a profiler and see where it slows down. You can also try switching your renderer to FX2D for faster rendering

I quickly tried to change to FX2D, but the change that frameRate displayed after it got stable was pretty much the same as P2D (3.14 to 3.17 for P2D and FX2D respectively, also increased the size of the paricle array by double, so thats why its slower, just to see a clear difference). As for the profiler part… i don’t know how that works. I can vaguely imagine what it does, but thats all, but i’ll take a look at it. Thanks :blush:

You should definitely check out how to use a profiler - It’s one of the best tools I use for testing. I think the best profiler for Processing is VisualVM using the sampling tab.

You may also get a performance boost if you spatial partitioning so you don’t have to use as many cycles, but it might take a while to set up depending on how complex you code is.

Good luck!

1 Like

Thanks, I’ll take a closer look at it, and try out VisualVM :blush:.

Hi Lexyth,

How about computing the force only on some points on your canvas and then linearly interpolate between them ? Maybe it won’t be as precise as what you are doing but it could be sufficient for visualisation ?

1 Like