We closed this forum 18 June 2010. It has served us well since 2005 as the ALPHA forum did before it from 2002 to 2005. New discussions are ongoing at the new URL http://forum.processing.org. You'll need to sign up and get a new user account. We're sorry about that inconvenience, but we think it's better in the long run. The content on this forum will remain online.
IndexProgramming Questions & HelpPrograms › Charged Particles
Pages: 1 2 3 
Charged Particles (Read 5611 times)
Re: Charged Particles
Reply #15 - Dec 14th, 2009, 1:29am
 
Well using just a single point works most of the time and avoids the complexities of storing an array and calculating an average vector.   However, it gets a little flaky when the mouse is being dragged very slowly and the recorded point gets too close to the current point; so you could build something in to handle that (i.e. if dist between the 2 < threshold do special case).

I may overhaul the bouncing balls code though and apply the same principles for mouse-handling as used in my drag and drop demo (also on OpenProcessing): you can build mouse-handling directly into the class.
Re: Charged Particles
Reply #16 - Dec 14th, 2009, 1:02pm
 
I have to say the example blindfish was suggesting is a little weired. Sometimes if you drag a particle and let go, it zooms away as extremely high speed. Even fishing for a particle (have mouse stay at the same position all time) then let go is not immune to this problem. After inspecting the code, I found no mention of time in calculating for speed. Say if dragged gets processed every so often at a very constant pace, no problem. But if dragged doesn't get processed very regularily and especially not at the same constant pace as draw, we have a problem. I suggest using System.nanoTime() to store time and the speed will be multiplied a factor of 2 if say dragged is triggered around 60fps instead of 30fps for draw(). I try to pin a particle by clicking on the window and let go without moving the mouse, the particle still has speed when I let go of the mouse button, sometime huge speed Smiley
Re: Charged Particles
Reply #17 - Dec 14th, 2009, 3:30pm
 
liudr - there may well be a bug in my implementation; but the original idea is from Actionscript Animation and is sound.  In theory you record the position of the mouse on the previous frame (so pmousex/y could be used).  You then check the distance from that to the current position and that gives you an angle and an indication of speed.  Sure it's relatively crude; but in most cases it suffices.

Edited:
Actually thinking about it this is an issue with my implementation and specifically my use of 'mouseDragged()'.  The original Actionscript code used a boolean to check 'dragged' and compared the points at the set framerate; but of course mouseDragged() can update faster than the framerate so the two points being compared don't have enough distance between them to make it work properly...  I'll fix it in the morning.  Trust me, when it's done properly it does work Wink
Re: Charged Particles
Reply #18 - Dec 14th, 2009, 3:58pm
 
Yep. You compared a distance of mouse positions between two events happening in sequence that are not necessarily happening at fixed delay. Plus, there is also a case where the dragged ball is bounced away from the mouse while being pinned but not dragged ^_^. Just find a ball and keep it in place and see it bounces off to the side by other balls. But once you move your mouse, the dragged routine updates the ball position just fine.
Re: Charged Particles
Reply #19 - Dec 14th, 2009, 7:11pm
 
In my program I also realised that oldx and oldy aren't initialised if you don't drag the mouse - so are initialised at zero, presumably. So you do get a huge catapult effect if you just hold the mouse down on a particle and then release without dragging it (Blindfish - your balls seem to do the same thing - not surprisingly since I used your code!).
Re: Charged Particles
Reply #20 - Dec 15th, 2009, 2:38am
 
OK - I just fixed a lot of the issues with the code and updated my sketch on OpenProcessing.

First off I stopped using the ball position to determine the velocity when thrown and now use the mouse position.  The issue with insane speed was caused because of my tendency to centre the ball on the mouse position when it is 'picked up': that created a large distance between oldX/Y and currentX/Y leading to high speed on release.  Happily resolving this issue resolved the other problem: using pmouseX/Y by definition compares the position from the previous frame (and there's also no need to store the variable on mouseReleased).

There's an argument to factor in framerate (or use a time-based approach) since that would affect the distance recorded between the two points and therefore affect the speed (i.e. I imagine at higher framerates the speed will diminish).  There's also still an issue at slow speeds where it can go off in an unexpected direction; but this is more of a physical issue and I'm not sure a time based solution would avoid it: the act of releasing the button can lead to unintended motion of the mouse...  I guess storing the last few positions and averaging out the vector might limit this to some extent.

I did write the original code a while ago and would do things a little differently now anyway (e.g. handle mouse events in the class, use registerDraw() etc.), so might create an updated example and look into possible improvements; but for the moment it's now a lot better than it was.

Sorry Giles for posting a bad example and thanks liudr for the heads-up.
Re: Charged Particles
Reply #21 - Dec 15th, 2009, 4:42am
 
OK here's an updated implementation of the basic concept:

http://www.blindfish.co.uk/code/processing/throw-ball-01/

There are two classes: 'Body' just handles generic motion/bounds detection.  'Ball' handles display and interaction with built-in mouse handling, using the simplistic "mousePosition - previousMousePosition" to calculate a vector to 'throw' the ball.

The registerDraw() and, in particular, the mouse-handling technique was something I first saw posted by Quark - note the use of a global 'selected' variable to store the currently selected ball.  I find this approach makes it much easier to organise things: it avoids cluttering up the main draw loop with class-specific behaviour.  The only draw-back I've encountered thus far is that objects are drawn in the order that registerDraw() is called (I haven't yet explored workarounds).

