We are about to switch to a new forum software. Until then we have removed the registration on this forum.
Hello,
I am trying to create a charge particle system where when you click left mouse it creates negative charge and right click creates positive charge. You can add as many as positive and negative charges.
The problem in my code is when I try to calculate the ditance between the two charges it returns NaN and when I check for NaN as in line number 63 it returns some float values so I figured out that when I try calculating the force and accl it returns NaN but when float.NaN(d) is ture the d returns some value.
ArrayList<Charge> poop = new ArrayList();
void setup() {
size(300, 200);
}
float k = 1; // 8.98E+9; // 8.9875517873681764×10^9
void draw() {
background(0);
for (int i=0;i<poop.size();i++) {
Charge q = (Charge)poop.get(i);
q.show();
q.update();
q.applyForce(q);
}
}
void mousePressed() {
int t=1;
if (mouseButton == RIGHT) t = 1;
if (mouseButton == LEFT) t = -1;
Charge C = new Charge(t, mouseX, mouseY);
poop.add(C);
}
class Charge {
PVector loc;
PVector vel;
PVector acc;
float k = 1;
float state = 1;//1.60E-19; // 1.602176487×10−19
color c;
Charge(int t, int x, int y) {
loc = new PVector(x, y);
vel = new PVector(0, 0);
acc = new PVector(0, 0);
//acc = new PVector(random(-0.05, 0.05), random(-0.05, 0.05));
state*=t;
c = (color) random(#000000);
}
void show() {
noFill();
strokeWeight(2);
stroke(c);
ellipse(loc.x, loc.y, 20, 20);
setCharge();
}
void update() {
vel.add(acc);
vel.limit(1);
loc.add(vel);
}
void applyForce(Charge C) {
for (int i=0;i<poop.size();i++) {
Charge Q = (Charge)poop.get(i);
PVector dir = PVector.sub(Q.loc, C.loc);
float d = dir.mag();
println(" d: " + d);
if (!Float.isNaN(d)) {
float force = (k*Q.state*C.state)/d*d;
dir.mult(force);
acc.add(dir);
}
}
}
void setCharge() {
pushMatrix();
translate(loc.x, loc.y);
if (state<0)line(-5, 0, 5, 0);
else {
line(0, -5, 0, 5);
line(-5, 0, 5, 0);
}
popMatrix();
}
}
boolean flag=false;
void keyPressed() {
flag = !flag;
}
Answers
The problem is caused because in applyForce you end up testing a charge against itself which creates the NaNs. Change this method to
There is now need to to check for NaNs because they will not be created.
@Quark once again you saved me :) :) :) Thank you sooooo much :) Actually I had the same thought it might be returning NaN becuase charge is checking against itself. I should believe myself before posting silly question :P .............
So now I did the changes but something strange happening ..now same charges are attracting and opposite charges are repling :/ ...
Tip: No need for
(Charge)
casting if you had already declared the Collection type variable is for Charge references only! *-:)ArrayList<Charge> poop = new ArrayList();
Charge Q = poop.get(i);
The applyForce method is part of the Charge class but is testing every charge against every other charge. Then you repeat this for each Charge in draw.
Anyway I have made the corrections to the code see below
@Quark I dont know if I am correct but I think in the line 64 where you have made correction for checking if this!=C is correct because when you think "this" object has default positive charge (since charge of the object is set by the mouse pressed) so it has created another problem now charges are randomly attracting and reppelling smilar and opposite charges.
I think you will find the problem is that acc is not being zeroed each update try
@Quark, I tried it but still after some click same charges are starting to attract each other and repelling to opposite charge. I think my code is buggy :( I'll try to write fresh code.
I can't see anything wrong with the code logic, but once you have more than 2 charges you have a more complex system so seeing cause-and-effect relationships will be difficult.
In the update method you limit the velocity to 1 (line 57) but this might cause too much distortion of the system if the magnitude of acc is much larger than 1
Oh ! I got the error. I was not normalizing the dir vector so I have normalized the dir vector before multiplying it with the force :D Now it is working fine :D Thanks Quark :)
Just a last question, when I am drawing a resultant vector with line(dir.x,dir.y,C.loc.x,c.loc.y); , the line is drawing from the origin. why not line is pointing towads the net force direction ? It is also not working in js mode?
dir is a PVector relative to the charge location so
line(c.loc.x, c.loc.y, c.loc.x + dir.x, c.loc.y + dir.y);
The only problem is that the magnitude of dir is very small so you won't see it. Try
line(c.loc.x, c.loc.y, c.loc.x + dir.x *10, c.loc.y + dir.y * 10);
Thanks that worked :)
blyk, remember to choose a category when posting... Thanks.