3

I'm modeling a vector field in flash and spawning a mess of particles to visualize the flow of the field. Using the vector field F(x,y)=yi-xj

This vector field has a curl, the particles are to move in circles which they do. My problem is that the particles diverge from the origin, though this particular vector field has no divergence. I suspect that my data types may be losing decimal precision during the very basic caluclations for this field or perhaps I'm making some logic mistake I am unsure.

This code spawns the particles on the screen (which is 800x450). This code probably isn't in trouble, but for completeness I included it.

//spawn particles
var i:int;
var j:int;
//spread is the spacing between particles
var spread:Number;
spread = 10.0;
//spawn the particles
for (i=0; i<=800/spread; i++)
{
 for (j=0; j<=450/spread; j++)
 {
  //computes the particles position and then constructs the particle.
  var iPos:Number = spread * Number(i) - 400.0;
  var jPos:Number = 225.0 - spread * Number(j);
  var particle:dot = new dot(iPos,jPos,10.0);
  addChild(particle);
 }
}

This is the "dot" class which contains everything important about the particles being spawned.

package 
{
 //import stuff
 import flash.display.MovieClip;
 import flash.events.Event;
 public class dot extends MovieClip
 {
  //variables
  private var xPos:Number;
  private var yPos:Number;
  private var xVel:Number;
  private var yVel:Number;
  private var mass:Number;
  //constructor
  public function dot(xPos:Number, yPos:Number, mass:Number)
  {
   //Defines the function to be called when the stage advances a frame.
   this.addEventListener(Event.ENTER_FRAME, moveDot);
   //Sets variables from the constructor's arguments.
   this.xPos = xPos;
   this.yPos = yPos;
   this.mass = mass;
   //Set these equal to 0.0 so the Number type knows I want a decimal (hopefully).
   xVel = 0.0;
   yVel = 0.0;
  }
  //Controlls the particle's behavior when the stage advances a frame.
  private function moveDot(event:Event)
  {
   //The vector field is a force field. F=ma, so we add F/m to the velocity. The mass acts as a time dampener.
   xVel += yPos / mass;
   yVel +=  -  xPos / mass;
   //Add the velocity to the cartesian coordinates.
   xPos +=  xVel;
   yPos +=  yVel;
   //Convert the cartesian coordinates to the stage's native coordinates.
   this.x = xPos + 400.0;
   this.y = 225.0 + yPos;
  }
 }
}

Ideally the particles would all move in circles about the origin forever. But the code creates a situation where the particles rotate around the origin and spiral outwards, eventually leaving the stage. I'd really appreciate a helping hand. Thanks!

warpstack
  • 71
  • 2
  • 10
  • I think your assumption is correct. Seems floating point inaccuracies are the cause. As to how you can fix this..... – Allan Nov 12 '10 at 01:50
  • I am still suspicious though, my calculations shouldn't produce numbers which are too large for the Number data type. Unless the inaccuracy can be seen with fractional values such as 1/3. Then it would be impossible to model vector fields in flash using the native data types. – warpstack Nov 12 '10 at 23:16

2 Answers2

1

You can normalize each particle's distance from origin (maybe not on each step to save calculations). Also it seems your code is not optimized - you are creating ENTER_FRAME listener for every particle, and there is 3600 of them. One listener should be enough. And I would change all these divisions to multiplication by inverse value.

alxx
  • 9,897
  • 4
  • 26
  • 41
  • I'll make these optimizations and see where I am at. While I could normalize the particles radius from the origin this would not allow me to easily change the vector field. While currently the field is defined within the particle, the field will later be defined elsewhere and I'd like the particle to be ready to behave appropriately in any any field. – warpstack Nov 12 '10 at 22:44
  • Yes, normalization is very specific workaround. Maybe you can emulate high precision numbers in actionscript and use them instead of Number for field calculations? Like Python does with its numbers. Don't ask me how, though. – alxx Nov 13 '10 at 06:45
  • My simulation is for teaching purposes so I don't need the values to be perfect just close enough to pass inspection. I'll try to mess with my code to see if I can do the calculations in such a way that it minimizes the error as much as possible. – warpstack Nov 14 '10 at 19:31
0

To set decimal places use the toFixed() function.

//Set these equal to 0.0 so the Number type knows I want a decimal (hopefully).
 xVel = 0;
 yVel = 0;
 xVel.toFixed(1); //(specifies decimal places)
 yVel.toFixed(1);

Hope it helps

Steve
  • 149
  • 1
  • 11
  • No, `toFixed` returns a String of the number with the specified number of decimal places. It doesnt do anything to the actual number. – Mikepote Apr 13 '11 at 14:25