First I recommend fixing syntax errors and posting code that runs so it's easy for other contributors to replicate your issue.
There are multiple ways to do this:
- You can use
push()
/ pop()
calls to isolate coordinate systems and rotate the handles
- You can use the polar to cartesian coordinates conversion function to rotate the tips of the handles around the clock centres.
The formula is:
x = cos(angle) * radius
y = sin(angle) * radius
(You can find a detailed explanation here)
Option 1 is pretty straight forward:
show1() {
ground.push();
ground.translate(this.x, this.y);
ground.rotate(frameCount * 0.1);
ground.line(0, 0, this.r / 2 * (w*0.005), this.r / 2 * (w*0.005));
ground.line(0, 0, - this.r / 2 * (w*0.005), this.r / 2 * (w*0.005));
ground.pop();
}
In this case frameCount * 0.1
is used as an angle (in radians).
Option 2 would look like this if you were to use two independent angles for each clock handle:
show1(){
let angle1 = frameCount * 0.1;
let angle2 = frameCount * 0.01666666667;
let x1 = cos(angle1) * this.r;
let y1 = sin(angle1) * this.r;
let x2 = cos(angle2) * this.r * 0.75;
let y2 = sin(angle2) * this.r * 0.75;
ground.line(this.x, this.y, this.x + x1, this.y + y1);
ground.line(this.x, this.y, this.x + x2, this.y + y2);
}
Here's a version of your sketch with the push()
/pop()
option and two angles:
let bubbles = [];
let ground;
let w;
function setup() {
createCanvas(400, 400);
w = width;
startViz();
ground = createGraphics(width, height);
}
function draw() {
drawViz();
}
function startViz() {
for (let i = 0; i < 5; i++) {
bubbles.push(new Bubble());
}
}
function drawViz() {
ground.background(30);
for (let b of bubbles) {
b.update();
b.show();
b.show1();
}
// noLoop();
image(ground, 0, 0);
}
class Bubble {
constructor() {
this.r = random(50, 80);
this.x = random(this.r, width - this.r);
this.y = random(this.r, height - this.r);
this.vx = random(-1 * (w*0.005), 3 * (w*0.005));
this.vy = random(-1 * (w*0.005), 3 * (w*0.005));
this.color = color(random(255), random(255), random(255));
}
show() {
ground.noFill();
ground.stroke(255);
ground.fill(this.color);
ground.strokeWeight(3);
ground.circle(this.x, this.y, this.r * 2 * (w*0.005));
}
show1() {
ground.push();
ground.translate(this.x, this.y);
ground.rotate(frameCount * 0.1);
ground.line(0, 0, this.r / 2 * (w*0.005), this.r / 2 * (w*0.005));
ground.pop();
ground.push();
ground.translate(this.x, this.y);
ground.rotate(frameCount * 0.01);
ground.line(0, 0, - this.r / 2 * (w*0.005), this.r / 2 * (w*0.005));
ground.pop();
}
update() {
this.x += this.vx;
this.y += this.vy;
if (this.x > width - this.r || this.x < this.r) {
this.vx *= -1;
}
if (this.y > height - this.r || this.y < this.r) {
this.vy *= -1;
}
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.4.1/p5.min.js"></script>
Notice the order of transformations is important!
First we translate to the clock's centre, then we rotate (otherwise we'd get a totally different result).
(I wasn't sure what w
was meant to be so assumed width
(similar to Anton's function))
The indentation isn't necessary, but hopefully it helps visually isolate coordinate systems in code.
Additionally you can encapsulate repeating code into a reusably function:
show1(){
drawClockHandle(frameCount * 0.1, this.r);
drawClockHandle(frameCount * 0.01666666667, this.r * 0.75);
}
drawClockHandle(angle, radius){
ground.push();
ground.translate(this.x, this.y);
ground.rotate(angle);
ground.line(0, 0, radius, 0);
ground.pop();
}