Particle Simulator in Python (Rigid Bodies, Soft Bodies, Fluid and More!)
HTML-код
- Опубликовано: 21 авг 2024
- For the past few weeks, I’ve been working on a particle simulator, in which particles follow some simple rules that are similar to the way molecules interact. From these rules, more complex behavior can emerge. Springs, fluid, soft-bodies, breakable buildings and tearable cloths... you can simulate all of this and more using the simulator! It also has a handy GUI that allows you to easily edit simulations and play with them in real-time. So in this video, I’ll show you these simulations, how I made the simulator and how you can use the GUI to experiment with it yourself!
You can download the code from the GitHub-repository:
github.com/PyE...
You can now also download it as a .exe file, though it is not recommended:
github.com/PyE...
Music:
Candlepower by Chris Zabriskie is licensed under a Creative Commons Attribution-license (creativecommon...)
Source: chriszabriskie....
Artist: chriszabriskie....
#python #physicssimulation
When I was rendering the video, I noticed that the 'links' weren't visible. However, when you would run the simulator on your PC, the links should show up as a light grey color. Some other things also looked lighter in the video than they were in reality. I hope you'll enjoy the video nonetheless =).
How do you optimize it
The optimization in this project was actually quite simple. The 'canvas' sort of gets divided into multiple grid cells which makes it so you only have to check for collisions in that grid cell. However, this doesn't work when the attraction or repulsion radius are too big or just "infitinitely large" (i.e. set to -1). In that case, all distances will have to be calculated and no optimization is possible.
There are better optimization strategies out there (like a quadtree), but this project just started as an experiment to see how far this simple grid optimization would get me.
900th Sub, #Idea Chemistry Simulation, Periodic table of elements floating in a void until they start to form suns, Stars, & Planets.
@@bonkaiblue7906 That's a cool idea! Though it's probably also insanely complex. I guess there are more basic versions of this principle, like in The Powder Toy. However, actually simulating all elements correctly would require a lot of computing power and complex equations and principles.
So far, I haven't had the time for big projects in a while. I'll keep your suggestion in mind, though. Maybe one day I'll try a simplified version of chemistry simulations :).
When the tutorial is TOO Good:
No seriously i mean you deserve more, first time here and subed, liked and also commented.
Thank you so much! I really appreciate comments like these 🙏
Man, that simulator is awesome! Congratulations!
Thanks!
So underrated dude...
Epic
This was such a wonderful video to watch. Thank you for sharing your amazing work!
This is insanely good. Thanks for sharing
Beautiful video 👏
This Channel is such a gem. Love your videos. Will try to implement these when i get some free time . Kudos to your content . Keep doing .lots of love❣❣
Amazing work mate!
This is so amazing and helpful... Well done 👌
This inspired me to try doing this myself !
Thank u !
Hey! What an amazing and inspiring video!
May I ask you something? What did you use as the visual interface for your simulation? I'm used to program in JavaScript so I always go for the browser, but when it comes to Python what tools do I have to display whatever I want?
Thank you in advance :)
In this project, I used a combination of tkinter and OpenCV. In the sense that I used tkinter for the GUI and OpenCV as a drawing canvas for the actual particles and links (which I then display using canvas.create_image, you can convert it to a tkinter-image using some PIL functions: www.tutorialspoint.com/read-an-image-with-opencv-and-display-it-with-tkinter for an example). Even though it works fine for a project like this, I do not recommend at all doing this for bigger projects, as tkinter is not that good of an option. I think libraries like PyGame or OpenGL would be better options instead. The reason why I haven't used them yet is that I never took the time to learn them. I suppose it's also time for me to improve my knowledge about these libraries then ;).
Amazing dude, i am a beginner and i wish i could create something like this in the near future 😊✌
Thanks! I'm sure you'll be able to make things like this in the near future. Just start with the basics and make your way up to some bigger projects.
Great video! I got inspired to try and make something similar myself, but for some reasons my particle clusters end up spinning when they get too large, weird lol
Thanks! It's also really cool that you made your own version of this. Maybe the uncontrollable spinning could be solved using a dampening factor? I'd suggest using something like air resistance, but you may have already implemented this, in which case you could try increasing the resistance/dampening.
Great video! Thank you!
Very informative video
you definitely stand out...amazing work.....did u do it during lock down?
Thank you so much! I honestly don't remember if there was a lockdown when I was making this. It could have been a period of part-time online lessons, which gave me more time to work on these sorts of projects. But honestly, the situation changed so often at that time that I can't fully recall which projects I did during a lockdown.
However, I now find it difficult to find the time and motivation for these projects. I'm not sure if there'll be any videos coming soon. I have plenty of ideas, but it would be too stressful to start a project with this amount of homework. It's honestly comments like these that do give me motivation to work on another project. I'm just not sure if that's what I'd like to invest my time in right now. Though, thanks again for the lovely comment :).
Great work!
Nice work ! Many Thanks.
Hey I'm trying to create the fluid sim shown in the video but I'm not sure about the formula for the force between individual particles can you tell me?
First of all, it's really cool that you're trying out the simulator! At least I'm glad to know that it still seems to function for most people :).
To answer your question: you should just be able to load in the file "fluid.sim" from the folder "example_simulations". In the case of that simulation, I used a repulsion-radius of 50 and a strength of 1 (with the mass of the particles also being equal to 1). The attraction-radius is -1 and the strength being 0. Hope this helps.
@@PyExplained thanks that helps! 😊...I was trying understand how fluid sim works and this video helped a lot keep up the good work
Oh, I'm so sorry. I just realized that you're probably talking about making your own simulator. To do that, you can take a look at the code in the Particle class. Especially, the 'calc_attraction_force' function.
This part of the code is probably what you're asking for:
if distance < repel_r:
magnitude = -repel * rest_distance / 10
Again, I wrote this code a long time ago, so it often isn't clear to me either what I wrote back then. The division by 10 is also probably just a constant that I found worked for the simulation, but this might be different for your simulation.
@@PyExplained 🤔 ohh thanks I understood this time... I am trying to do this in blender a 3d software and was trying different formula but didn't work... I'll try using your method😅
Very cool thanks for sharing
Is that tkinter? Have you used it just for GUI or for the whole simulation?
Moreover, I would like to know how much time did it took to complete?
Just wanted to know because I was falling for such things and was hoping to learn C++ before starting. I already know python, so, I would just have to see Physics if I can do it in tkinter and Python.
I did indeed use Tkinter for the GUI and graphics. I also used OpenCV and Numpy to draw the particles and links to an image and used PIL to draw it in the Tkinter frame. You asked if I used Tkinter for the whole simulation, but I'm not sure if you mean just the graphics or both the graphics and the physics. Of course, you can't use Tkinter to do the simulation: that part was something I wrote myself. So, I just used it for the graphics and GUI.
About how long it took me to make: I think it took about a month or a month and a half to complete, but I'm not entirely sure when exactly I started working on this project.
If you want to make these kinds of physics simulations, you could use Tkinter, but it isn't the best graphics library out there. Using Python for the simulations is neither the best option because of how slow it is (relative to other languages). I am now learning how to use Java instead, so my future projects will hopefully run a little faster, but I still think Python is suitable for this kind of project, just not the fastest.
I hope that answers your questions.
@@PyExplained Thanks for responding! I was actually trying to make simple collision detection in tkinter canvas using threads. Then, the pausing function wasn't working most of the times (program simply hung) but sometimes it worked! I checked the design, rewrote etc. Finally I discovered that tkinter is thread unsafe and after that, I decided not to use tkinter for such work. Its good for simple GUI but not for performant tasks.
Thats why I asked you. Just wanted to know whether is it really possible to do all that work you did in tkinter! And I got my answer from your response - NO! 🙃😁
this is awesome
very impressive
Very interesting ...It would be good also if you teach us the code behind .
I'm glad you enjoyed it 🙂! If you want to look at the code, you can do so with the link in the description. I know the code isn't too self-explanatory. Though, I wasn't planning on making another explanation video. If you have questions about certain things, you can always leave a comment. I'll try to respond as quickly as possible.
So dope!
Thanks!
Fantastic sw
playing with clothes example and the code snip found in ReadMe got this; "Warning (from warnings module):
File "", line 5
FutureWarning: In the future `np.object` will be defined as the corresponding NumPy scalar."
then this .. main thread it's not in main loop ....i´m stuck in there, help , py 3.11 w11
I looked at it (it's been a while since I opened the simulator myself, so I had to figure some things out again), but I found the problem! When pasting the code in the code window, you should change "np.object" to "object" (you can also re-install the simulator, since I updated the GitHub-repo).
When adding particles, the code uses the current 'particle settings' (from the particles tab). So it's best to change this to appropriate settings for a cloth (I suggest: radius: 4, mass: 1, attraction-radius: -1, attr-strength: 500, repulsion-radius: 40, repel-strength: 1, link-breaking-forces: -1, also leave all the boxes unchecked) and set the gravity to 0.6 and the air resistance to 0.04 in the simulation settings.
Hope this helps :).
U're a BOSS! gg
Could you add a player character so we could interact with the scene as a player?
I really like the idea, but I think I'll leave it as it is for now, because it might look more like a game otherwise. Feel free to create your own version using the code from the GitHub repository! (though, if you would share it somewhere, please mention that the original code came from me)
With the current version, you can technically already do something like this. Obviously, you can use the cursor to manipulate objects (also during simulation), but you could also make a 'player character' using the code window (binding keys to certain forces on a specific particle that represents the player).
i try to run it but ui is a little buggy. It looks like the frame is to small for showing all the assets. Is this a common problem?
Mmh.. I've never had a problem with that myself, but maybe you can try adjusting the width and height parameters in the ParticleSimulator.py file (line 3). Hope that solves the problem :).
How did you get yours to form into a uniform diagonal patten. They attract and repel but they keep no specific shape
Are you trying to get similar results using the simulator or by making your own version of a particle simulator?
In the first case, you can just copy the particle properties of the scene that's created when booting up the program.
In the second case, there is no specific way to make them form this pattern. The pattern itself is self-emerging... No rule makes them do this: it's just the most optimal way to 'stack' circles (you can regard the repel area as a circle). When implementing the attraction between particles that are far away and the repulsion of particles that are close-by each other, you should see similar patterns.
Hopefully this helps? If not, you can always elaborate on your question and I'll try to give more information :).
Sir,
May I know what papers/books about SPH did you use to make this code?
thanks
Actually, I didn't use any books or papers specifically to make this project. It was just an experiment to see what behaviour would emerge when you give particles one or a few simple properties. There aren't really any complex formulas that I implemented... just some experimentation that resulted in this program :).
Who do you optimize it
I think you asked this question twice, but I'll just copy my answer in case you hadn't seen my original answer: The optimization in this project was actually quite simple. The 'canvas' sort of gets divided into multiple grid cells which makes it so you only have to check for collisions in that grid cell. However, this doesn't work when the attraction or repulsion radius are too big or just "infitinitely large" (i.e. set to -1). In that case, all distances will have to be calculated and no optimization is possible.
There are better optimization strategies out there (like a quadtree), but this project just started as an experiment to see how far this simple grid optimization would get me.
@@PyExplained that you so much
Could your tell more about your attraction and repultion interaction algorithm, please?
Ok, this is kind of how it works (when 'Better Radii-Calculation' is set to True, otherwise some shortcuts will be taken):
First, the distance between 2 particles gets checked. If it's less than the attraction-radius and greater than the repulsion-radius, the particles will attract. If it's less than the repulsion-radius, they will repel each other.
Depending on whether they attract or repel each other, a different formula will be used.
When particles attracht each other, this formula gets used to calculate the magnitude of the force between them:
"magnitude = attr * rest_distance / 3000"
Where 'attr' is the attraction-strength and 'rest-distance' is is the absolute value of the difference between the distance and and the repulsion-strength.
When particles repel each other, this formula gets used to calculate the magnitude of the force between them:
"magnitude = -repel * rest_distance / 10"
Where 'repel' is the repulsion-strength of said particle.
This gets calculated for each particle of a 'collision'.
I hope that explanation answers your question. If you want more info, you can always check out the code in the GitHub-repository (github.com/PyExplained/Particle-Simulator/) or leave another comment.
Can I simulate all things with partical figuration?
I wouldn't necessarily say you can simulate ALL things that behave like particles in the real world, but there is a surprising amount of behaviours that you can reproduce using the simulator (e.g. fluid, rigid bodies, soft bodies, bouncy balls, light particles, planets, buildings, cloth, ropes, air particles, ...). In most cases, the stability and performace of the simulation are the limiting factors. There are also some systems that may be too difficult to reproduce (like fire and actual thermodynamics).
Definitely let me know if you find ways to use the simulator that I haven't already mentioned! I'm always curious to hear what other people use it for :).
im trying reconstruct sand and water particle movement like in noita. i've noticed that it horrendously demanding in terms of cpu consumption. any tips how can i optimize it? i have like few tousand pixels on screen...
First of all, it's really cool that you're trying to create your own physics simulations! I actually didn't know the game you were talking about, but I looked it up and it seems to be similar to the powder toy. I'm not sure if you are using the particle simulator that I wrote to recreate this kind of system. I assume you're talking about a simulation that you wrote yourself? In that case, I can't give a lot of tips to optimize it (as it's been a long time since I wrote this kind of program myself), but I do have some ideas.
Firstly, you could try using a sort of 'grid optimization' like I'm doing, although I don't think it's relevant when working with pixels and not particles, since you can just check for collisions with the neighbouring pixels. What you could also try, is using the Numba library (numba.pydata.org/) to run the calculations in parallel on your GPU. This will, however, require some adjustments to the code in order to make it compatible with Numba.
I hope this already gives you some ideas, but be sure to let me know if you need more help :).
@@PyExplained
Oh, thanks for answer! I did everything from scratch in PyGame. Every pixel has it's X, Y coordinates. I've tried numba, multiprocessing, cython. Neither of these worked for me, I recieved different errors everytime or they slowed it even more. It's really werid. I supposed Python is not made for this kind of stuff. Every pixel checks if there row bottom with place X-1, X, X+1 is free basically. It has to check if the given coordinaes (ex. Y+1, X-1) are occupied. This is the curse, that's why I'm using sets' intersection and it actually makes it faster a little. I added parameter 'age' which counts time from pixel spawn and if this time is above 3 seconds it stops it's calculations. This gave me like 2x more pixels on screeen, but they freeze after that time.
I'm kinda newbie to programming and I don't know algorithms but if you want, there it is.
github.com/gracjan-p/gracjan-p.github.io/blob/main/media/pyita.py
I just took a look at your project and it looks amazing already! On my PC, I can get around 20.000 particles (water + sand) on screen before the FPS starts to drop below 30, so imo it's quite optimized already (for a basic simulation). I haven't inspected the full code yet, but one thing that does seem 'sub-optimal' is checking the set you created for particles that already hold that position. Wouldn't it make more sense to make a variation on the 'particles_arr' that has the same dimensions as your screen and stores the particle objects as its elements on their respective locations. Then you could just check at a certain index whether or not there is already a particle object present.
That's just an idea I had, but maybe you already tried it and it didn't make it any faster... I actually haven't programmed anything for like more than a year, so I would need to brush up some programming skills and principles to give you good advice.
I would also change the fact that you're using the age parameter to determine if you should update a particle or not. Maybe it would be better to have a boolean variable that determines if the particle got 'stuck' (/ is in a stable position). Then you could set that back to false if you remove particles below that 'stable' particle.
One last thing that I noticed: the sand particles seem to be able to float on the water. Maybe you should make it so they can swap places with the water particles and sink to the bottom?
@@PyExplained
I do appreciate for a good word :D
1) Tried NumPy 2d array for this grid. Didn't made a huge difference. The problem is the amount of repetitive calculations for each pixel. There are too many of them. Matrix is better tho because It could easily check for type of particle near so it would act differently in dependency of it.
2) I'll give a try with boolean values. I did this stuck trick but it had just one 'old' position' and pixels tended to freeze in air because of collisions with other particles near them.
3) I know sand float on water I just didn't implied the swapping position yet. It's still kinda buggy for now. Water is not as fluid as It should be, etc.
Sounds like you're already on your way to outsmart me concerning physics simulations :). For real, though, most of my projects just came to be from me tinkering around with code and something more or less cool arising. In other words, I'm afraid I can't give you any specific tips to further improve your simulation ('cause you probably know more about this stuff than I do at the moment).
Basically, great work so far! And don't hesitate to give me some updates if you want to (Discord: #pyexplained).
Hi, your simulation looks amazing. Unfortunately i am a absolute beginner in python and not able to compile it. This is the error I get:
line 502, in simulate
cv2.circle(image, (int(particle.x), int(particle.y)), particle.r, particle.color, -1)
cv2.error: OpenCV(4.5.5) :-1: error: (-5:Bad argument) in function 'circle'
> Overload resolution failed:
> - Layout of the output array img is incompatible with cv::Mat
> - Expected Ptr for argument 'img'
It would be great, if you could help.
Thank you
Hi, could you let me know whether you get the error when trying a specific thing or if it's just when you try to open the simulator? Frankly, I've never seen that error before, nor do I know what causes it. Maybe you're using a different version of Python or one of the libraries, but it could also be the operating system (I only tested it on Windows 10). Could you give me some details on your Python version and OS?
You could also test if it works with the '.exe' version of the simulator (github.com/PyExplained/Particle-Simulator-.exe-).
i did it 3 ways i am a newbie too , i git cloned it from url , i downloaded the zip and unzipped it in my py 3.11 folder, runs neat from it , ten downloaded the exe and runs great too , ust when i add code to examples like clothes buildings , from ReadMe note i get warnings and errors
Can you make .exe file? I would want to play with it but i don't want to install any python executor.
Normally, you shouldn't try to compile Python files, because they are not meant to be compiled. The resulting file would be really large and quite inefficient. I do understand that you don't want to install all the dependencies, so I compiled the files anyway and you can download them right here: github.com/PyExplained/Particle-Simulator-.exe-.
Hope this helps
@@PyExplained Thanks alot!
it's crazy
very interesting simulation bro!. can you please share codes. thanks from Tanzania
Thanks! There's a link to the GitHub-project (with the code) in the description of the video :).
What all modules do you used?
Here's a list of the modules I used: tkinter, pynput, PIL, numpy, threading, random, pickle, time, math, OpenCV and os
@@PyExplained thankyou
how much if you do a simulation?
What exactly do you mean by your question? You should be able to run simulations yourself if you download the code and it's free!
HUh ..... Even AI can't make it run ????
cv2.circle(image, (int(particle.x), int(particle.y)), particle.r, particle.color, -1)
cv2.error: OpenCV(4.9.0) :-1: error: (-5:Bad argument) in function 'circle'
> Overload resolution failed:
> - Layout of the output array img is incompatible with cv::Mat
> - Expected Ptr for argument 'img'
@@user-uo7vo4wn8r I can't seem to replicate the error... Maybe you could try downloading the ".EXE"-version? If you send me some details about your Python, OpenCV and Numpy version, I could try and take a look at it (though I can't promise anything, because I haven't really looked at the project for a long time).
too slow
You're absolutely right that it isn't the fastest simulator out there. Back when I was working on it, I tried implementing GPU-accelerated computing using CUDA, but I don't remember ever getting close to making it run decently (mostly because the code was not adapted to the CUDA library when I first wrote it). Since then, I haven't really worked on the simulator, but it's a little toy project after all. Hence, I don't really think it matters that it's in Python and it performs some unefficient calculations.
code not work
That's strange... I tested it again just now and everything still seems to be working for me. Which version of Python are you running this on exactly? Maybe you didn't install all the required libraries (you can find more details on that in the documentation on GitHub)? Also, if there's an error message showing, it might be handy if you could paste it over here so I can see what might be causing the error.
@@PyExplained No module named 'PIL.ImageTk'. But i have pillow installed
@@timon1816 I honestly don't know what could be the problem then. Perhaps the library works differently in newer versions of Python? You can always try and install the exe-version of the code. I hope that solves the problem...