代码地址如下:
http://www.demodashi.com/demo/14754.html

前言

之前讲过Paint和Canvas的基本使用,今天来介绍下Path的使用

涉及内容有:

  1. Path画直线路径
  2. Path画弧线路径
  3. PathView引用说明
  4. 项目结构图和效果图
一. Path画直线路径

Path画直线路径的步骤分三步:

第一步:设置path的起点,代码如下:

  1. path.moveTo(float x,float y);//设置path的起点

第二步:设置下一个路径点,代码如下:

  1. path.lineTo(float x,float y);//设置下一个路径点

注意:path的lineTo方法可以不断使用。

第三步:封闭形成闭环,代码如下:

  1. path.close();

注意:第三步的调用不是必须的,只有当你连续LineTo了几条直线以后,想形成一个封闭的空间的时候,可以直接调用此方法,而不用又费力的调用lineTo回到原点。

二. Path画弧线路径

path画弧线的方法常用的有如下几个:

  1. arcTo(RectF oval, float startAngle, float sweepAngle, boolean forceMoveTo);
  2. arcTo(float left, float top, float right, float bottom, float startAngle, float sweepAngle, boolean forceMoveTo)

其实第一个和第二个大同小异,只是第一个是传入一个RectF,而第二个是直接将构造RectF的参数传进去而已。这里以讲解

  1. arcTo(RectF oval, float startAngle, float sweepAngle, boolean forceMoveTo);

为例,方法很简单,但是理解是个问题。下面着重介绍arcTo方法的几个参数的意义,帮助大家理解。

2.1 RectF oval 参数

书本解释是:生成椭圆的矩形。

这里大家注意一点,如果矩形是长方形,那么生成的是椭圆,如果矩形是正方形的时候,生成的就是圆了。

这里解释让人感觉生硬,不好理解,那么这个RectF和弧线到底啥关系,让我们用代码解释:

  1. //设置paint
  2. Paint paint=new Paint();
  3. paint.setColor(Color.RED);
  4. paint.setStyle(Paint.Style.STROKE);
  5. paint.setStrokeWidth(5);
  6. //设置Path
  7. Path path=new Path();
  8. RectF rectF=new RectF();
  9. rectF.set(340,350,740,550);
  10. //画矩形
  11. canvas.drawRect(rectF,paint);
  12. paint.setColor(Color.BLUE);
  13. path.arcTo(rectF,0,90,false);
  14. //画弧线
  15. canvas.drawPath(path,paint);

效果图如下:

测试矩形画弧线



下面看下,当矩形为正方形的情况:

  1. //设置paint
  2. Paint paint=new Paint();
  3. paint.setColor(Color.RED);
  4. paint.setStyle(Paint.Style.STROKE);
  5. paint.setStrokeWidth(5);
  6. //设置Path
  7. Path path=new Path();
  8. RectF rectF=new RectF(340,600,740,1000);
  9. //画正方形
  10. canvas.drawRect(rectF,paint);
  11. //画弧线
  12. paint.setColor(Color.BLUE);
  13. path.arcTo(rectF,0,90,false);
  14. canvas.drawPath(path,paint);

效果图如下:

测试正方形画矩形



由上两个示例不难看出,RectF和弧线的关系是,RectF是弧线所在圆或椭圆的外切矩形,当RectF为长方形的时候,弧线为其内切椭圆上的一段轨迹,当RectF为正方形的时候,弧线为其内切圆上的一段轨迹,也不难推断,弧线所在几何中心或圆心即为RectF的几何中心。

2.2 float startAngle, float sweepAngle 参数

书本解释:

float startAngle:弧开始的角度,以x轴正方向为0度

float sweepAngle:弧持续的弧度

在2.1中,我设置的画弧代码均是:

  1. path.arcTo(rectF,0,90,false);

即 startAngle=0,sweepAngle =90,与上面的书本解释相结合,我们可以这样理解,当弧线切线角度为0°的时候开始画弧,直到当弧线的切线角度为90°的时候,停止画弧。

2.3 boolean forceMoveTo 参数

在Path画图的过程中,除了addXXX系列函数和moveTo()方法外,路径默认都是连贯的。而forceMoveTo 则是设置弧线与画弧线之前的“最后一笔”是否强制不连接。当 forceMoveTo =false 时,表示连接,当 forceMoveTo =true时,表示不连接。

