View绘制系列(9)-Canvas八卦图绘制

Canvas八卦图绘制

前面咱们已经学习了Path.quadTo(float x1, float y1, float x2, float y2)Path.cubicTo(float x1, float y1, float x2, float y2,float x3, float y3)方法的使用,但并非全部的曲线全部的曲线都须要用贝塞尔曲线来描述,毕竟在没有专业软件辅助的状况下,确认控制点也是一件很复杂的事情,好比说咱们闭合曲线中包含一段椭圆弧或者圆弧,抑或者圆角矩形,咱们该怎么作呢?做为描述组合路径的核心类,Path固然会提供对应的方法。web

Path部分路径截取函数对照说明表:canvas

函数名 函数说明 备注
addArc(float left, float top, float right, float bottom, float startAngle,float sweepAngle) 添加以(left,top)为左上顶点,(right,bottom)为右下顶点矩形的内切椭圆中,以startAngle角度起始,划过sweepAngle角度后所获得的弧 注意:这里传入的startAnglesweepAngle单位均为角度,sweepAngle顺时针为正值,逆时针为负值
addArc(RectF oval, float startAngle, float sweepAngle) 同上,只是将矩形的描述方式改为了RectF类对象描述 同上
addCircle(float x, float y, float radius, Direction dir) 添加一个圆到Path路径中,dir说明环绕圆周方向 其中dir取值Direction.CW为顺时钟,Direction.CCW为逆时针
addOval(float left, float top, float right, float bottom, Direction dir) 添加一个椭圆到路径中,椭圆是以(left,top)为左上顶点,(right, bottom)为右下顶点矩形的内切椭圆,dir说明环绕方向 同上
addRect(float left, float top, float right, float bottom, Direction dir) 添加以(left,top)为左上顶点,(right, bottom)为右下顶点的矩形,dir说明环绕方向 同上
addRoundRect(float left, float top, float right, float bottom, float rx, float ry, Direction dir) 添加以(left,top)为左上顶点,(right, bottom)为右下顶点,以rxry为圆角度的圆角矩形,dir说明环绕方向 同上
arcTo(float left, float top, float right, float bottom, float startAngle, float sweepAngle, boolean forceMoveTo) 添加以(left,top)为左上顶点,(right,bottom)为右下顶点矩形的内切椭圆中,以startAngle角度起始,划过sweepAngle角度后所获得的弧,forceMoveTo是否强制修正路径起点,若是为true,至关于执行Path.moveTo(startAngle对应坐标),随后arcTo 注意:这里传入的startAnglesweepAngle单位均为角度,sweepAngle顺时针为正值,逆时针为负值

添加整个图形路径的函数原型比较简单,你们自行尝试使用下,这里咱们重点演示下addArc方法的使用。c#

查看下图,是一个八卦图,为了更好的说明问题,我在图上添加了辅助坐标系和点:微信

从图上咱们能够将该图简单分为四部分,黑色小圆M,白色小圆N,以及曲线ABOA(即白色阴阳鱼区域),曲线BAOB(即黑色阴阳鱼区域).


进一步在上图中添加辅助点和辅助曲线,咱们能够看到,白色阴阳鱼其实是由半圆BFA,半圆AEO及半圆BDO的圆周曲线所围成,同理黑色阴阳鱼是由半圆AGB,半圆BDO,及半圆OEA的圆周围成。

假设咱们以View宽度(在onDraw函数内能够经过getWidth(),getHeight()获取View的可见宽高)为大圆O直径,那么圆M及圆N直径就为getWidth()/2。函数

圆O的外接矩形顶点为:学习

左上顶点:(0,0),右下顶点:(getWidth(),getHeight())flex

圆M的外接矩形顶点为:编码

左上顶点:(getWidth()/4,),右下顶点:(getWidth()*3/4,getWidth()/2)url

圆N的外接矩形顶点为:spa

左上顶点:(getWidth()/4,getWidth()/2),右下顶点:(getWidth()*3/4,getWidth())

那么左侧白色阴阳鱼的路径为:

Path leftDiagramPath = new Path();
//添加圆O的左侧半圆BFA所在的圆周
leftDiagramPath.addArc(0,0,getWidth(),getWidth(),90,180);
//添加圆M的右侧半圆AEO所在的圆周,起始角度负90,以水平X正向为0度
leftDiagramPath.addArc(getWidth()/4,0,getWidth()*3/4,getWidth()/2,-90,180);
//添加圆N的左侧半圆ODB所在的圆周,起始角度负90,以水平X正向为0度
leftDiagramPath.addArc(getWidth()/4,getWidth()/2,getWidth()*3/4,getWidth(),-90,-180);

右侧黑色阴阳鱼的路径为:

Path rightDiagramPath = new Path();
//添加圆O的右侧半圆BGA所在的圆周
rightDiagramPath.addArc(0,0,getWidth(),getWidth(),90,-180);
//添加圆M的右侧半圆AEO所在的圆周,起始角度负90,以水平X正向为0度
rightDiagramPath.addArc(getWidth()/4,0,getWidth()*3/4,getWidth()/2,-90,180);
//添加圆N的左侧半圆ODB所在的圆周,起始角度负90,以水平X正向为0度
rightDiagramPath.addArc(getWidth()/4,getWidth()/2,getWidth()*3/4,getWidth(),-90,-180);

两个小圆的绘制代码,取半径为100:

//上面的黑色小圆圆心
Point topCircleCenter = new Point(getWidth()/2,getWidth()/4);
//下面的白色小圆圆心
Point bottomCircleCenter = new Point(getWidth()/2,getWidth()*3/4);
//小圆半径
float smallerCircleRadius = 100;

canvas.drawCircle(topCircleCenter.x,topCircleCenter.y,smallerCircleRadius,paint);
canvas.drawCircle(bottomCircleCenter.x,bottomCircleCenter.y,smallerCircleRadius,paint);

先调用canvas.drawPath(@NonNull Path path, @NonNull Paint paint)绘制阴阳鱼,随后绘制两个小圆,运行效果以下:

这里我在 onDraw 函数刚开始使用 canvas.drawColor(Color.GREY) 为页面绘制了灰色背景。

完整代码参见附录_Canvas八卦图绘制

往期推荐

View绘制系列(1)-View简介

OpenCV SDK下载及Android Java环境搭建

玩转花式Loading


本文分享自微信公众号 - 小海编码日记(gh_1f87b8c00ede)。
若有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一块儿分享。

相关文章
相关标签/搜索