Summing vector fields
in
Programming Questions
•
1 year ago
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.)
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.)
- 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
1