下面以示例说明:

当 forceMoveTo =false时:

  1. Paint paint=new Paint();
  2. paint.setColor(Color.GREEN);
  3. paint.setStyle(Paint.Style.STROKE);
  4. paint.setStrokeWidth(5);
  5. Path path=new Path();
  6. path.moveTo(540,1400);//设置path初始点,模仿画弧前"最后一笔"
  7. //画弧线
  8. RectF rectF=new RectF(50,1050,490,1350);
  9. path.arcTo(rectF,0,90,false);
  10. canvas.drawPath(path,paint);

效果图:

测试forceMoveTo=false



当 forceMoveTo =true 时:

  1. Paint paint=new Paint();
  2. paint.setColor(Color.GREEN);
  3. paint.setStyle(Paint.Style.STROKE);
  4. paint.setStrokeWidth(5);
  5. Path path=new Path();
  6. path.moveTo(540,1400);//设置path初始点,模仿画弧前"最后一笔"
  7. //画弧线
  8. RectF rectF=new RectF(50,1050,490,1350);
  9. path.arcTo(rectF,0,90,true);
  10. canvas.drawPath(path,paint);

效果图如下:

测试forceMoveTo=true

2.4 arcTo 方法需要注意的地方

Path的 arcTo 方法是用来画弧线的,不能用来画圆,当你代码如下设置的时候:

  1. path.arcTo(rectf,0,360,true);

时,将无法画出一个圆,因为弧的弧度不能为360°,当你设置的度数大于360°的时候,实际画出的弧度为你设置的度数减去360°得到的度数,例如下面:

  1. //设置画笔
  2. Paint paint=new Paint();
  3. paint.setColor(Color.BLACK);
  4. paint.setStyle(Paint.Style.STROKE);
  5. paint.setStrokeWidth(5);
  6. //设置路径
  7. Path path=new Path();
  8. RectF rectF=new RectF(590,1050,1030,1350);
  9. path.arcTo(rectF,0,400,true);
  10. canvas.drawPath(path,paint);

效果图如下:

超过360度

三. PathView引用说明

所有的测试代码我都封装到了PathView控件中,下面贴出PathView中主要代码:

  1. //初始化
  2. init(canvas);
  3. //path画直线
  4. drawLinePath(canvas);
  5. //Path画弧线
  6. drawArcPath(canvas);
  7. //测试画弧线
  8. drawActPathTest(canvas);
  9. //测试长方形和弧线的关系
  10. testOneArcTo(canvas);
  11. //测试正方形和弧线的关系
  12. testTwoArcTo(canvas);
  13. // //测试 forceMoveTo =false
  14. // testForceMoveTo(canvas,false);
  15. //测试 forceMoveTo =true
  16. testForceMoveTo(canvas,true);
  17. //测试度数超过360
  18. testMore360(canvas);

PathView在MainActivity对应的activity_main.xml中的引用如下:

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3. xmlns:app="http://schemas.android.com/apk/res-auto"
  4. xmlns:tools="http://schemas.android.com/tools"
  5. android:layout_width="match_parent"
  6. android:layout_height="match_parent"
  7. tools:context="com.android.testdemo.main.MainActivity">
  8. <com.android.testdemo.function.PathView
  9. android:layout_width="match_parent"
  10. android:layout_height="match_parent"/>
  11. </android.support.constraint.ConstraintLayout>
四. 项目结构图和效果图

项目结构图

效果图



Path画直线与弧线

代码地址如下:
http://www.demodashi.com/demo/14754.html

