Reputation: 545
I recently asked a question about drawing polygons in an HTML5 Canvas and got an excellent answer I just need to be able to add one feature. The ability to make those two functions (draw_sharp_polygon()
and draw_reuleaux_polygon()
) draw irregular polygons with random angles that are still inscribed on the same circle. Preferably I'd like to do this by adding one simple Boolean argument that decides whether the polygon to be drawn will be regular or irregular.
Similar to the picture on this Wikipedia page.
Upvotes: 1
Views: 1265
Reputation: 89171
var canvas = document.getElementById('target');
var context = canvas.getContext('2d');
document.getElementById('trigger').addEventListener('click', generate, false);
generate();
function generate()
{
var angles = randomAngles(5);
var centerX = 150;
var centerY = 150;
var radius = 100;
context.clearRect(0, 0, canvas.width, canvas.height);
context.strokeStyle = 'silver';
polygon(centerX, centerY, radius, angles);
context.stroke();
context.strokeStyle = 'silver';
circle(centerX, centerY, radius);
context.stroke();
context.strokeStyle = 'black';
reuleaux(centerX, centerY, radius, angles);
context.stroke();
}
function randomAngles(numPoints)
{
var angles = [];
for (var i = 0; i < numPoints; i++)
{
angles.push(Math.random()*2*Math.PI);
}
angles.sort();
return angles;
}
function polygon(centerX, centerY, radius, angles)
{
var angle3 = angles[angles.length - 1];
var p3 = { x: centerX + radius * Math.cos(angle3),
y: centerY + radius * Math.sin(angle3) };
context.beginPath();
context.moveTo(p3.x, p3.y);
for (var i = 0; i < angles.length; i++)
{
var angle1 = angle3;
var p1 = p3;
angle3 = angles[i];
p3 = { x: centerX + radius * Math.cos(angle3),
y: centerY + radius * Math.sin(angle3) };
context.lineTo(p3.x, p3.y);
}
}
function circle(centerX, centerY, radius)
{
context.beginPath();
context.arc(centerX, centerY, radius, 0, 2*Math.PI, false);
}
function reuleaux(centerX, centerY, radius, angles)
{
// The "previous point" for the first segment
var angle3 = angles[angles.length - 1];
var p3 = { x: centerX + radius * Math.cos(angle3),
y: centerY + radius * Math.sin(angle3) };
context.beginPath();
context.moveTo(p3.x, p3.y);
for (var i = 0; i < angles.length; i++)
{
// Copy previous point as startpoint.
var angle1 = angle3;
var p1 = p3;
// Calculate the new endpoint.
angle3 = angles[i];
p3 = { x: centerX + radius * Math.cos(angle3),
y: centerY + radius * Math.sin(angle3) };
// Angular size of the segment.
var angleSize = angle3 - angle1;
if (angleSize < 0) angleSize += 2 * Math.PI;
// Middle-point
var angle2 = angle1 + angleSize/2;
var p2 = { x: centerX + radius * Math.cos(angle2),
y: centerY + radius * Math.sin(angle2) };
var reuleaux_radius = radius * Math.sqrt(2 + 2*Math.cos(angleSize/2));
context.arcTo(p2.x, p2.y, p3.x, p3.y, reuleaux_radius);
}
}
<div><button id="trigger">Regenerate</button></div>
<canvas id="target" width="300" height="300"></canvas>
Upvotes: 2