Canvas绘制任意正多边形

几何知识介绍

任意正多边形规律

1、任意正多边形都存在与一个外接圆。
2、外接圆的圆心为正多边形的中心重心到各边的距离相等,到各角的距离相等=外接圆半径
3、中心到各个角的连线将正多边形n等分(n = 正多边形边数),同时将圆心角(2π)n等分。
我们已正八边形为例,如下图所示:
在这里插入图片描述

坐标表达方式

1、坐标系上任意一点到圆心的连线,我们可以用 θ 来表示。
2、上述连线上的任意点的坐标可以表示为(r * cosθ,r * sinθ),其中r是该点到(0,0)的距离,θ是直线与x坐标轴的夹角(0 <= θ <= 2π)

绘图方式

假设我们要绘制一个正n边形,他的外接圆半径为r,圆心角被平分为θθ = 2π/n)。
那么正多边形所有的顶点坐标分别是:
(r * cos(θ * 0),r * sin(θ * 0))
(r * cos(θ * 1),r * sin(θ * 1))
(r * cos(θ * 2),r * sin(θ * 2))

(r * cos(θ * n),r * sin(θ * n))
我们只需要将这些点连起来就可以获得一个正多边形

代码

代码一(没有摆正)

<!DOCTYPE html>
<html>

<body>
    <!--定义画布容器,给个边框省的你们找不到-->
    <canvas id="myCanvas" width="400" height="400" style="border:1px solid #d3d3d3;">
        Your browser does not support the HTML5 canvas tag.
    </canvas>

    <script>
        //获取画布对象
        var c = document.getElementById("myCanvas");
        var ctx = c.getContext("2d");
        var canvasSide = 400,
            circleCenterX = canvasSide/2,
            circleCenterY = canvasSide/2;
        var sideLength = 200,
            sideCount = 6,
            r = sideLength/(2*Math.sin(Math.PI/4));

        var a = 2 * Math.PI / sideCount ; // 角度
        ctx.beginPath();
        for( var i = 0; i <= sideCount; i++ ){
            var x = circleCenterX + r * Math.cos(a * i); 
            var y = circleCenterY + r * Math.sin(a * i);
            if (i == 0){
                ctx.moveTo(x,y); // 移动到第一个顶点   
            }else{
                ctx.lineTo(x,y); //    
            }
        }
        ctx.closePath();
        ctx.stroke();
    </script>

</body>

</html>

画完之后发现一个问题,正多边形它摆放位置不正,研究一番发现如果这样写第一个点一定是落在x轴上(y = r*sin0° = 0)的,于是进行改造让首次的点摆正它更新后代码如下:

代码二(摆正了解决了强迫症的问题)

<!DOCTYPE html>
<html>

<body>
    <!--定义画布容器,给个边框省的你们找不到-->
    <canvas id="myCanvas" width="400" height="400" style="border:1px solid #d3d3d3;">
        Your browser does not support the HTML5 canvas tag.
    </canvas>

    <script>
        //获取画布对象
        var c = document.getElementById("myCanvas");
        var ctx = c.getContext("2d");
        var canvasSide = 400,
            circleCenterX = canvasSide/2,
            circleCenterY = canvasSide/2;
        var sideLength = 200,
            sideCount = 6,
            r = sideLength/(2*Math.sin(Math.PI/4));

        var a = 2 * Math.PI / sideCount ; // 角度
        var offset =  - Math.PI/2;
        if(sideCount % 2 ==0){
            offset = - Math.PI/2 + a/2;
        }
        ctx.beginPath();
        for( var i = 0; i <= sideCount; i++ ){
            var x = circleCenterX + r * Math.cos(a * i + offset); 
            var y = circleCenterY + r * Math.sin(a * i + offset);
            if (i == 0){
                ctx.moveTo(x,y); // 移动到第一个顶点   
            }else{
                ctx.lineTo(x,y); //    
            }
        }
        ctx.closePath();
        ctx.stroke();
        
    </script>

</body>

</html>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值