I have a polygon that has circles on its vertices.
What I expect to accomplish is that every circle will be moving to the circle on its right. This is a physics concept which proves that if every circle is moving to the one on its right with a constant speed, soon they will reach the center. I'm trying to accomplish this animation, however I am able to move circles but not in the direction to the one next to it. Here's my current code that draws the polygon with circles:
function particleGenerator(n){
const ctx = document.getElementById('poly').getContext('2d');
ctx.reset();
drawPolygon(ctx, 154, 71.25 , n, 50, 0, 5, 7.5);
}
const drawPolygon = (ctx, x, y, points, radius, rotation = 0, nodeSize = 0, nodeInset = 0) => {
ctx.beginPath();
ctx.moveTo(
x radius * Math.cos(rotation),
y radius * Math.sin(rotation)
);
for (let i = 1; i <= points; i = 1) {
const angle = (i * (2 * Math.PI / points)) rotation;
ctx.lineTo(
x radius * Math.cos(angle),
y radius * Math.sin(angle)
);
}
ctx.fillStyle = "#00818A";
ctx.fill();
if (!nodeSize) return;
const dist = radius - nodeInset;
for (let i = 1; i <= points; i = 1) {
const angle = (i * (2 * Math.PI / points)) rotation;
let x1 = x dist * Math.cos(angle);
let y1 = y dist * Math.sin(angle);
ctx.beginPath();
ctx.arc(x1, y1, nodeSize, 0, 2 * Math.PI);
ctx.fillStyle = "#DBEDF3"
ctx.fill();
}
};
<button onclick="particleGenerator(4)">Click Me!</button>
<canvas id="poly">
CodePudding user response:
You can keep track of a list of corners. You generate them in order, so to get a corner's next neighbor you can do corners[i 1] || corners[0]
.
To move the corner in the direction of the next one, you can calculate their differences in x
and y
coordinates and add a percentage of that difference to a corner's current location.
Here's a running example (I did remove some of the code so I could focus on just the updating problem:
function particleGenerator(n) {
const ctx = document.getElementById('poly').getContext('2d');
ctx.reset();
const originalCorners = createCorners(150, 70, n, 50);
const corners = createCorners(150, 70, n, 50);
const next = () => {
corners.forEach(([x0, y0], i) => {
const [x1, y1] = corners[i 1] || corners[0];
const dx = x1 - x0;
const dy = y1 - y0;
const SPEED = 0.05;
corners[i][0] = x0 dx * SPEED;
corners[i][1] = y0 dy * SPEED;
});
}
const frame = () => {
ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
drawPolygon(ctx, originalCorners, "grey");
drawPolygon(ctx, corners);
drawDots(ctx, corners);
next();
requestAnimationFrame(frame);
};
frame();
}
const createCorners = (x, y, n, radius) => {
const corners = [];
for (let i = 1; i <= n; i = 1) {
const angle = (i * (2 * Math.PI / n));
corners.push([
x radius * Math.cos(angle),
y radius * Math.sin(angle)
]);
}
return corners;
}
const drawPolygon = (
ctx,
corners,
color = "#00818A"
) => {
// Draw fill
ctx.beginPath();
corners.forEach((c, i) => {
if (i === 0) ctx.moveTo(...c);
else ctx.lineTo(...c);
});
ctx.fillStyle = color
ctx.fill();
};
const drawDots = (
ctx,
corners,
) => {
// Draw dots
corners.forEach(([x, y], i, all) => {
ctx.beginPath();
ctx.arc(x, y, 5, 0, 2 * Math.PI);
ctx.fillStyle = "red"
ctx.fill();
});
};
<input type="number" value="6" min="3" max="100">
<button onclick="particleGenerator(document.querySelector('input').valueAsNumber)">Click Me!</button>
<canvas id="poly">