bigfanjs
bigfanjs

Reputation: 772

Move an object along the trajectory of a hexagon

As you can see in the attached GIF, the white dot moves in circular path.

How to make it move along the trajectory of the hexagon. in other words, make the dot follow the hexagon path?

I am rotating the white dot using the following code:

const angle = Math.PI / 6 * delta; // delta is the current time to increment the angle.
const radius = 300;
const x = center.x + Math.cos(angle) * radius;
const y = center.y + Math.sin(angle) * radius;

the white dot moves in circular path

thank you

Upvotes: 0

Views: 130

Answers (1)

r3mainer
r3mainer

Reputation: 24587

There are various ways of doing this. If you want to keep a constant angular rotation speed around the centre of the hexagon, then you could modify the radius of the moving object according to the angle of rotation.

First choose the radius corresponding to the vertices of the hexagon. In this example, I'm using a radius of 90px. The inner radius (of the inscribed circle tangential to the sides of the hexagon) is sqrt(0.75) times this value:

    r_outer = 90.0
    r_inner = r_outer * Math.sqrt(0.75)

If an angle of zero corresponds to the middle of one side of the hexagon, then by simple geometry the radius along this side will equal r_inner / Math.cos(theta) as theta varies from −30° to +30°. You can use a floating-point modulus operator to confine the angle to the range from 0 to 60°. To keep the angle within ±30° for the radius calculations, just add 30° to the angle before calculating the modulus, and subtract it afterwards.

So the complete calculation looks something like this:

    r0 = 90.0              (Outer radius)
    r1 = r0 * sqrt(0.75)   (Inner radius)
    d30 = 30 * pi/180      (30 degrees in radians)
    d60 = 60 * pi/180      (60 degrees in radians)
    r = r1 / cos((theta + d30) % d60 - d30)
    x = x_center + sin(theta) * r
    y = y_center - cos(theta) * r

Here's a working example:

let theta=0.0;
let r0 = 90.0; // Outer radius
let r1 = r0 * Math.sqrt(0.75); // Inner radius
let d30 = 30 * Math.PI/180; // 30 degrees in radians
let d60 = 60 * Math.PI/180; // 60 degrees in radians

function move_dot() {
    theta += 0.025;
    let r = r1 / Math.cos((theta + d30) % d60 - d30);
    let x = Math.sin(theta) * r;
    let y = -Math.cos(theta) * r;
    document.getElementById('dot').style.cx=x.toFixed(2)+'px';
    document.getElementById('dot').style.cy=y.toFixed(2)+'px';
}

document.body.onload=function(){setInterval(move_dot,30);}
#hex { fill:none; stroke:#aaf; stroke-width:1; }
#dot { fill:#000; stroke:none; cx:90px; cy:0px; }
<svg width="200" height="200" viewBox="-100 -100 200 200">
<path id="hex" d="M45-77.94 90 0 45 77.94-45 77.94-90 0-45-77.94Z"/>
<circle id="dot" cx="90" cy="0" r="5"/>
</svg>

Upvotes: 2

Related Questions