RobinSchmidt / RS-MET

Codebase for RS-MET products (Robin Schmidt's Music Engineering Tools)
Other
56 stars 6 forks source link

working on a particle system... #90

Closed RobinSchmidt closed 2 years ago

RobinSchmidt commented 7 years ago

just for info

i just started to get serious about implementing a particle system. each particle has a mass and a charge and a current position and velocity. at each iteration, the forces on each particle due to all the other particles are calculated, then the velocity of each particle is updated according to F = m*a -> v += F/m and then the position is updated as p += v.

i dug out all the formulas for gravitational, electric (and also magnetic) forces and i think i got them right - however, these formulas are problematic in a numeric simulation, because the forces depend on the distance r between any pair of particles via 1/r^2. when the two particles coincide (occupy the same position), i get an infinite force. and if they almost coincide (i.e. get very close) at some instant, i may get a very large, yet finite, force which gives the particles an insane speed which makes them drift apart forever. they get - kind of - thrown away due to the extreme velocity bump.

a more realistic simulation would perhaps have to model the particles not as point masses but as balls with some radius and detect collisions and handle them by bouncing off again. but i think, that's overkill for what i'm trying to achieve (which is to create a musically useful chaotic system). i'm currently looking into tweaking the force equations in a way to avoid this problem and also to make them more flexible. the final system may the not be true to physics anymore, but maybe it will do something musically useful. i'll try to parametrize the formulas such that with certain parameter settings, the original, physically correct formulas are recovered and with other settings, we get robust behavior

RobinSchmidt commented 7 years ago

i'm currently experimenting with some very simple configurations: just two particles, initially located at (-1,0,0) and (+1,0,0) with zero velocities and interacting only via gravitation (it's possible to tweak the overall effects of gravity, electric and magnetic force - we can adjust the natural constants for these forces). with the physically correct force law, they initially approach each other but then they come very close and bump each other away due to the force singularity and the numerical inability to deal with it appropriately. ...but i found some tweaks to the force law, where i got some nice periodic oscillations - a good starting point for musical explorations

elanhickler commented 7 years ago

did you add soemthing to chainer so I can check it out?

I don't think you need physical particles that bounce off each other, I would stick to the goal of getting non-colliding particles to work... my first thought would be limiting the speed. I think bouncing particles would cause too much noise, see brownian motion: https://en.wikipedia.org/wiki/Brownian_motion while non-colliding particles will have the benefit of their paths NOT being interrupted thereby allowing for more steady patterns/oscillations/tones.

~not useful for music.~

Maybe you can have a maximum distance at which your numbers are recalculated, so you stop calculating new speed or new gravity values when the distance is too close, or soft clip your values or something.

Things can still end up being natural without infinite potential. Limit the potential.

RobinSchmidt commented 7 years ago

hmm...interesting idea, with limiting distance. reminds me of the idea of the circle (soft) clipper. just that here i would have to have a 3D version of that, i.e. a spherical soft clipper. however, as said, with some tweaks to the force law, i can effectively avoid the singularities and also add another degree of freedom. i'm trying distance dependencies of the form like 1 / (c+d)^p, 1 / (c + d^p), etc. here, d is the distance, c is a positive constant and p is some exponent. for c = 0, p = 2, we recover 1 / d^2, the physically correct inverse-square dependency. the added constant c avoids divisions by zero. with the exponent, we can adjust the shape of the periodic waveform. with p = -1, i think, it should become sinusoidal, since then the force-distance dependency is proportional to the distance itself, resembling a force that follows Hooke's law. anyway, interesting stuff to explore. i don't have a chainer module for that yet, just doing some plots in my experiments project

RobinSchmidt commented 7 years ago

of course, all that goes for the simple case of two particles. the real fun will start with 3 or more particles, when things become chaotic. but at the moment, studying the behavior with two particles is essential to figure out if i got all the physics right, i.e. if the particles behave as physics predicts

