如何用Canvas画一个正多边形
2016年12月12日
场景
给定一个指定的正方形的区域,要求在该区域内画一个正N边形(正三角形、正方形、正五边形……)123public 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
来绘制出来。
实现
简化的伪代码:
|
|
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