可以在Circle HTML5 Canvas上刻录的不规则多边形

时间:2014-11-28 20:17:48

标签: javascript html5 canvas html5-canvas

我最近问了一个关于在HTML5 Canvas中绘制多边形的问题,得到了一个很好的answer我只需要能够添加一个功能。使这两个函数(draw_sharp_polygon()draw_reuleaux_polygon())能够绘制具有随机角度的不规则多边形,这些角度仍然刻在同一个圆上。我希望通过添加一个简单的布尔参数来确定要绘制的多边形是规则的还是不规则的。

与此Wikipedia page上的图片类似。

1 个答案:

答案 0 :(得分:2)



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);
    }
}
&#13;
<div><button id="trigger">Regenerate</button></div>
<canvas id="target" width="300" height="300"></canvas>
&#13;
&#13;
&#13;