RobinSchmidt commented 7 years ago

my first thought would be limiting the speed

with my 1 / (c + d^p) force law, i'm effectively (smoothly) limiting the force to be equal to 1/c at maximum (when d=0). that, in turn, limits the acceleration (which is proportional to the force)

RobinSchmidt commented 7 years ago

i just had an idea: what about not just (soft) clipping the position on an imaginary enclosing sphere but reflect - like i did in raybouncer? effectively, that would be the 3D version of raybouncer, just with multiple rays/particles that also interact with each other (of course, you could also just use one particle, when you have a reflecting shell - then it would be it - well, ok, i would have to figure out, how to reflect at an arbitrary ellipsoid rather than a sphere (which is much easier))

i'm a bit worried that just clipping would thwart things like energy conservation, which may (or may not) be a problem. ...it wouldn't surprise me if we can even relate the total energy in the system (kinetic plus potential) to some kind of pseudo-frequency / perceived pitch.

another idea: invent a fictional force that drags the particles towards the origin. maybe something like a force that always points toward the origin whose strength is proportional to (some power of) the distance to the origin. it would be like having the particles attached to the origin with springs. that may be also an effective way of preventing particles from being thrown away (which, in itself, is actually a totally physically plausible thing to happen - just think of hyperbolic and parabolic trajectories)

elanhickler commented 7 years ago

yes, you need non-linearities, that's what sounds good.

what about a little bit of repulsion based on distance of particles? You can crossfade between repulsion and attraction, where repulsion only takes affect at the very nearest distances to avoid infinite closeness. Oh I guess that would be soft-clipping the distance.

RobinSchmidt commented 7 years ago

you can already have repulsion by giving the particles the same charge and ramping up the electrical force constant. hmm...however, i think, gravitation and electrical force will combine to a combined force that is equivalent to a single force for different values of mass (or charge)...unless the force-distance law is different for the two forces. maybe i should consider to use different force-distance laws for the different forces

RobinSchmidt commented 7 years ago

repulsion only takes affect at the very nearest distances to avoid infinite closeness

i think, that could be done with a repulsive force that falls off more quickly with distance than the attraction of some other force - for example with a higher power of the distance - or even exponentially. i think (i have to look it up to be sure), one of the (attractive) nuclear forces falls off exponentially (or maybe with some high power). that holds nuclei together - which would otherwise be thrown apart by the electric repulsion of the protons. in the unstable nuclei (the really big ones with a lot of protons (which means a lot of positive charge) like uranium or plutonium), the outermost protons have a delicate balance between electric repulsion and nuclear attraction...or something

RobinSchmidt commented 7 years ago

btw. gravity plays no role there. the gravitional attraction between two protons is orders of magnitude smaller than the electric repulsion (even more so for electrons which have much less mass). that's what physicists mean when they say "gravitation is a weak force"

RobinSchmidt commented 7 years ago

...but in my system, i plan to have all the forces the same order of magnitude - that makes it more interesting. otherwise, i could just as well leave the other forces out entirely

elanhickler commented 7 years ago

i just solved a major problem with my envelope generator, essentially using simple dithering and ~anti-aliasing~ linear interpolation techniques. Noise is awesome. You can "make a random decision" when the numbers would otherwise be too high or low or close to zero or whatever. Not sure if this applies for your particles, but it definitely applies to RayBouncer, or even any time you have to reflect values such as bouncing off a wall. What happens when you bounce twice within one sample period? Well, you either have to oversample or just... clip the value or just reflect the value... or you could just choose a random position. This solves exploding numbers or stuck/inf numbers, or stuck oscillations.

My ADSR in looping mode at audio rate is far more stable by dithering numbers with noise.

RobinSchmidt commented 7 years ago

What happens when you bounce twice within one sample period? Well, you either have to oversample or just... clip the value or just reflect the value... or you could just choose a random position.

