Electric field pattern generated by two charges

edited June 2014 in Share Your Work
    /* Electric field pattern generated by two charges, simulation of the classical experiment
    with semolina seed in castor oil (see: www.youtube.com/watch?v=7vnmL853784)
    (my first Sketch)  */


    size(1000,700); background(255);
    int cpx=200, cpy=350; // position of the first charge (the one on the left)
    int cnx=800, cny=350; // position of the second charge (the one on the right)
    int qp=1000, qn=-1000;// values of the charges; try qn=1000 and different combinations (e.g. qp=10, qn=1000)
    int x,y,dx,dy,dxn,dyn;
    float d1,E1,E1x,E1y,d2,E2,E2x,E2y;
    float EEx,EEy,EE,ll,deltax,deltay;
    fill(0); ellipse(cpx,cpy,8,8);
    fill(120); ellipse(cnx,cny,8,8);
    fill(0);
    ll=15; // grains of semolina dimension (try ll=10, ll=20)
    int ns=20000; // number of grains (try ns=10000, ns=30000)
    for(int i=0; i<ns; i++)
    {
    x=int(random(1000));
    y=int(random(700));
    dx=x-cpx; dy=y-cpy;
    d1=sqrt(dx*dx+dy*dy);
    E1=qp/(d1*d1);
    E1x=dx*E1/d1;
    E1y=dy*E1/d1;

    dxn=x-cnx; dyn=y-cny;
    d2=sqrt(dxn*dxn+dyn*dyn);
    E2=qn/(d2*d2);
    E2x=dxn*E2/d2;
    E2y=dyn*E2/d2;

    EEx=E1x+E2x;
    EEy=E1y+E2y;
    EE=sqrt(EEx*EEx+EEy*EEy);


    deltax=ll*EEx/EE;
    deltay=ll*EEy/EE;
    line(x,y,x+deltax,y+deltay);
    }

