Save mouse coordinates and draw arrows with it

Im working on a program that draws arrows with the mouse, so for the tip of the arrow to be pointing in the right direction Im using PVector (one for the base and one for the tip of the arrow). I made it work so you can draw one arrow and it stays in the screen, but the second arrow and third etc is drawn in a completely wrong place, looks like the coordinates are not being passed correctly to the function. Does anyone know what is wrong with my approach to this problem?

PVector arrowTip = new PVector(); //for drawing arrows
PVector lineBase = new PVector(); //for drawing arrows

//save drawn arrow value for drawing saved arrows
PVector [] base = new PVector[100];
PVector [] vec = new PVector[100];
PVector vector = new PVector();
boolean drawing;
float xx,yy;


int flag=0;


void settings() {
  float hg=displayHeight/1.1;
  int wd=(int)hg*10/8;
  size(wd, (int)hg);
  drawing=false;
}

void draw() {
  background(255);

  //draw arrows
   if (flag == 1) {
   
   arrowTip.x = mouseX;
   arrowTip.y = mouseY;
   drawArrow(lineBase, arrowTip.sub(lineBase));
   }
   
  
  if (flag==1) {
    arrowTip.x = mouseX;
    arrowTip.y = mouseY;
  }
  
  //new
  drawSavedArrows();
}

//new
void drawSavedArrows() {
  for (int i =0; i<base.length; i++) {
    if (vec[i]!=null && base[i]!=null) {
      //draw saved arrow
      xx=vec[i].x;
      yy=vec[i].y;
      vector.x=xx;
      vector.y=yy;
      drawArrow(base[i], vector.sub(base[i]));//this is not working, the relative o,o coor seem to be stuck on the first one saved
    }
  }
}


void drawArrow(PVector base, PVector vector) {

  strokeWeight(height / 50);
  fill(20, 85, 30, 180);
  stroke(20, 85, 30, 180);
  translate(base.x, base.y); //set relative 0,0 coor
  line(0, 0, vector.x, vector.y); //draw line from relative 0,0 to mouse
  rotate(vector.heading());
  int arrowSize = height / 20;
  translate(vector.mag() - arrowSize, 0); //length of vec minus arrowsize relative
  triangle(0, arrowSize / 1.5, 0, -arrowSize / 1.5, arrowSize, 0);
}


void mousePressed() {
  if (mouseButton == RIGHT) //right click for drawing arrows
  {
    lineBase.x = pmouseX; //get the coor for the staring point of the arrow
    lineBase.y = pmouseY;


    //save base vector to first null
    for (int i =0; i<base.length; i++) {
      if (base[i]==null && vec[i]==null) {

        base[i] = new PVector();
        base[i].x=pmouseX;
        base[i].y=pmouseY;
        break;
      }
    }
    drawing=true;
  } else if(mouseButton == LEFT){
    for (int i=0; i<base.length; i++) {     //delete all vectors
      if (base[i]==null) {
        break;
      }
      base[i]=null; 
      vec[i]=null;
    }
  }
} 


void mouseDragged() {
  if (mouseButton == RIGHT) {
    flag = 1;
  }
}
void mouseReleased() {
  flag = 0;
  if (drawing) {
    for (int i =0; i<vec.length; i++) {
      if (vec[i]==null) {

        vec[i] = new PVector();//save coor for arrow tip
        vec[i].x=arrowTip.x;
        vec[i].y=arrowTip.y;
        break;
      }
    }
  }
  drawing=false;
}

Be careful, translate is cumulative!
So this:

translate(100, 300);

is the same as this:

translate(50, 150);
translate(50, 150):

If you draw more than 1 arrow, the first one is drawn correctly because you call translate only once, but for the second you already called translate once, so you are actually adding another translate on top of the one you have already done.

You can isolate the effect of the transformation using push() and pop(). All you have to do is update your drawArrow() function like so:

void drawArrow(PVector base, PVector vector) {
  push();
  strokeWeight(height / 50);
  fill(20, 85, 30, 180);
  stroke(20, 85, 30, 180);
  translate(base.x, base.y); //set relative 0,0 coor
  line(0, 0, vector.x, vector.y); //draw line from relative 0,0 to mouse
  rotate(vector.heading());
  int arrowSize = height / 20;
  translate(vector.mag() - arrowSize, 0); //length of vec minus arrowsize relative
  triangle(0, arrowSize / 1.5, 0, -arrowSize / 1.5, arrowSize, 0);
  pop();
}

oh, that is all I needed to know! thank you so much

1 Like