if you have to reflect twice, then you just do reflect twice. where's the problem? i'm not really a big fan of making random decisions. and if i do, then only with a well defined random-number generator with known seed, algorithm, etc. for me, exact reproducibility of results is very important

elanhickler commented 7 years ago

so you want to do this?:

while (reflectingIsNotFinished)
    process():

and if you get a near infinite number you have to process 100 reflections and you get a hang.

elanhickler commented 7 years ago

Also, the randomness is supposed to do this:

  1. You don't need to process multiple reflections
  2. You still get a relatively correct output.
  3. You get noise instead of foldback reflections of harmonics / aliasing. (noise increases as you reach nyquist)
  4. No worries about infinities, exploding numbers, numbers that become too high or cause stuck oscillations.
  5. Adding additional oversampling has the side effect of reducing noise and increasing accuracy rather than having infinite accuracy and all the problems associated.
elanhickler commented 7 years ago

Oh also, instead of doing noise you could also implement a "guess" function that may not be completely random, but more efficient than processing multiple reflections completely, the point is that infinite accuracy and aliasing is not musically pleasing. It's ok if you're not convinced, I'm just giving you something to consider.

RobinSchmidt commented 7 years ago

if you get a near infinite number you have to process 100 reflections and you get a hang.

how is such a situation supposed to occur? with reasonable settings, there should should actually not even be two reflections per sample (or, well, maybe on rare occasions). ...i had such situations (and yes, indeed, hangs) with raybouncer only when the particle was more or less exactly on the boundary - just a tiny little bit outside within numerical roundoff error...and the new, reflected location was still outside, also due to roundoff error.

You get noise instead of foldback reflections of harmonics / aliasing.

ok, that's a good point. noise is certainly less objectionable than aliasing.

elanhickler commented 7 years ago

My ADSR is capable of multiple reflections per sample because I allow for extremely small timings so that you can have a near-0-length-sample-attack and decay in loop mode. I don't want to process multiple reflections so I can just choose a new random value. It works well. I am using a random number, but I want to experiment with just using fmod, basically choosing a reflected number between 0 to 1, it should be pretty much random. I also want to experiment with random numbers where the spectrum is more violet, less low frequencies than white noise. It could be better.

RobinSchmidt commented 7 years ago

i spent some time thinking about my force singularity problem, reading physics books etc. and i think, i have now found a satisfactory solution: indeed give all the particles a nonzero size/radius, but don't detect collisions and bounce off, but simply let the particles fall through each other. what happens when the spheres overlap is that the force gets reduced. i think, this goes along (roughly) with a mental model where each particle is a spherically symmetric cloud of matter. the force becomes zero, when the clouds are concentric. it can't have any other value than zero in this case, because the force is a vector and you would have no way whatsoever to sensibly calculate a direction, even if you would assume a nonzero force strength (magnitude). it is also what would happen, if you could fall into earth (because there's a hole from one side to the other or the planet is made of gas). the gravitational force at the center of earth is zero - all of earth's matter is distributed into all directions equally around you, pulling in all directions equally, so the net force is zero.

RobinSchmidt commented 7 years ago

sooo...i guess a good force law would be something like: f = G m1 m2 * (v2-v1) / (size1 + size2 + d^p) or something with max(size1+size2, d^p) or max(size1, size2, d^p) in the denominator

...ok, will look into jitter stuff now

RobinSchmidt commented 7 years ago

look at figure 5.8 in section 5.7 here: http://www.feynmanlectures.caltech.edu/II_05.html that's the electric field (which is proportional to the force) of a charged ball with a uniform charge density. i think, the functions i proposed above are qualitatively the same (first raise to some maximum, then fall off like 1/d^p) but are more smooth, i.e. don't feature this kink - which might be even nicer. maybe it can be cast into some kind of nonuniform charge density/distribution in the mental gasball model - but actually, that doesn't really matter. all that matters is to have a well behaved force-distance-function with some physical plausibility

RobinSchmidt commented 7 years ago

my force-distance laws (for size1 = size2 = 0.01) now look like this: image the cyan curve approaches the 1/d^2 rule asymptotically, the red 1/d^3, purple 1/d, other red 1/d^0=1, green 1/d^-1 = d (linearly ascending - like a hooke spring), etc

RobinSchmidt commented 7 years ago

the hooke-spring law should give sinusoidal motion for two particles. such things are nice for sanity checks of the implementation

elanhickler commented 7 years ago

ok, nice, yes, I like the idea of particles falling through each other, that's what I was trying to suggest earlier with non-colliding particles.

RobinSchmidt commented 7 years ago

the plot above is with the sum - when i use the max-function i get plots very similar to what is depicted in the feynman lectures: image

...well, i think, it should exactly that curve

RobinSchmidt commented 7 years ago

my cyan curve should be like this one: image

RobinSchmidt commented 7 years ago

yes! problem solved! :-)