I'm not convinced a time-based approach to throwing presents major advantages (and suspect there might be difficulties in the implementation), but I do wonder how an array of previously stored vectors would behave: I'll look into adding this later and may explore the time-based approach if the above isn't satisfactory.
Re: Charged Particles
Reply #22 - Dec 15th, 2009, 8:38am
 
blindfish,

Very nice and smooth mouse handling now! I just speculate a time-based tracking and averaging over several frames might help. I'm doing a project to track position on a camera. The tracked position is jittery. I'll try the averaging on it and post some results.

liudr
Re: Charged Particles
Reply #23 - Dec 15th, 2009, 9:30am
 
OK - I've left the old type of ball in for comparison purposes:  the new type - with averaging applied - is blue.  In that I store up to ten points and average the distance between each in the list.  This seems to produce much better results at slow speed, which seemed particularly prone to effects from release of the mouse button.  At fast speed it still works well, though as expected when you make a sudden change in direction just before releasing it continues in the average direction...

Since the original Ball object is intact (except for an added 'additionalDrawMethods()') I overwrote the previous example:

http://www.blindfish.co.uk/code/processing/throw-ball-01/

I'd be fairly happy with using this approach in a final project and can't imagine a time-based approach would be any easier to implement or produce noticeably better results...  but I'm prepared to be proven wrong Wink
Re: Charged Particles
Reply #24 - Dec 15th, 2009, 11:44am
 
You've really nailed it, Blindfish. The blue balls are very impressive at low speeds - seems to capture the release speed very well.
Re: Charged Particles
Reply #25 - Dec 15th, 2009, 2:02pm
 
I updated my own sketch to take advantage of your work Smiley

I just used the pmouseX, pmouseY method for release velocity as it is fine for my purposes. I also added an "affected" field for the particle class - using blindfish's "gravityaffected" idea. When this field is false the movement created by the attractions/repulsions is not processed. This stops the particle from drifting around when you have grabbed it with the mouse pointer.

The weird thing about this is that it works fine when I run it from Processing on my desktop - but in the Java applet on OpenProcessing, it doesn't work.
Re: Charged Particles
Reply #26 - Dec 16th, 2009, 6:57am
 
Glad I've been able to make up for my previous badly implemented example Smiley

The current version on OpenProcessing looks OK to me: the particle I pick up isn't influenced by other particles (i.e. doesn't drift) though it does still have influence on them.  You could check to ensure both particles have 'affected' set to true before applying forces to them if you wanted to avoid this...

One thing I just noticed: in each loop you process the forces twice:

Code:
for(int i=0; i<numparticles; i++)  {
   for(int j=0; j<numparticles; j++)    {
     float ijdist = dist(particles[i].xpos, particles[i].ypos, particles[j].xpos, particles[j].ypos);
   }
}


e.g. when i=0 and j=3 you compare the same two particles as when i=3 and j=0.  Another useful nugget I've seen posted by Quark: start j at the current value of i:

Code:
for(int i=0; i<numparticles; i++)  {
   for(int j=i; j<numparticles; j++)    {
     float ijdist = dist(particles[i].xpos, particles[i].ypos, particles[j].xpos, particles[j].ypos);
   }
}


It all still works; though you may find the reactions are less strong since you're only applying them once and not twice each frame Wink
Re: Charged Particles
Reply #27 - Dec 16th, 2009, 9:13am
 
Yeah. I should have picked that up when I was commenting on not having the same particle interact with itself at zero distance. I guess the loop should go like: notice the i+1 instead of i.

for (i=0; i<particles.length;i++)
{
 for (j=i+1; j<particles.length;j++)
 {
 }
}
Re: Charged Particles
Reply #28 - Dec 16th, 2009, 10:23am
 
Yes, that's right...the i+1 means you use half the matrix of comparisons, not including the diagonal (where i=j). Thanks for pointing that out.
Re: Charged Particles
Reply #29 - Dec 16th, 2009, 10:34am
 
Interestingly, changing this makes the sketch much more static. the chains that are formed sit in place, and don't migrate around. Something about checking the force and applying it twice seems to make the particles more jittery - more interesting behaviour. That's where I think "glitches" or mistakes in programming can lead to more interesting behaviour than "getting it right". Though it's good to have the understanding to be able to get it right if you need to.

It's weird...the drift problem is fixed now...must have been a browser refresh problem. The code was updated, I tried deleting the browser cache a few times and refreshing...but I still wasn't getting the most recent version of the applet... or maybe the problem was at the OpenProcessing end...

Anyway, thanks for all your help with this, guys...very instructive....
Merry Christmas!
Pages: 1 2 3