Problem with rotating of objects

PerPer
edited April 2018 in Questions about Code

I got this square with four points Im looping and connecting with lines. My idea was to create rectangles and place them over the lines to be able to use different fills such as lerp etc.

Im getting the distance between the different vectors and are using that as length of the rectangles. Then my idea was to calculate the angle between the different points and use that for rotating each rectangle into place but my rotation get messed up.

Any hint for solving this?

PVector[] loc = new PVector[4];

void setup() { 
  size(500, 500);  
  background(255);
  loc[0] = new PVector(100, 100);
  loc[1] = new PVector(400, 100);
  loc[2] = new PVector(100, 400);
  loc[3] = new PVector(400, 400);

  fill(100);
  stroke(200);

  for (int i = 0; i < loc.length; i++) {
    strokeWeight(1);
    ellipse(loc[i].x, loc[i].y, 10, 10);

    for (int j=i+1; j < loc.length; j++) {
      strokeWeight(2);
      stroke(2);

      line(loc[i].x, loc[i].y, loc[j].x, loc[j].y);

      float distance = loc[i].dist(loc[j]);

      float a = PVector.angleBetween(loc[i], loc[j]);

      pushMatrix();
      noFill();
      strokeWeight(2);
      stroke(1);
      rectMode(CENTER);
      rotate(a);
      rect(loc[i].x, loc[i].y, distance,10);

      popMatrix();
    }
  }
}

void draw() {
}

Thanks