elanhickler commented 7 years ago

interesting, it almost looks like a collision.

RobinSchmidt commented 7 years ago

no - in a collision, you would immediately see a strong repelling force be added - when the distance goes below some threshold.

RobinSchmidt commented 7 years ago

here, the force gets lower when the objects penetrate each other. it just starts going down back to zero, when the threshold is crossed - instead of having a rectangular pulse added. ...well actually it's not a pulse - but anyway, you'g get an immediate bump/discontinuity

RobinSchmidt commented 7 years ago

...assuming the force above is repelling, like it would be for two equal charges. if we assume the force to be attractive (like gravitation or opposite charges), you would see it steeply going into the negative, when the collision threshold is crossed

elanhickler commented 7 years ago

i kinda was thinking along those lines, the two particles trade energy

RobinSchmidt commented 7 years ago

i just received my copy of this yesterday:

https://www.amazon.com/Special-Relativity-Classical-Field-Theory/dp/0465093345

and couldn't put it away for like 8 or 9 hours and now i'm about 1/3 through (reading from 11 pm to 8 am - fuck, i should sleep at those times). it has some stuff about relativistic particle motion. maybe i can soon incorporate relativistically correct equations of motion. haha...but probably that will not be very musically useful. i guess, in the end, it will boil down to soft-clipping/saturating the velocity (at the lightspeed). ...or maybe having a saturating accumulation for the vleocity, like for the pixel-brightness in phase-scope/prettyscope (the higher the velocity, the smaller the change in velocity due to the same force due to relativistic mass increase - or something)

the brighter the pixels already are, the smaller the "embrightening" by the new hit of the electron beam ...the higher the velocity already is, the smaller the acceleration by a new application of the force

RobinSchmidt commented 7 years ago

...because the mass is higher at high velocities. the equation F = ma is actually F = dp / dt - the force is derivative of the momentum with respect to time. the momentum p classically is mass times velocity: p = mv. and if the mass is constant, this boils down to F = d(mv) / dt = m dv/dt = m*a. the mass can be dragged out of the derivative, because it's constant. but at high velocities, that's not true anymore. the mass will depend (increase with) the velocity, too

i have no idea, why the board software uses so much italic fonts above - must be a bug.

aahh ...maybe because of the *? everything in between is emphasized?

RobinSchmidt commented 7 years ago

...sorry - i'm drunken

RobinSchmidt commented 7 years ago

F = dp / dt is still true, in relativistic mechanics, though

RobinSchmidt commented 7 years ago

i guess, in the end, it will boil down to soft-clipping/saturating the velocity (at the lightspeed).

..well, not only. that's one aspect. another one is, that the force from the other particles do not apply instantaneously. the force on "me" will depend on where some other distant particle was some time before

RobinSchmidt commented 7 years ago

if the sun would just disappear, earth would stay another 8 minutes in orbit before it would take off tangentially - because the sun is 8 lightminutes away from earth

RobinSchmidt commented 7 years ago

...that would mean delaylines for each particle - OVERKILL!