Android 绘制 Path

本文探讨了Path.Direction和Path.FillType在UI设计中的使用,解释了顺时针和逆时针方向如何影响图形的填充判断。通过数学函数sin和cos计算特定角度的坐标,用于图形的精确定位。此外,还介绍了PathDashPathEffect在创建虚线和刻度线中的应用,以及如何利用这些原理实现饼图中特定区块的偏移。

Path.Direction

  • 顺时针 Path.Direction.CW

  • 逆时针 Path.Direction.CCW

    mPath.addCircle(dp2px(100F), dp2px(100F), dp2px(50F), Path.Direction.CW)
    mPath.addCircle(dp2px(180F), dp2px(100F), dp2px(50F), Path.Direction.CW)
      
    从任意一点画线,与顺时针的边界相交 +1, 与逆时针的边界相交 -1, 结果为 0 表示在外部, 否则为内部
    

Path.FillType

  • Path.FillType.EVEN_ODD 不考虑方向, 穿插奇数次为内部, 偶数次为外部

    mPath.fillType = Path.FillType.EVEN_ODD
    

Math

println(sin(Math.toRadians(30.0)))      结果: 0.49999999999999994
println(sin(Math.toRadians(150.0)))     结果: 0.49999999999999994
println(cos(Math.toRadians(30.0)))      结果: 0.8660254037844387
println(cos(Math.toRadians(150.0)))     结果: -0.8660254037844387
  • 这里根据正余弦的图可以想到,

    正弦值 30° 和 150° 都在 x 轴上方, 相对于 90° 对称, 所以结果相等
    余弦值 30° 在 x 轴上方, 150° 在 x 轴下方, 大小相等, 方向相反 
    

PathDashPathEffect

  • 这个本来是用来画虚线的, 但是画刻度也是可以的, 理解成弯曲的垂直曲线…

    Path shape      虚线的样子, 通过 addRect(0F, 0F, dp2px(2F), dp2px(10F), Path.Direction.CW) 设置成指定大小的矩形
    float advance   两个虚线之间的间隔 
    float phase     开始绘制的时候的偏移
    Style style     style, 这个还没搞懂, 但是效果先出来了...
    
    // 绘制刻度
    mPaint.pathEffect = mPathEffect
    canvas.drawArc(mRectF, 90F + mAngle / 2F, 360F - mAngle, false, mPaint)
    mPaint.pathEffect = null
    

饼图其中一块偏移

要将 A 块偏移出去, 思路是计算要偏移出去的角度, 然后根据要偏移出去的距离的 cos/sin 函数, 计算出 translation x/y 坐标

偏移的角度是 A 块的开始角度 + A块总共的大小的一半

x: cos(Math.toRadians(currAngle + ANGLES[i] / 2.0)).toFloat() * PULLED_LENGTH
y: sin(Math.toRadians(currAngle + ANGLES[i] / 2.0)).toFloat() * PULLED_LENGTH
### 使用 Android Canvas 绘制 Path 的详细解释 #### 创建 Path 对象 为了在 `Canvas` 上绘制路径 (`Path`),首先需要创建一个 `Path` 实例。此对象允许定义复杂的形状和线条。 ```java Path path = new Path(); ``` #### 定义路径数据 通过调用 `Path` 类的方法来构建想要绘制的具体路径。常用方法有: - `moveTo(float x, float y)`:移动到指定位置而不画线。 - `lineTo(float x, float y)`:从当前点向给定坐标绘制直线并更新当前位置。 - `quadTo(float x1, float y1, float x2, float y2)` 或者 `rQuadTo()` :用于添加二次贝塞尔曲线段。 - `cubicTo(float x1, float y1, float x2, float y2, float x3, float y3)` 或者 `rCubicTo()` : 添加三次方程控制的贝塞尔曲线段。 - `close()`:闭合子路径,即连接起点与终点形成封闭区域[^1]。 #### 设置 Paint 属性 为了让绘图效果更加美观,在实际绘制之前还需要配置好 `Paint` 对象的相关属性,如颜色、宽度以及样式等。 ```java Paint paint = new Paint(); paint.setColor(Color.BLUE); paint.setStrokeWidth(5f); paint.setStyle(Paint.Style.STROKE); // 可选 STROKE/FILL/STROKE_AND_FILL ``` #### 执行绘制命令 最后一步是在重写的 `onDraw(Canvas canvas)` 方法内利用上述准备好的 `Path` 和 `Paint` 来完成具体的绘制工作。 ```java @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); // 开始定义path path.moveTo(50, 50); path.lineTo(150, 50); path.quadTo(200, 0, 250, 50); path.cubicTo(300, 100, 400, -50, 500, 50); // 调用canvas.drawPath()函数进行绘制 canvas.drawPath(path, paint); } ``` 以上代码片段展示了如何使用基本几何变换组合成复杂图形,并将其呈现在屏幕上。值得注意的是所有的这些操作最终都会被转换为 OpenGL ES 命令并通过 GPU 加速处理以提高效率。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值