Answers

  • I assume this will help.

    PVector[] loc = new PVector[4];
    
    void setup() { 
      size(500, 500);  
      background(255);
      loc[0] = new PVector(100, 100);
      loc[1] = new PVector(400, 100);
      loc[2] = new PVector(100, 400);
      loc[3] = new PVector(400, 400);
    
      fill(100);
      stroke(200);
    
      for (int i = 0; i < loc.length; i++) {
        strokeWeight(1);
        ellipse(loc[i].x, loc[i].y, 10, 10);
    
        for (int j=0; j < loc.length; j++) {
          strokeWeight(2);
          stroke(2);
    
          line(loc[i].x, loc[i].y, loc[j].x, loc[j].y);
    
          float distance = loc[i].dist(loc[j]);
    
          float a = PVector.angleBetween(loc[i], loc[j]);
    
          pushMatrix();
          noFill();
          strokeWeight(2);
          stroke(1);
          rectMode(CENTER);
          translate(loc[i].x, loc[i].y);
          rotate(a);
          rect(0,0, distance,10);
          popMatrix();
        }
      }
    }
    
    void draw() {
    }
    

    Notice that the translate call moves the origin to the corner of the main square. This is then the point that rotation happens around.

  • PerPer
    edited April 2018

    The translate can push them into place, even though it´s not at the correct place :). But it doesnt solve the rotation where the angles is a bit messed up. I made the window a bit bigger so it´s easierto see.

    (Need to keep this line though. Otherwise you get to many and duplicate rects) for (int j=i+1; j < loc.length; j++) {

    PVector[] loc = new PVector[4];
    
    void setup() { 
      size(1000, 1000);  
      background(255);
      loc[0] = new PVector(300, 300);
      loc[1] = new PVector(700, 300);
      loc[2] = new PVector(300, 700);
      loc[3] = new PVector(700, 700);
    
      fill(100);
      stroke(200);
    
      for (int i = 0; i < loc.length; i++) {
        strokeWeight(1);
        ellipse(loc[i].x, loc[i].y, 10, 10);
    
        for (int j=i+1; j < loc.length; j++) {
          strokeWeight(2);
          stroke(2);
    
          line(loc[i].x, loc[i].y, loc[j].x, loc[j].y);
    
          float distance = loc[i].dist(loc[j]);
    
          float a = PVector.angleBetween(loc[i], loc[j]);
    
          pushMatrix();
          noFill();
          strokeWeight(2);
          stroke(1);
          rectMode(CORNER);
          translate(loc[i].x, loc[i].y);
          rotate(a);
          rect(0,0, distance,10);
          popMatrix();
        }
      }
    }
    
    void draw() {
    }
    
  • Demo below. Choosing the proper reference will make things a bit easier. The order of the vectors in the function matter.

    Kf

    PVector[] loc = new PVector[4];
    
    void setup() {
      size(1000, 1000); 
    
      loc[0] = new PVector(300, 300);
      loc[1] = new PVector(700, 300);
      loc[2] = new PVector(700, 700);
      loc[3] = new PVector(300, 700);
    
      fill(100);
      stroke(50);
      //strokeWeight(2);
      rectMode(CENTER);
    }
    
    void draw() {
      background(255);
      for (int j=1; j < loc.length; j++) {
        //line(loc[j-1].x, loc[j-1].y, loc[j].x, loc[j].y);
        drawRectLine(loc[j-1], loc[j], color(0, 0, 250));
      }
      line(loc[3].x, loc[3].y, loc[0].x, loc[0].y);  //Close the shape
    
      drawRectLine(loc[0], loc[2], color(10, 255, 0));
      drawRectLine(loc[1], loc[3], color(250, 100, 0));
    }
    
    void drawRectLine(PVector u, PVector v, color c) {
    
    
      PVector centroid =PVector.add(u, PVector.sub(v, u).mult(0.5)); 
      PVector aux=PVector.sub(v, u);
    
      pushMatrix();
      translate(centroid.x, centroid.y);
      //ellipse(0, 0, 15, 15);
      float a = PVector.angleBetween(new PVector(1, 0), aux);//aux.mag();
      rotate((a));
      fill(c);
      rect(0, 0, aux.mag(), 10);
      popMatrix();
    }
    
  • Ah, sorry, I didn't properly understand that/how you wanted to connect them. Hopefully Kf's post helped you more.

  • Thanks! That worked. Just for me to understand. I translated your sketch to "my own words". I get the angles right this time but the image is not kept together.

    I understand this: PVector aux=PVector.sub(loc[i], loc[j]); subtracts the two vectors

    But what exactly does the new vector(1,0) do? float a = PVector.angleBetween(new PVector(1,0), aux);//aux.mag();

    how can I edit my sketch for keeping the lines in place with the method below?

    PVector[] loc = new PVector[4];
    
    void setup() { 
      size(1000, 1000);  
      background(255);
      loc[0] = new PVector(300, 300);
      loc[1] = new PVector(700, 300);
      loc[2] = new PVector(300, 700);
      loc[3] = new PVector(700, 700);
    
      fill(100);
      stroke(200);
    
      for (int i = 0; i < loc.length; i++) {
        strokeWeight(1);
        ellipse(loc[i].x, loc[i].y, 10, 10);
    
        for (int j=i+1; j < loc.length; j++) {
          strokeWeight(2);
          stroke(2);
    
           //line(loc[i].x, loc[i].y, loc[j].x, loc[j].y);
    
          //float a = PVector.angleBetween(loc[i], loc[j]);
          float distance = loc[i].dist(loc[j]);
    
          // subtracts the two vectorsa
          PVector aux=PVector.sub(loc[i], loc[j]);
    
          pushMatrix();
          translate(loc[i].x, loc[i].y);
          noFill();
          strokeWeight(2);
    
          // what exactly does the new vector do? 
          float a = PVector.angleBetween(new PVector(1,0), aux);//aux.mag();
          rotate(a);
          rect(0, 0, distance, 10);
          popMatrix();
        }
      }
    }
    
    void draw() {
    }
    
  • A line is between two points.

    The angle is with respect to certain reference frame.

    Most people use cartesian: x is positive to the right (with respect to 0,0) and Y is positive up

    In Processing Y is positive down (left handed ref frame?)

    It doesn't matter, we just need a way to measured the angle consistently.

    Step 1: Choose your reference point. I translate my reference from 0,0 in my sketch to the first vector

    Step2: Calculate the second vector based with respect to the first vector. Here I used subtract

    Step 3: Measured the angle. In my cartesian way of thinking this... I chose vector (1,0) aka. the positive x axis with respect to my first vector.

    NOTE:

    What is wrong with angleBetween(v,u);

    Nothing wrong. You are just measuring something that is not in a cartesian frame. Actually, you are measuring the angle between both vectors, both vectors measured from the 0,0 point in your sketch.

    Kf

  • Thanks! That makes sense.

    I have now also edit my sketch, changed the translate index to: translate(loc[j].x, loc[i].y); so now Im getting all the rectangles in the right place.

    Thanks for your help with the rotation!

    PVector[] loc = new PVector[4];
    int index = 0;
    color[] col = {  color(255, 0, 0), color(0, 255, 0), color(0, 0, 255), color(0, 0, 0), color(255), color(125)};
    
    void setup() { 
      size(1000, 1000);  
      background(255);
      loc[0] = new PVector(300, 300);
      loc[1] = new PVector(700, 300);
      loc[2] = new PVector(300, 700);
      loc[3] = new PVector(700, 700);
    
      stroke(200);
    
      for (int i = 0; i < loc.length; i++) {
        strokeWeight(1);
        ellipse(loc[i].x, loc[i].y, 10, 10);
    
        for (int j=i+1; j < loc.length; j++) {
          strokeWeight(2);
          stroke(2);
    
          //float a = PVector.angleBetween(loc[i], loc[j]);
          float distance = loc[i].dist(loc[j]);
    
          // subtracts the two vectors
          PVector aux=PVector.sub(loc[i], loc[j]);
    
          pushMatrix();
          translate(loc[j].x, loc[i].y);
          fill(col[index]);
    
          println(index + "  posX: " + loc[j].x + "  posY: "+ loc[i].y);
          strokeWeight(2);
          float a = PVector.angleBetween(new PVector(1, 0), aux);//aux.mag();
          rotate(a);
          rect(0, 0, distance, 10);
          popMatrix();
    
          index++;
        }
      }
    }
    
    void draw() {
    }
    
Sign In or Register to comment.