Repositioning my bird character

Hello @CharrR,

One way to think about it is to realize that everything you are drawing is based on an origin point.
When you say:

ellipse(40, 20, 3, 3);

You are saying that you want to draw an ellipse center 40 pixels on the right of the origin and 20 pixels under the origin.
And of course the origin is the top right of your screen.

Now let’s say you want instead to draw the ellipse at the position (60, 50). Of course you can simply write:

ellipse(60, 50, 3, 3);

But in that case we are back at your issue to have to rewrite everything.

What if instead we move our origin point?
As you can see, that ellipse is 20 pixels more on the right and 30 pixels more down than the previous one (40 + 20 = 60 and 20 + 30 = 50).
So drawing the previous ellipse at the same “position” from the origin but moving the origin by (20, 30) would be a solution.

One way to achieve it is to write our own function

void drawEllipseFromOrigin(float x, float y) {
  ellipse(x + 60, y + 50, 3, 3);
}

With that function the following code would draw the 2 ellipses where we wanted them:

drawEllipseFromOrigin(0, 0) // The first ellipse at position (40, 20)
drawEllipseFromOrigin(20, 30) // The second ellipse at position (60, 50)

Now imagine that instead of having 1 ellipse you have several lines, and ellipses and arc like in your bird. Then every elements would be translated and you would just need to write in only once:

void setup() {
  size(500, 500);
  background(102, 178, 255); 
  scale(0.70);
  drawBird(0, 0);
  drawBird(400, 200);
}

void drawBird(float x, float y) {
  
  strokeWeight(1.5);
  fill(0, 153, 120);
  line(x + 50, y + 381, x + 300, y + 381);
  
  /*Right Leg*/
  line(x + 150, y + 220, x + 190, y + 300);
  line(x + 190, y + 300, x + 170, y + 380);
  arc(x + 176, y + 380, 20, 18, PI, TWO_PI, CLOSE);

  fill(250, 200, 100);

  /*body and head*/
  arc(x + 140, y + 180, 150, 150, 0, PI, CLOSE);
  arc(x + 220, y + 180, 50, 50, 0, 2*PI, CLOSE);

  /*left Leg*/
  fill(0, 153, 120);
  line(x + 120, y + 220, x + 150, y + 300);
  line(x + 150, y + 300, x + 110, y + 380);
  arc(x + 118, y + 380, 20, 18, PI, TWO_PI, CLOSE);

  /*eye*/
  fill(255);
  ellipse(x + 225, y + 175, 20, 20);
  fill(0, 0, 153);
  ellipse(x + 227, y + 174, 10, 10);
  fill(255);
  ellipse(x + 229, y + 175, 5, 5);

  /*Lashes*/
  fill(1);
  strokeWeight(2);
  line(x + 220, y + 165, x + 218, y + 160);
  line(x + 226, y + 165, x + 226, y + 158);
  line(x + 232, y + 166, x + 235, y + 162);

  /*Beak*/
  triangle(x + 236, y + 190, x + 232, y + 200, x + 247, y + 200);

  /*Antena*/
  noFill();
  strokeWeight(1);
  arc(x + 258, y + 148, 70, 85, 2.95, TWO_PI);
  arc(x + 288, y + 146, 10, 14, 0, TWO_PI);

  /*Tail*/
  strokeWeight(1);
  fill(255, 153, 153);
  triangle(x + 6, y + 180, x + 60, y + 120, x + 70, y + 180);
  fill(100, 180, 100);
  triangle(x + 12, y + 178, x + 58, y + 126, x + 68, y + 180);
  fill(0, 204, 204);
  triangle(x + 18, y + 176, x + 56, y + 132, x + 68, y + 180);
  fill(250, 200, 100);
  triangle(x + 24, y + 174, x + 54, y + 138, x + 70, y + 180);

  /*wings*/
  strokeWeight(1.5);
  fill(255, 170, 51);
  arc(x + 150, y + 190, 80, 70, 0, PI, CLOSE);
  strokeWeight(2);
  line(x + 126, y + 216, x + 134, y + 210);
  line(x + 144, y + 223, x + 146, y + 212);
  line(x + 164, y + 222, x + 156, y + 212);
}

Now this works but as you can see, there is a lot of x + and y +: it is easy to make a mistake, forget one etc. and it is not easy to read.

To simplify our life, we can use, as you said the translate() function. The idea is exactly the same as what we did (moving the origin point) but instead of adding manually the x + and y +, it does it automatically for us:

void setup() {
  size(500, 500);
  background(102, 178, 255); 
  scale(0.70);
  drawBird(0, 0);
  drawBird(400, 200);
}

void drawBird(float x, float y) {
  pushMatrix();
  translate(x, y);
  
  strokeWeight(1.5);
  fill(0, 153, 120);
  line( 50, 381, 300, 381);

  /*Right Leg*/
  line( 150, 220, 190, 300);
  line( 190, 300, 170, 380);
  arc( 176, 380, 20, 18, PI, TWO_PI, CLOSE);

  fill(250, 200, 100);

  /*body and head*/
  arc( 140, 180, 150, 150, 0, PI, CLOSE);
  arc( 220, 180, 50, 50, 0, 2*PI, CLOSE);

  /*left Leg*/
  fill(0, 153, 120);
  line( 120, 220, 150, 300);
  line( 150, 300, 110, 380);
  arc( 118, 380, 20, 18, PI, TWO_PI, CLOSE);

  /*eye*/
  fill(255);
  ellipse( 225, 175, 20, 20);
  fill(0, 0, 153);
  ellipse( 227, 174, 10, 10);
  fill(255);
  ellipse( 229, 175, 5, 5);

  /*Lashes*/
  fill(1);
  strokeWeight(2);
  line( 220, 165, 218, 160);
  line( 226, 165, 226, 158);
  line( 232, 166, 235, 162);

  /*Beak*/
  triangle( 236, 190, 232, 200, 247, 200);

  /*Antena*/
  noFill();
  strokeWeight(1);
  arc( 258, 148, 70, 85, 2.95, TWO_PI);
  arc( 288, 146, 10, 14, 0, TWO_PI);

  /*Tail*/
  strokeWeight(1);
  fill(255, 153, 153);
  triangle( 6, 180, 60, 120, 70, 180);
  fill(100, 180, 100);
  triangle( 12, 178, 58, 126, 68, 180);
  fill(0, 204, 204);
  triangle( 18, 176, 56, 132, 68, 180);
  fill(250, 200, 100);
  triangle( 24, 174, 54, 138, 70, 180);

  /*wings*/
  strokeWeight(1.5);
  fill(255, 170, 51);
  arc( 150, 190, 80, 70, 0, PI, CLOSE);
  strokeWeight(2);
  line( 126, 216, 134, 210);
  line( 144, 223, 146, 212);
  line( 164, 222, 156, 212);
  
  popMatrix();
}

If you want more info about the translate() function, I advise you to go read this post where I explain it a bit more in depth:

3 Likes