Comments

  • My first Sketch. Be patient and excuse my English

  • very nice!

    /* Electric field pattern generated by two charges, simulation of the classical experiment
     with semolina seed in castor oil (see: www.youtube.com/watch?v=7vnmL853784)
     (my first Sketch)  */
    
    
    int cpx=20, cpy=150; // position of the first charge (the one on the left)
    int cnx=800, cny=350; // position of the second charge (the one on the right)
    int qp=1000, qn=-1000;// values of the charges; try qn=1000 and different combinations (e.g. qp=10, qn=1000)
    
    int x, y, dx, dy, dxn, dyn;
    float d1, E1, E1x, E1y, d2, E2, E2x, E2y;
    float EEx, EEy, EE, ll, deltax, deltay;
    
    
    void setup() {
      size(1000, 700); 
      background(255);
    }
    
    void draw() {
    
      background(255);
    
      cpx=mouseX;
      cpy=mouseY;
    
    
      fill(0);
      ll=15; // grains of semolina dimension (try ll=10, ll=20)
    
      int ns=20000; // number of grains (try ns=10000, ns=30000)
      for (int i=0; i<ns; i++)
      {
        x=int(random(1000));
        y=int(random(700));
        dx=x-cpx; 
        dy=y-cpy;
        d1=sqrt(dx*dx+dy*dy);
        E1=qp/(d1*d1);
        E1x=dx*E1/d1;
        E1y=dy*E1/d1;
    
        dxn=x-cnx; 
        dyn=y-cny;
        d2=sqrt(dxn*dxn+dyn*dyn);
        E2=qn/(d2*d2);
        E2x=dxn*E2/d2;
        E2y=dyn*E2/d2;
    
        EEx=E1x+E2x;
        EEy=E1y+E2y;
        EE=sqrt(EEx*EEx+EEy*EEy);
    
    
        deltax=ll*EEx/EE;
        deltay=ll*EEy/EE;
        stroke(map(x, 0, width, 0, 255), y, 111);
    
        line(x, y, x+deltax, y+deltay);
      }
    
      fill(0); 
      ellipse(cpx, cpy, 8, 8);
    
      fill(120); 
      ellipse(cnx, cny, 8, 8);
    
      noLoop();
    } // func 
    
    void mouseMoved() {
      loop();
    }
    //
    
  • size(1000,700);
    background(255);
    int cpx=500, cpy=350;
    int cnx=800, cny=350;
    int qp=1000, qn=1000;
    int x,y,dx,dy,dxn,dyn;
    float d1,E1,E1x,E1y,d2,E2,E2x,E2y;
    float EEx,EEy,EE,ll,deltax,deltay;
    fill(0); ellipse(cpx,cpy,8,8);
    //fill(120); ellipse(cnx,cny,8,8);
    fill(0);
    ll=15;
    
    for(int i=0; i<20000; i++)
    {
    x=int(random(1000));
    y=int(random(700));
    dx=x-cpx; dy=y-cpy;
    d1=sqrt(dx*dx+dy*dy);
    E1=qp/(d1*d1);
    E1x=dx*E1/d1;
    E1y=dy*E1/d1;
    
    E2x=0.016;
    E2y=0;
    
    EEx=E1x+E2x;
    EEy=E1y+E2y;
    EE=sqrt(EEx*EEx+EEy*EEy);
    
    
    deltax=ll*EEx/EE;
    deltay=ll*EEy/EE;
    line(x,y,x+deltax,y+deltay);
    }
    
  • Thank you Chrisir, very good improvement, I'll study it and I'm sure your sketch will be useful to improve my knowledge of Processing. I teach Maths and Physics in an Italian high school and I wondered about the pattern field of the interaction of a uniform electric field with the one generated by a single charge. Of course, you can imagine it, but, what about a simulation program? First I tried a situation I already knew (Electric field pattern generated by two charges), then I wrote the following sketch:

  • It looks very nice, it is a piece of art.

  • It's always great to see science visualized with a bit of code! *-:)

    Next up, making it 3D?

  • I wonder how make complete uniterruoted lines ?

    and what if one pole ist stronger ?

  • long and mesy version for Field and equipotential line (not so efficient for the equi)

    import processing.pdf.*;
    
    int posCount = 3;
    float magMax;
    float magMin;
    
    int res = 6;
    boolean exportPDF;
    
    boolean drawFieldVec = true;
    boolean drawFieldPot = false;
    
    PVector [] allPos = new PVector [posCount];
    float [] posPot = new float [posCount];
    
    float[][] displayMag = new float [600/res][600/res];
    PVector [][] sumForce = new PVector [600/res][600/res];
    boolean [][] randomDisplay = new boolean [600/res][600/res];
    EMF[] FieldList = new EMF[posCount];
    
    
    //---[testPoint]
    ArrayList<ArrayList<PVector>> allTestPtHistory =  new ArrayList<ArrayList<PVector>>(); 
    
    FloatList testPot = new FloatList();
    ArrayList<PVector> startPt = new ArrayList<PVector>();
    ArrayList<PVector> testPt  = new ArrayList<PVector>();
    //---[Neighbors Finding]
    int [] neighborsX = {
      -1, -1, 0, 1, 1, 1, 0, -1
    };
    int [] neighborsY = {
      0, -1, -1, -1, 0, 1, 1, 1
    };
    ArrayList<Boolean> keepGoing =  new ArrayList<Boolean>();
    int count = 0;
    
    
    
    void setup() {
      size(600, 600);
      for (int i =0; i< allPos.length; i++) {
        allPos[i] = new PVector (random(70, width-70), random(70, height-70));
        posPot[i] = random(-1, 1);
    
        FieldList[i] = new EMF(allPos[i]);
      }
      for (int i = 0; i< width/res; i++) {
        for (int j = 0; j< width/res; j++) {
          if (random(1)>0.4) {
            randomDisplay[i][j] = true;
          } else {
            randomDisplay[i][j] = false;
          }
        }
      }
      for (int i =0; i<allPos.length; i++) {
        if (posPot[i] > 0) {
          FieldList[i].Initialize();
        }
      }
    
      PVector firstTestPt = new PVector(width/2, height/2);
      testPt.add(firstTestPt.get());
      startPt.add(firstTestPt.get());
      ArrayList <PVector>testPtHistory = new ArrayList<PVector>();
      testPtHistory.add(firstTestPt);
      allTestPtHistory.add(testPtHistory);
      float firstTestPot = 0;
      for (int pos_i = 0; pos_i<allPos.length; pos_i++) {
        firstTestPot += 1/pow(PVector.dist(allPos[pos_i], firstTestPt), 2);
      }
    
      testPot.append(firstTestPot);
    
      boolean firstKeep = true;
      keepGoing.add(true);
    }
    
    void draw() {
    
      if (mousePressed) {
        PVector mouse = new PVector(mouseX, mouseY);
        for (int i  = 0; i < allPos.length; i++) {
          if (PVector.dist(mouse, allPos[i]) < 20) {
            allPos[i] = mouse;
          }
        }
      }
    
      calcul();
    
      if(exportPDF == true){
        beginRecord(PDF, "filename"+frameCount+".pdf");
      }
      if (drawFieldVec == true) {
        background(0);
        lineForce();
      }
      if (drawFieldPot) {
        background(0);
        colorGrid();
      }
    
    
      for (int i =0; i<allPos.length; i++) {
    
        if (posPot[i] > 0) {
          EMF Field = FieldList[i];
          Field.DoField();
        }
      }
    
      if (count < 30) {
        PVector newTestPt = new PVector(random(0, width), random(0, height));
        testPt.add(newTestPt.get());
        startPt.add(newTestPt.get());
    
        ArrayList <PVector>newTestPtHistory = new ArrayList<PVector>();
        newTestPtHistory.add(newTestPt);
        allTestPtHistory.add(newTestPtHistory);
        float newTestPot = 0;
        for (int pos_i = 0; pos_i<allPos.length; pos_i++) {
          newTestPot += 1/pow(PVector.dist(allPos[pos_i], newTestPt), 2);
        }
    
        testPot.append(newTestPot);
    
        boolean newKeep = true;
        keepGoing.add(newKeep);
        count++;
      }
    
    
      for (int main_i = 0; main_i < startPt.size (); main_i ++) {
        if (keepGoing.get(main_i) == true) {
    
    
          PVector currentTestPt = bestNeighbour(allTestPtHistory.get(main_i).get(allTestPtHistory.get(main_i).size()-1), testPot.get(main_i), allPos, allTestPtHistory.get(main_i));
          strokeWeight(5);
          stroke(255);
          point(currentTestPt.x, currentTestPt.y);
          allTestPtHistory.get(main_i).add(currentTestPt);
        }
    
        if (allTestPtHistory.get(main_i).size()>10 && PVector.dist(startPt.get(main_i), allTestPtHistory.get(main_i).get(allTestPtHistory.get(main_i).size()-1)) < 2) {
          strokeWeight(1);
          println("END");
    
          //fill(52, 161, 169, 10);
          noFill();
          strokeWeight(0.25);
          stroke(255);
          beginShape();
          for (int i =0; i < allTestPtHistory.get (main_i).size()-1; i++) {
            curveVertex(allTestPtHistory.get(main_i).get(i).x, allTestPtHistory.get(main_i).get(i).y);
          }
          endShape(CLOSE);
          keepGoing.set(main_i, false);
        }
      }
    
    
      drawPos();
    
      if(exportPDF == true){
        endRecord();
        exportPDF = false;
      }
    }
    
    
    
    void calcul () {
      magMax = -1000;
      magMin = 1000;
      for (int x = 0; x < width/res; x ++) {
        for (int y = 0; y < height/res; y ++) {
          PVector current = new PVector (x*res, y*res);
          sumForce[x][y] = new PVector();
    
    
          for (int i = 0; i < allPos.length; i ++) {
    
            PVector force = new PVector();
            PVector.sub(allPos[i], current, force);  
            float distance = force.mag();
            float magnitude = posPot[i]/pow(distance, 2);
            force.setMag(magnitude );
            sumForce[x][y].add(force);
          }
    
          displayMag[x][y] = sumForce[x][y].mag();
    
    
          if (displayMag[x][y] > magMax) {
            magMax = displayMag[x][y];
          }
          if (displayMag[x][y] < magMin) {
            magMin = displayMag[x][y];
          }
        }
      }
    }//---{/calcul}
    
    void lineForce() {
      for (int x = 0; x < width/res; x ++) {
        for (int y = 0; y < height/res; y ++) {
          sumForce[x][y].normalize();
          sumForce[x][y].mult(1.5);
          if (randomDisplay[x][y] == true) {
            stroke(Blue1);
            line(x*res, y*res, (x-sumForce[x][y].x)*res, (y-sumForce[x][y].y)*res);
            noStroke();
          }
        }
      }
    }//---{/lineforce}
    
    void colorGrid () {
    
      for (int x = 0; x < width/res; x ++) {
        for (int y = 0; y < height/res; y ++) {
          float coefMag = pow(displayMag[x][y], 0.05);
          float col = map(coefMag, pow(magMin, 0.05), pow(magMax, 0.05), 0, 1);
          stroke(lerpColor(0, Blue1, col));
          fill(lerpColor(0, Blue1, col));
    
          rect(x*res, y*res, res, res);
        }
      }
    }
    
    void drawPos () {
      for (int i  = 0; i < allPos.length; i++) {
    
        noStroke();
        if (posPot[i]>0) {
          fill(Red1);
        } else {
          fill(255);
        }
        float rad = map(posPot[i], -1, 1, 10, 20);
        ellipse(allPos[i].x, allPos[i].y, rad, rad);
    
        noFill();
        strokeWeight(1);
        if (posPot[i]>0) {
          stroke(Red1);
        } else {
          stroke(255);
        }
    
    
        float rad2 = map(posPot[i], -1, 1, 15, 27);
        ellipse(allPos[i].x, allPos[i].y, rad2, rad2);
      }
    }
    
    class EMF {
    
    
      PVector SourcePos;
      int subPosCount;
      float offsetFromSourcePos = 5;
      float coefSpeed = 10 ;
    
    
      //CONSTRUCTOR
    
      EMF( PVector _Pos) {
        SourcePos = _Pos;
        subPosCount = 20;
    
      }
    
      PVector [] subPos;// to store the particules
      PVector [] OtherPos = new PVector[posCount]; // to store the other "sources"
      ArrayList<PVector>[] subPosCrv; //to store the particule history
      boolean [] subPosCrvGuestList; // to determiner if subPosCrv have already be drawn
      boolean [] isReach; // have subPos isReach its goal ?
      boolean  isStatic = false ; // is subPos  angle static ?
    
      void Initialize() { 
    
        GetOtherPos();
        BeBorn();
      }//__________________________________________________ Initialize
    
      void DoField() {
        Magnetise();
      }//__________________________________________________ DoField
    
    
    
      void GetOtherPos() {
        for (int i = 0; i<allPos.length; i++) {
          OtherPos[i] = allPos[i];
        }
      }//__________________________________________________ GetOtherPos
    
      void BeBorn() {
        subPos = new PVector [subPosCount]; 
        subPosCrv = new ArrayList[subPosCount];
        subPosCrvGuestList = new boolean [subPosCount];
        isReach = new boolean [subPosCount];
        for (int i = 0; i<subPosCount; i++) {
    
          float _coef = map(i, 0, subPosCount, 0, PI*2);
          subPos[i] = new PVector (cos(_coef), sin(_coef));
          subPos[i].setMag(offsetFromSourcePos); // Set an Offset from BornPos
          subPos[i] = PVector.sub(SourcePos, subPos[i]);
          subPosCrv[i] = new ArrayList();
          subPosCrvGuestList[i] = false;
          isReach[i] = false;
          isStatic = false;
        }
      }//__________________________________________________ BeBorn
    
    
      void Magnetise() {
        PVector [][] subForces = new PVector [subPosCount][posCount];
        float [][] distSub2Pos = new float [subPosCount][posCount];
    
    
        for (int subPos_i = 0; subPos_i<subPosCount; subPos_i++) { //subPos
          isReach[subPos_i] = false;
          for (int OtherPos_i = 0; OtherPos_i<posCount; OtherPos_i++) {
            distSub2Pos[subPos_i][OtherPos_i] = PVector.dist(subPos[subPos_i], OtherPos[OtherPos_i]);
            if (distSub2Pos[subPos_i][OtherPos_i] < offsetFromSourcePos-0.1) isReach[subPos_i] = true;
          }
    
          if (subPos[subPos_i].x < 0  || 
            subPos[subPos_i].x > width  || 
            subPos[subPos_i].y < 0  || 
            subPos[subPos_i].y >height ) {
            isReach[subPos_i] = true;
          }
          if (isReach[subPos_i] == true) { 
             drawCrv(subPos_i); // draw the curve once subPos get out of the window or reach an attractor point
    
          } 
          else {
    
            PVector SumSubMove = new PVector();
    
            for (int OtherPos_i = 0; OtherPos_i<posCount; OtherPos_i++) {
              subForces[subPos_i][OtherPos_i] = PVector.sub(subPos[subPos_i], OtherPos[OtherPos_i]);
              distSub2Pos[subPos_i][OtherPos_i] = subForces[subPos_i][OtherPos_i].mag();
    
    
    
              //+++++++++++This is the core of magnetise function +++++++++++
              /* if (distSub2Pos[subPos_i][OtherPos_i] < birthControlDist) {
               float distMap = distSub2Pos[subPos_i][OtherPos_i];
    
               float subForcesMag = map(distMap, 0, birthControlDist, 1, subForces[subPos_i][OtherPos_i].mag());
               subForces[subPos_i][OtherPos_i].setMag((1/pow(subForcesMag,2))*coefSpeed);
               //subForces[subPos_i][OtherPos_i].limit(2);
               }
               else {*/
              float subForcesMag = subForces[subPos_i][OtherPos_i].mag();
              subForces[subPos_i][OtherPos_i].setMag((abs(posPot[OtherPos_i])/pow(subForcesMag, 2))*coefSpeed);
    
              // }
              //Set the attraction or repulsion
              subForces[subPos_i][OtherPos_i].mult(posPot[OtherPos_i]/abs(posPot[OtherPos_i]));
    
              SumSubMove.add(subForces[subPos_i][OtherPos_i]);
              //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
            }// end OtherPos loop
            SumSubMove.setMag(1);
            subPos[subPos_i].add(SumSubMove);
    
    
    
            subPosCrv[subPos_i].add(subPos[subPos_i].get()); // add to an ArrayList
    
          }
          drawEllipse(subPos_i);
    
        }// end subPos loop
      }//__________________________________________________ Magnetise
    
    
      void drawCrv(int subPos_i) {
    
       // if (subPosCrvGuestList[subPos_i] == false) { // has the curve already be drawn ?
    
          pushStyle();
          noFill();
          stroke(255);
          strokeWeight(2);
          beginShape();
    
          for (int subPosCrv_i = 0; subPosCrv_i<subPosCrv[subPos_i].size(); subPosCrv_i+=1) { //subPosCrv_i loop
            PVector currentSubPos = subPosCrv[subPos_i].get(subPosCrv_i);
            curveVertex(currentSubPos.x, currentSubPos.y);
          }//end subPosCrv_i loop
          endShape();
          popStyle();
    
    
          //subPosCrvGuestList[subPos_i] = true;
       // }// end guestList Test
      }//__________________________________________________drawCrv
    
    
    
    
    
    
    
      void drawEllipse(int subPos_i) {
        pushStyle();
        strokeWeight(0.5);
        noFill();
        point(subPos[subPos_i].x, subPos[subPos_i].y);
        //ellipse(subPos[subPos_i].x, subPos[subPos_i].y, 2, 2);
        popStyle();
    
      }//__________________________________________________drawEllipse
    }//EndOfClass
    
    
    PVector bestNeighbour(PVector ptToTest, float potToTest, PVector[]sourcePos, ArrayList<PVector>History) {
      float [] potPool = new float [8];
      for (int ngh = 0; ngh< neighborsX.length; ngh++) {
        PVector myNgh = new PVector (neighborsX[ngh], neighborsY[ngh]);
        myNgh.setMag(1);
        myNgh.add(ptToTest);
        // println(myNgh, ngh);
        float tempPot = 0;
        for (int pos_i = 0; pos_i<allPos.length; pos_i++) {
          tempPot += 1/pow(PVector.dist(allPos[pos_i], myNgh), 2);
        }
        //println(tempPot);
        potPool[ngh] = tempPot;
      }
      PVector _currentPoint;
      PVector _currentTan;
      if (History.size()>2) {
        _currentPoint = ptToTest;
        _currentTan = _currentPoint.get();
        _currentTan.sub(History.get(History.size()-2));
      } else {
        _currentTan = new PVector (0, 0);
      }
      _currentTan.normalize();
    
      //println(PVector.dot(currentTan, previousTan));
      //if (PVector.dot(currentTan, previousTan)>=0) {
    
    
    
      float bestDeltaPot = 1000;
      PVector bestNgh = new PVector(0, 0, 0);
      int bestIndex = -1;
      for (int pot_i = 0; pot_i <neighborsX.length; pot_i ++) {
        //  println(potPool[pot_i]-potToTest, pot_i);
    
        if (abs(potPool[pot_i]-potToTest) < bestDeltaPot) {
          PVector _nextTan = new PVector(neighborsX[pot_i], neighborsY[pot_i]) ;
          _nextTan.normalize();
          boolean shouldI = true;
          if (History.size()>2) {
            if (PVector.dot(_currentTan, _nextTan)>=0) {
              for (int i = 0; i< History.size (); i++) {
                if (neighborsX[pot_i]+ptToTest.x == History.get(i).x && neighborsY[pot_i]+ptToTest.y == History.get(i).y) {
                  shouldI = false;
                }
              }
              if (shouldI == true) {
                bestNgh  =  new PVector (neighborsX[pot_i], neighborsY[pot_i]);
                bestDeltaPot = abs(potPool[pot_i]-potToTest);
                bestNgh.add(ptToTest);
                bestIndex = pot_i;
              }
            }
          } else {
            for (int i = 0; i< History.size (); i++) {
              if (neighborsX[pot_i]+ptToTest.x == History.get(i).x && neighborsY[pot_i]+ptToTest.y == History.get(i).y) {
                shouldI = false;
              }
            }
            if (shouldI == true) {
              bestNgh  =  new PVector (neighborsX[pot_i], neighborsY[pot_i]);
              bestDeltaPot = abs(potPool[pot_i]-potToTest);
              bestNgh.add(ptToTest);
              bestIndex = pot_i;
            }
          }
        }
      }
      //println(bestIndex);
      return bestNgh;
    }
    
    
    void keyPressed() {
    
      if (key == 'q' || key == 'Q') { 
        drawFieldVec = true;
        drawFieldPot = false;
      }
      if (key == 'a' || key == 'A') {
        drawFieldVec = false ;
        drawFieldPot = true ;
      }
       if (key == 'e' || key == 'E') {
         exportPDF = true;
       }
    }
    
    
    color Blue1 = color(52, 161, 169);
    color Blue2 = color(41,113,118);
    color Green = color(18,220,120);
    color Red1 = color(224, 55, 74);
    color Red2 = color(169, 47, 121);
    
  • When you use a Particle system you can visualize the flow of the electric field.

    Adapted Code Example

    int cpx=500, cpy=350;
    int qp=1000, qn=1000;
    float x, y, dx, dy, dxn, dyn;
    float d1, E1, E1x, E1y, d2, E2, E2x, E2y;
    float EEx, EEy, EE, deltax, deltay;
    float ll = 0.5;
    ArrayList <Particle> particles = new ArrayList <Particle> ();
    
    void setup() {
      size(1000, 700, P2D);
      smooth(16);
      background(255);
      strokeWeight(0.75);
      while (particles.size () < 20000) { particles.add(new Particle()); }
    }
    
    void draw() {
      if (frameCount % 5 == 0) {
        noStroke();
        fill(255, 15);
        rect(0, 0, width, height);
      }
      stroke(0, 128);
      for (Particle p : particles) {
        p.run();
      }
    }
    
    class Particle {
      PVector loc;
    
      Particle() {
        loc = new PVector(random(width), random(height));
      }
    
      void run() {
        if (loc.x > width || loc.x < 0 || loc.y > height || loc.y < 0) {
          loc = new PVector(random(width), random(height));
        } else {
          loc.add(getDirection(loc));
          point(loc.x, loc.y);
        }
      }
    
      PVector getDirection(PVector p) {
        dx=p.x-cpx; 
        dy=p.y-cpy;
        d1=sqrt(dx*dx+dy*dy);
        E1=qp/(d1*d1);
        E1x=dx*E1/d1;
        E1y=dy*E1/d1;
    
        E2x=0.016;
        E2y=0;
    
        EEx=E1x+E2x;
        EEy=E1y+E2y;
        EE=sqrt(EEx*EEx+EEy*EEy);
    
        deltax=ll*EEx/EE;
        deltay=ll*EEy/EE;
        return new PVector(deltax, deltay);
      }
    }
    
  • Look like the magnetic field of the earth :p

  • Thanks for your contributions. As a matter of fact, these are my first attempts with Processing (and with Java as well) and I have a lot to learn. If I try to run "amnon code", I get "Processing cannot run because GLSL shaders are not available"; if I try to run "sus code" I get "the method append(int) in the type FloatList is not applicable for the arguments (float). I don't know if submitting my naive experiments in the "Share your work" section is a good idea; I'm a beginner and the section is probably designed for more skilled people. Thanks a lot anyway ... I'll learn

  • edited June 2014

    Which Processing version are you using? In @amnon's code, replace P2D by JAVA2D @ line #10.

    P.S.: Mine's v2.0.2. It's far from the latest version, but it's enough to run both codes!

  • My version is 2.0b8 (time to get a more recent one?). I replaced P2D with JAVA2D and ... it worked fine. Thank you GoToLoop !

  • edited June 2014

    Then you are using a really old beta version.

    I would strongly advise you to download the latest version: 2.2.1 (19 May 2014)

  • Amazing! :)

  • Article deserves pictures. I modified "Adapted Code Example" to assign random color for each particle via:

      colorMode(HSB,200,200,200,200); // in setup
    

    and

      Particle() {
        loc = new PVector(random(width), random(height));
          c = color(random(100),random(200),random(200),random(200)); //<===
      }
    
      void run() {
        if (loc.x > width || loc.x < 0 || loc.y > height || loc.y < 0) {
          loc = new PVector(random(width), random(height));
          c = color(random(100),random(200),random(200),random(200));//<===
        } else {
          loc.add(getDirection(loc));
          stroke(c);                                                       //<===
          point(loc.x, loc.y);
        }
      }
    

    and changed

       E2x=0.032; //  <== 0.016;
    

    electirc-field-pattern3

  • Another image with

      c = color(random(100),random(200),random(100),random(20));
    

    electric-field-charge4

  • matured

    electric-field-charge6

  • Really nice work. You should check if you can pen plot it somewhere.

  • Really beautiful! Thanks jas0501.

Sign In or Register to comment.