Scaling in a vector field plot

edited July 2016 in Questions about Code

Hello! In an attempt to familiarize myself with some of the basics of Processing, I'm working on some code to make a 2-D vector field. I wrote a Vector class (which stores the magnitude and direction of a Vector) and a VectorField class (which plops down all the vectors according to some hard-coded function. Here is f(x,y)=(x,-y): Screen Shot 2016-07-05 at 11.40.02 AM One of the difficulties I'm is figuring out how to scale the vectors so that they don't overlap with one another. My initial idea was to pick a grid size (say, 25x25) and scale the entire canvas down to that grid size. This works decently well, except when a vector is bigger than the canvas! Here's the previous shot with the 25x25 grid turned on: Screen Shot 2016-07-05 at 11.39.47 AM Not perfect, but not awful. It's not hard to really break the code - we just have to make the vectors sufficiently large. Here is f(x,y)=(1000,1000): Screen Shot 2016-07-05 at 11.43.15 AM Too much overlap! :-O

Is there a clever-er way I can scale the vectors so that this doesn't happen? Here's my code in it's entirety (edit: not sure how to include my code without it getting truncated):

    
    VectorField VF;
    void setup() {
      size(750, 750);  
      VF = new VectorField(25.0, true); // true => grid is ON
    }
    void draw() {
      background(255);
      VF.draw();
    }
    class Vector {
      float magnitude, direction, xPos, yPos;
      Vector(float mag, float dir, boolean polar) {
        if (polar) { // polar coordinates
          magnitude = mag;
          direction = dir;
          xPos = magnitude*cos(direction);
          yPos = magnitude*sin(direction);
        } else { // if polar is false, just use (mag,dir) as (x,y)
          xPos=mag;
          yPos=dir;
          magnitude = sqrt(xPos*xPos+yPos*yPos);
          direction = atan2(yPos, xPos);
        }
      }
      void draw() {
        stroke(0);
        line(0, 0, xPos, yPos);
        pushMatrix();
        translate(xPos, yPos);
        rotate(direction);
        fill(0);
        triangle(1*magnitude/10, 0, 0, -1*magnitude/10, 0, 1*magnitude/10); // arrow head
        popMatrix();
      }
    }
    class VectorField {
      Vector[][] VF;
      float gridSize, scaleX, scaleY;
      int n, m;
      boolean drawGrid;
      VectorField(float grid, boolean draw) {
        gridSize=grid;
        scaleX=gridSize/width;
        scaleY=gridSize/height;
        n=floor(width/gridSize);
        m=floor(height/gridSize);
        VF = new Vector[n][m];
        drawGrid=draw;
      }
      void draw() {
        for (int i = 0; i < n; i++) {
          for (int j = 0; j < m; j++) {
            pushMatrix();
            VF[i][j] = new Vector(1000, 1000, false); // f(x,y)=(1000,1000)
            //          VF[i][j] = new Vector(i*gridSize,-j*gridSize,false); // f(x,y)=(x,-y)
            scale(scaleX, scaleY);
            translate(i*width, j*height);
            VF[i][j].draw();
            popMatrix();
          }
        }
        if (drawGrid) { // draw the grid?
          stroke(255, 0, 0);
          for (int i=0; i
Tagged:

Answers

  • find the largest of the vectors, work out how to scale that so that it fits, scale everything using the same scale factor.

    and look at PVector

  • Thanks, koogs. That's a good idea. It looks like Mathematica has a few ways of dealing with this, which makes me think that every method is somewhat of a compromise.

    I know a bit about PVector but don't see how it will be useful in this scenario. Are you suggesting that I have my Vector class inherit from them?

Sign In or Register to comment.