user21270064
user21270064

Reputation: 43

How to rotate an object made of multiple shapes from its center?

I would like to be able to rotate my turkey made up of many shapes from its center point using the rotate() function on a keypress. In practice you would be able to rotate the turkey slowly in circles either to either the left or right using the arrow keys. The turkey's position would not be changing since it rotates from the center, but it is simply rotated in the truest sense.

My problem at the moment though is that I don't know how to rotate the entire shape from its exact center, rather than around a random point. So how would I go about setting a single point to rotate from for each shape?

Here is my current code:

let bubbles=[];  //arrayList

function setup() {
  createCanvas(windowWidth, windowHeight);
  angleMode(DEGREES);
  speedX=random(1,3);
  speedY=random(1,2);
}

function mouseDragged() {
  let a=bubbles.length;
  bubbles.pop(a);
}



function mousePressed() {
  let d=random(10,50);
  let w=random(50, 180);
  let b=new Bubble(mouseX,mouseY,d, w);
  bubbles.push(b);
}

function draw() {
  background(255);
  for (let bubble of bubbles) {
    bubble.move(); 
    bubble.show();
  }
}

class Bubble {
  
  constructor(x,y,d,w) {
    this.x=x;
    this.y=y;
    this.d=d;
    this.speedX=random(15, 15);
    this.speedY=random(15, 15);
    this.d=random(0.5, 1.5);
    this.w=w;
  }
  move() {

    if (this.x > width-this.w/1.08/2 || this.x < 0+this.w/1.08/2) {
      this.speedX=-this.speedX;
      this.speedX*=1.1
    } // right and left bounce
    
    if (this.y > height-this.w/1.05 || this.y < 0+this.w/2/2) {
      this.speedY=-this.speedY;
      this.speedY*1.1
    } // bottom and top bounce 
  

    this.x+=this.speedX;     //x=x+speedX;
    this.y+=this.speedY;
  }
  show() {  
  //200 200
           push();
    translate(this.x+this.w/5, this.y+this.w/8);
    rotate(25);
    fill(255,153,51);
    ellipseMode(CENTER);
    ellipse(0, 0, this.w/1.67, this.w/0.67); //left orange feather
    pop(); 
    
       push();
    translate(this.x-this.w/5, this.y+this.w/8);
    rotate(-25);
    fill(255,153,51);
    ellipseMode(CENTER);
    ellipse(0, 0, this.w/1.67, this.w/0.67); //left orange feather
    pop(); 
    
        push();
    translate(this.x+this.w/2, this.y+this.w/5);
    rotate(60);
    fill(255,0,0);
    ellipseMode(CENTER);
  ellipse(0, 0, this.w/1.67, this.w/0.67) //right red feather
    pop();
    
    push();
  translate(this.x-this.w/2, this.y+this.w/5);
    rotate(-60);
    fill(255,0,0);
    ellipseMode(CENTER);
  ellipse(0, 0, this.w/1.67, this.w/0.67) //left red feather
    pop();
    
 
   fill(255,204,0);   
  ellipse(this.x, this.y+this.w/20, this.w/1.67, this.w/0.67) //yellow feather
    
    push();
    translate(this.x-this.w/2, this.y+this.w/1.67);
    rotate(10);
    fill(78,39,0);
    ellipse(0, 0, this.w/0.8, this.w/1.67);
    pop();
    
    push();
    translate(this.x+this.w/2, this.y+this.w/1.67);
    rotate(-10);
    fill(78,39,0);
    ellipse(0, 0, this.w/0.8, this.w/1.67);
    pop();
     
    
  fill(153, 102, 51, 255);
  ellipse(this.x, this.y+this.w/2.11, this.w/1.08, this.w/1.08); //body
  ellipse(this.x, this.y, this.w/2, this.w/2) //head
  
  fill(255);
  ellipse(this.x-this.w/10, this.y-this.w/20, this.w/6.67*this.d, this.w/6.67*this.d); //eye
  ellipse(this.x+this.w/10, this.y-this.w/20, this.w/6.67*this.d, this.w/6.67*this.d); //eye
  
  fill(0);
  ellipse(this.x-this.w/11.77, this.y-this.w/28.57, this.w/13.33*this.d, this.w/13.33*this.d) //pupil
  ellipse(this.x+this.w/8.7, this.y-this.w/28.57, this.w/13.33*this.d, this.w/13.33*this.d) //pupil
  
    
  fill(255, 0, 0);
  ellipse(this.x-this.w/20, this.y+this.w/5, this.w/10, this.w/5); //gobble
  fill(255,153,51);
 triangle(this.x, this.y+this.w/3.33,  this.x-this.w/10, this.y+this.w/10,  this.x+this.w/10, this.y+this.w/10) //beak
    
  triangle(this.x-this.w/13.33, this.y+this.w/1.05, this.x-this.w/3.08, this.y+this.w/1.05, this.x-this.w/13.33, this.y+this.w/1.29) //left foot
  triangle(this.x+this.w/13.33, this.y+this.w/1.05, this.x+this.w/3.08, this.y+this.w/1.05, this.x+this.w/13.33, this.y+this.w/1.29); //right foot
    
    
    push();
    translate(this.x-this.w/2.22, this.y+this.w/2.22);
    rotate(30);
  fill(218,180,142);
    ellipse(0, 0, this.w/3.64, this.w/1.67); //left wing
    pop(); 
    
  push();
    translate(this.x+this.w/2.22, this.y+this.w/2.22);
    rotate(-30);
    fill(218,180,142)
    ellipse(0,0, this.w/3.64, this.w/1.67); //right wing
    pop();
    
  } 
}

Upvotes: 0

Views: 93

Answers (1)

Theodore Kidd
Theodore Kidd

Reputation: 55

A lot of what you are doing is relative to the width and height. Instead of doing this, create the acting as if the center of it was (0,0), rotate them as needed, and then call transform(this.x, this.y) to map them to where you need them to go.

To help show what I mean, here's a short demonstration:

function setup() {
  createCanvas(400, 400);
}

function draw() {
  background(220);
  
  push()
  angleMode(DEGREES) // Set the anglemode to degrees instead of radians.
  translate(200,200) // Move the figure to (200,200), the center of the canvas
  rotate(45) // Rotate 45 degrees
  // Draw the shapes, working as if the center of them was (0,0)
  rect(-10,-10,20,20)
  ellipse(-40,0,20,20)
  ellipse(40,0,20,20)
  pop()
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.6.0/p5.js"></script>

Hope this helps!

Upvotes: 2

Related Questions