Path画直线与弧线的更多相关文章

  1. SVG 学习<七> SVG的路径——path(1)直线命令、弧线命令

    目录 SVG 学习<一>基础图形及线段 SVG 学习<二>进阶 SVG世界,视野,视窗 stroke属性 svg分组 SVG 学习<三>渐变 SVG 学习<四 ...

  2. WPF画图の利用Path画扇形(仅图形)

    一.画弧 Path继承自Sharp,以System.Windows.Shapes.Shape为基类,它是一个具有各种方法的控件. 我们先看一段xaml代码: <Path Stroke=" ...

  3. 《图形学》实验五:改进的Bresenham算法画直线

    开发环境: VC++6.0,OpenGL 实验内容: 使用改进的Bresenham算法画直线. 实验结果: 代码: //中点Bresenham算法生成直线 #include <gl/glut.h ...

  4. 《图形学》实验四:中点Bresenham算法画直线

    开发环境: VC++6.0,OpenGL 实验内容: 使用中点Bresenham算法画直线. 实验结果: 代码: //中点Bresenham算法生成直线 #include <gl/glut.h& ...

  5. 《图形学》实验三:DDA算法画直线

    开发环境: VC++6.0,OpenGL 实验内容: 使用DDA算法画直线. 实验结果: 代码: #include <gl/glut.h> #include <math.h> ...

  6. Bresenham画直线,任意斜率

    function DrawLineBresenham(x1,y1,x2,y2) %sort by x,sure x1<x2. if x1>x2 tmp=x1; x1=x2; x2=tmp; ...

  7. 几种画直线的方法-孙鑫C++笔记

    // HDC画直线 CPoint m_ptOrigin ; void CDrawView::OnLButtonDown(UINT nFlags, CPoint point) { m_ptOrigin ...

  8. 1.1.2-学习Opencv与MFC混合编程之---画图工具 画直线 画圆 画矩形

    源代码地址:http://download.csdn.net/detail/nuptboyzhb/3961685 画图工具 1.     画直线 Ø  增加‘直线’菜单项,建立类向导: Ø  对CXX ...

  9. Python使用DDA算法和中点Bresenham算法画直线

    title: "Python使用DDA算法和中点Bresenham算法画直线" date: 2018-06-11T19:28:02+08:00 tags: ["图形学&q ...

随机推荐

  1. Pytorch之CrossEntropyLoss() 与 NLLLoss() 的区别

    (三)PyTorch学习笔记——softmax和log_softmax的区别.CrossEntropyLoss() 与 NLLLoss() 的区别.log似然代价函数 pytorch loss fun ...

  2. Intent 常用场景 FileProvider 拍照 裁剪 MD

    Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱 MyAndroidBlogs baiqiantao baiqiantao bqt20094 baiqiantao@sina ...

  3. 如何清空IFRAME中的HTML

    window.frames["ifra"].document.write(""); window.frames["ifra"].docume ...

  4. 绝对定位常见误区:position:absolute相对于谁定位、及当溢出时怎么隐藏

    1.绝对定位元素溢出父元素,怎么隐藏问题? 通常,为了让DIV子元素超出部分隐藏,都是在父元素设置overflow:hidden,这样即可防止子元素撑开父元素,使子元素能够溢出隐藏! 但是,对于pos ...

  5. C++两个矩阵相乘

    /*编程求两个矩阵相乘的结果.输入第一行是整数m,n,表示第一个矩阵式m行n列的:然后是一个m * n的矩阵.再下一行的输入时整数p,q,表示下一个矩阵p行,q列的(n=p);然后就是一个p行q列的矩 ...

  6. Laravel SQL 查询语句集锦

    1.从数据表中取得单一数据列 $user= DB::table('users')->where('name','John')->first(); 2.检索表中的所有行 复制代码代码如下: ...

  7. 成为Linux内核高手的四个方法

    首页 最新文章 资讯 程序员 设计 IT技术 创业 在国外 营销 趣文 特别分享 更多 > - Navigation -首页最新文章资讯程序员设计IT技术- Java & Android ...

  8. (C++)字符串分割

    题目: 如何对C++中输入的字符串进行分割呢?如“I am a student”,去除空格后分割成为“I”,“am”, “a”, “student”四个单词 思路: 直接参考代码 代码: void s ...

  9. ESXI 6.5 从载到安装

    下载ESXI 访问官网 https://www.vmware.com 到download,选择vsphere 下载esxi https://my.vmware.com/en/group/vmware/ ...

  10. ShopEx customSchema 定制能够依据客户的需求对站点进行对应功能的加入改动或者删除

    站内锚文本制作 1.改动config.php,在文件末尾添加下面内容 define('CUSTOM_CORE_DIR',BASE_DIR . '/custom'); 2.添加custom目录(与cor ...