Pages: [1]   Go Down
Author Topic: Summing vector fields  (Read 754 times)
0 Members and 1 Guest are viewing this topic.
Dublin, Ireland
Offline Offline
Newbie
*
Karma: 0
Posts: 34
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi,

The sketch below produces two vector fields. Part of the third last method called calculateField() is commented out. Uncommenting that section calculates an average for theta and magnitude for the two fields and should then plot a single vector field which would be the sum of the two fields.

Firstly the fields are not summing correctly and secondly moving the charges, only one seems to effect the overall field. (The fields can be changed by holding down the left mouse button and dragging the charges around.)

Code:
int numCharges = 2;//the number of charges
Electrons[] charge = new Electrons[numCharges];//Declare the 1D array called 'charge', the elements of which are objects of the class called 'Electrons'
int numVectorsX = 21;//20*30 that's number of vectors across by spacing between each is width and add 1 to the number of vectors in the x-direction
int numVectorsY = 11;//10*30 that's number of vectors down by spacing between each is height and add 1 to the number of vectors in the y-direction
int distance = 30;//spacing between vectors, same for x and y directions
Field[][] vectors = new Field[numVectorsX][numVectorsY];//Declare the 2D array called 'vectors', the elements of which are objects of the class called 'Field'
float targetX = 300, targetY = 150, pol, fieldStrength, minDiameter, maxDiameter;//the field initially points to a singularity at the coordinate (300,150). targetX and targetY is where the field points to. 'pol' is the polarity of the charge
float theta = 0;//angle between charge and each vector
float magnitude = 0;//length or magnitude of a vector
float fieldTransparency = 0;
int r, g, b;//red green blue variables for charge colour
float Fieldstrength;
int countCharges = -1;
void setup() {
  size(600, 300);
  smooth();
  noStroke();
  for (int k = 0; k < numCharges; k++) {//these loops populate the 2D array, each element of this array is an object and each object is a vector
    //x, y, r, g, b, transparency, count, initial diameter, minChargediameter, maxChargediameter... the fields
    charge[k] = new Electrons(100 + (100*k), 100 + (50*k), 0, 0, 255, 30, 1, 100, 20, 400); //Construct the object charge
  }
  float maxdist = 400;
  for (int i = 0; i < numVectorsX; i++) {//these loops populate the 2D array, each element of this array is an object and each object is a vector
    for (int j = 0; j < numVectorsY; j++) {
      // fieldTransparency, xField, yField, magnitude, theta, maxdist, countCharges
      vectors[i][j] = new Field(fieldTransparency, i*distance, j*distance, magnitude, theta, maxdist, countCharges);
    }
  }
}
void draw() {
  background(#DAEBF2);
  for (int k = 0; k < numCharges; k++) {//these loops populate the 2D array, each element of this array is an object and each object is a vector
    charge[k].move();
    charge[k].display();
  }

  for (int i = 0; i < numVectorsX; i++) {
    for (int j = 0; j < numVectorsY; j++) {
      for (int k = 0; k < numCharges; k++) {
        vectors[i][j].calculateField();
        vectors[i][j].update(charge[k].x, charge[k].y, charge[k].diameter, charge[k].minChargediameter, charge[k].maxChargediameter);//puts the fields x, y etc. from the object 'charge' into the object 'vectors', there they are set equal to targetX, targetY, etc. which is where the field points to
        vectors[i][j].polarity(charge[k].r);//puts the field r from the object 'charge' into the object 'vectors', there it is set equal to 'pol'.
        //vectors[i][j].plotField();
      }
    }
  }
}
void mouseReleased() {
  if (mouseButton == CENTER) {
    for (int k = 0; k < numCharges; k++) {//these loops populate the 2D array, each element of this array is an object and each object is a vector
      charge[k].released();
    }
  }
}
class Electrons {
  float x, y, r, g, b, transparency, diameter, minChargediameter, maxChargediameter;
  int count;
  //Constructor
  Electrons(float xpos, float ypos, float rpos, float gpos, float bpos, float trans, int countpos, float diameterpos, float minChargediameterpos, float maxChargediameterpos) {
    x = xpos;
    y = ypos;
    r = rpos;
    g = gpos;
    b = bpos;
    transparency = trans;
    count = countpos;
    diameter = diameterpos;
    minChargediameter = minChargediameterpos;
    maxChargediameter = maxChargediameterpos;
  }
  void move() {
    if (((dist(mouseX, mouseY, x, y))<(diameter/2))&&(mousePressed == true)) {//tests to see if mouse is on charge
      if (mouseButton == LEFT) {
        x = mouseX;
        y = mouseY;
      }
      else if (mouseButton == RIGHT) {//dragging mouse toward centre decreases size of charge
        if (((dist(mouseX, mouseY, x, y))-(dist(pmouseX, pmouseY, x, y)))>(0)) {
          if (diameter < maxChargediameter) {//prevents diameter getting too big, max diameter is 400
            diameter = diameter + 5; //increases size of diameter
            transparency += 0.5;
          }
        } //dragging mouse away from center increases size of charge
        else if (((dist(mouseX, mouseY, x, y))-(dist(pmouseX, pmouseY, x, y)))<(0)) {
          if (diameter > minChargediameter) {//prevents diameter getting too small and circle disappearing, min diameter is 20
            diameter = diameter - 5; // decreases size of diameter
            transparency -= 0.5;
          }
        }
      }
    }
  }
  void display() {
    fill(r, g, b, transparency);//fills the charge with colours red, green, blue
    ellipse(x, y, diameter, diameter);//draws the charge
  }
  void released() {
    if (((dist(mouseX, mouseY, x, y))<(diameter/2))) {//tests to see if mouse is on charge
      count = (count + 1) % 2;
      if (count == 1) {//sets colour to blue once
        r = 0;
        b = 255;
      }
      else if (count == 0) {//set colour red to blue
        r = 255;
        b = 0;
      }
    }
  }
}
class Field {
  float fieldTransparency, xField, yField, magnitude, theta, maxdist, countCharges;
  //Constructor
  Field(float fieldTransparencypos, float xFieldpos, float yFieldpos, float magnitudepos, float thetapos, float maxdistpos, int countChargespos) {
    fieldTransparency =fieldTransparencypos;
    xField = xFieldpos;
    yField = yFieldpos;
    magnitude = magnitudepos;
    theta = thetapos;
    maxdist = maxdistpos;
    countCharges = countChargespos;
  }
  void calculateField() {
    float theta = atan((targetY-yField)/(targetX-xField));//(targetX,targetY) coordinates of the charges. (xField,yField) coordinates of point at which vector is defined.
    float d = (sqrt(pow(targetY-yField, 2) + pow(targetX-xField, 2)));//should be 1/r^2 but not practical here
    if (targetX < xField) {//without this the vectors on the left of screen will point away from charge and vectors on right of screen toward it. All should point away or toward it
      theta += PI;
    }
    if (pol == 0) {//if 'pol' is 0 then r = 0 in charge.released and so charge is blue and positive
      theta += PI; //points the field away from the charge position for a positive charge
    }    
    float maxFieldstrength, minFieldstrength = 0;
    float newVectorlengthmin = 10, newVectorlengthmax = 35;
    maxFieldstrength = map(fieldStrength, minDiameter, maxDiameter, newVectorlengthmin, newVectorlengthmax);//maps the fieldStrength, which is the diameter of the charge, from the max and mix charge diameter to the max and min charger length
    if (d > maxFieldstrength) {
      magnitude = map(d, 0, maxdist, maxFieldstrength, minFieldstrength);//the second last value is the maximum length of a vector. 2nd last value should a min and last a max value, inverting them puts longest vectors near charge
      fieldTransparency = map(d, 0, maxdist, 205, -20);
    }
/*    countCharges = (countCharges + 1) % numCharges;
    if (countCharges != 0) {
      fieldTransparency += fieldTransparency;
      theta += theta;//sums theta
      magnitude += magnitude;//sums theta
    }
    if (countCharges == 0) {
      fieldTransparency = fieldTransparency/numCharges;//calculates average
      theta = theta/numCharges;//calculates average
      magnitude = magnitude/numCharges;//calculates average
*/
      stroke(1, fieldTransparency);
      fill(0, 0, 0);
      pushMatrix();
      translate(xField, yField);
      rotate(theta);
      line(0, 0, magnitude, 0);
      beginShape();//this shape is the arrow heads of the vectors
      vertex(magnitude, -3);
      vertex(magnitude, 3);
      vertex(magnitude + 3, 0);
      endShape(CLOSE);
      popMatrix();
      noFill();
      noStroke();
    //} THIS BRACKET IS COMMENTED OUT
  }
  void update(float x, float y, float diameter, float minChargediameter, float maxChargediameter) {//this method transfers fields x, y, diameter, ... etc from the class Electrons to the class Field
    targetX = x;//x-coordinate of charge
    targetY = y;//y-coordinate of charge
    fieldStrength = diameter;
    minDiameter = minChargediameter;
    maxDiameter = maxChargediameter;
  }
  void polarity(float r) {
    pol = r;
  }
}


Any help would be greatly appreciated.

Thanks,

Shane
« Last Edit: October 17, 2012, 08:50:21 pm by ofey » Logged

Those who say it can't be done are usually interrupted by others doing it.

Massachusetts, USA
Offline Offline
Tesla Member
***
Karma: 201
Posts: 8695
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

What you have there appears to be a Processing sketch, not an Arduino sketch.  You might want to ask your question on a Processing forum like http://forum.processing.org/programming-questions
Logged

Send Bitcoin tips to: 1L3CTDoTgrXNA5WyF77uWqt4gUdye9mezN
Send Litecoin tips to : LVtpaq6JgJAZwvnVq3ftVeHafWkcpmuR1e

Dublin, Ireland
Offline Offline
Newbie
*
Karma: 0
Posts: 34
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Oops! :smiley-red

Thanks for pointing that out. I'm working too late, time to sleep!
Logged

Those who say it can't be done are usually interrupted by others doing it.

Pages: [1]   Go Up
Jump to: