如何用Canvas画一个正多边形

作者: 腾儿飞 | 来源:发表于2016-12-12 00:39 被阅读1173次

    本文由BarryZhang原创,同时首发于barryzhang.com简书,非商业转载请注明作者和原文链接。

    场景

    给定一个指定的正方形的区域,要求在该区域内画一个正N边形(正三角形、正方形、正五边形……)

    public static void drawPolygon (RectF rect, Canvas canvas, Paint p, int n) {
        // draw……
    }
    

    分析

    要用到一些三角函数的知识,于是我画了一幅灵魂画作👻:

    灵魂画作

    分析:

    • 计算出每个顶点的坐标,然后把它们连起来,就是一个正多边形啦~
    • 圆心角a的度数为360/n,弧度计算为2π/n
    • 如果把圆心的坐标为(0,0),那么顶点P1的坐标为[X1=cos(a),Y1=sin(a)]
    • 以此类推,顶点Pn坐标为[Xn=cos(a*n),Yn=sin(a*n)]
    • 圆心的实际坐标是外接矩形的中心:[Ox=(rect.right+rect.left)/2 , Oy=(rect.top+rect.bottom)/2]
    • 所以Pn的实际坐标是[Xn+Ox,Yn+Oy]
    • 把P0-P1…Pn连起来就是我们要的结果了。
    • Java中可以使用Path来保存路径,最后使用canvas.drawPath来绘制出来。

    实现

    简化的伪代码:

    float a = 2π / n ; // 角度
    Path path = new Path();
    for( int i = 0; i <= n; i++ ){
        float x = R * cos(a * i); 
        float y = R * sin(a * i);
        if (i = 0){
            path.moveTo(x,y); // 移动到第一个顶点   
        }else{
            path.lineTo(x,y); //    
        }
    }
    drawPath(path);
    

    Java代码最终的完整代码,可以直接拿去用:

    
    public static void drawPolygon (RectF rect, Canvas canvas, Paint paintByLevel, int number) {
        if(number < 3) {
            return;
        }
        float r = (rect.right - rect.left) / 2;
        float mX = (rect.right + rect.left) / 2;
        float my = (rect.top + rect.bottom) / 2;
        Path path = new Path();
        for (int i = 0; i <= number; i++) {
            // - 0.5 : Turn 90 ° counterclockwise
            float alpha = Double.valueOf(((2f / number) * i - 0.5) * Math.PI).floatValue();
            float nextX = mX + Double.valueOf(r * Math.cos(alpha)).floatValue();
            float nextY = my + Double.valueOf(r * Math.sin(alpha)).floatValue();
            if (i == 0) {
                path.moveTo(nextX, nextY);
            } else {
                path.lineTo(nextX, nextY);
            }
        }
        canvas.drawPath(path, paintByLevel);
    }
    

    DEMO

    这个项目里用到了这个函数,可以点进去看以及下载demo。
    https://github.com/barryhappy/TContributionsView

    DEMO

    另外,希望这篇文章能对你有所帮助。
    最近开始整了一个微信公众号,用以分享一些 Android 相关以及不相关的干货,既然都看到这里了,何不长按/扫码关注一下?
    不只Android

    不只Android

    相关文章

      网友评论

        本文标题:如何用Canvas画一个正多边形

        本文链接:https://www.haomeiwen.com/subject/tffmmttx.html