Rotate multiple geometric shape together

Hi!

Lets say i layered a triangle over an ellipse to make a fish doodle. I have a class named Fish and a function to display it on screen. If i want to rotate that fish so that it points toward the direction it’s going, how to I do that? Doing a function that would do that seem really complicated since the ellipse and the triangle will need to be treated separately…

Is there another way of making a fish (or a fly, or anything else) so that it’s easier to rotate the whole thing?

Thanks!

Yes. Start by drawing it so the point that it rotates around is at (0,0). For a fish shape, that looks like this:

void setup(){
  size(600,400);
  fill(255);
  noStroke();
}

void draw(){
  background(0);
  fish();
}

void fish(){
  ellipseMode(CENTER);
  ellipse(0,0,40,40);
  triangle(0,0,40,-20,40,20);
}

Notice that this puts your thing mostly off screen, since it’s in the top left corner by default. This is easily fixed by a translate() call:

void setup(){
  size(600,400);
}

void draw(){
  background(0);
  translate(mouseX, mouseY);
  fish();
}

void fish(){
  ellipseMode(CENTER);
  noStroke();
  fill(200,100,50);
  ellipse(0,0,40,40);
  triangle(0,0,40,-20,40,20);
  fill(255);
  ellipse(-10,-10,10,10);
  fill(0);
  ellipse(-13,-10,5,5);
  stroke(0);
  line(-10,10,-5,5);
}

Then you do this.

PVector fishPosition;
PVector fishVelocity;

void setup() {
  size(600, 400);
  fishPosition = new PVector( random(width), random(height), 0 );
  fishVelocity = new PVector( random(-5, 5), random(-5, 5), 0 );
}

void draw() {
  background(0,0,200);
  fish();
}

void fish() {

  // Move fish.
  fishPosition.add( fishVelocity );

  // Contain fish to sketch window.
  if ( fishPosition.x < 0 ) {
    fishPosition.x = 0;
    fishVelocity.x *= -1;
  }
  if ( fishPosition.y < 0 ) {
    fishPosition.y = 0;
    fishVelocity.y *= -1;
  }
  if ( fishPosition.x > width ) {
    fishPosition.x = width;
    fishVelocity.x *= -1;
  }
  if ( fishPosition.y > height ) {
    fishPosition.y = height;
    fishVelocity.y *= -1;
  }

  // Save space's orientation.
  pushMatrix();

  // Position fish.
  translate( fishPosition.x, fishPosition.y );

  // Point fish in direction of movement.
  rotate( atan2( fishVelocity.y, fishVelocity.x ) + PI ); // Add PI because the fish swims left!

  // Flip fish if moving right.
  if( fishVelocity.x > 0 ){
    scale(1,-1);
  }

  // Draw fish.
  ellipseMode(CENTER);
  noStroke();
  fill(200, 100, 50);
  ellipse(0, 0, 40, 40);
  triangle(0, 0, 40, -20, 40, 20);
  fill(255);
  ellipse(-10, -10, 10, 10);
  fill(0);
  ellipse(-13, -10, 5, 5);
  stroke(0);
  line(-10, 10, -5, 5);
  line(30, 0, 40, 0);
  line(30, 10, 40, 14);
  line(30, -10, 40, -14);
  line(30, 5, 40, 7);
  line(30, -5, 40, -7);

  // restore the saved orientation.
  popMatrix();

}

void mousePressed() {
  fishVelocity = new PVector( random(-5, 5), random(-5, 5), 0 );
}

It’s a fish.

I wish I could explain this magic to you but I haven’t had any coffee yet. Maybe you could try to understand it yourself and ask questions about things you don’t get?

2 Likes

Thanks again for your help!

I think I understood pretty much everything with your example!

My fishes are now constrain to their lake and pointing toward the direction they’re moving to! I make them move randomly using a PVector of acceleration and perlin noise. My next goal is to figure out how to make them react more naturally when they touch the side of a lake!

But enough for today, thanks again!