Canvas中任意波浪线的绘制

2022-03-26  本文已影响0人  猿创日记

最近接触一个墨水屏的项目,有个需求就是会进行一些标记绘制,类似直线、自由曲线、波浪线等,所以就涉及到波浪线如何绘制。

本篇文章并不会告诉你在 Android 中如何利用 Canvas 去绘制线条。

水平波浪线

其实波浪线就是一段正弦曲线,调整一下振幅、周期,即可达到一段波浪线的效果。

Android 并未提供绘制正弦曲线的 API,所以只能采取描点并连接的方式来绘制。

对于一个函数 y=sin(x) 的图像,即是给定一个 x 的取值范围,然后计算出对应的 y 值,所有的 y 值的描点就构成了 y=sin(x) 的图像。

在实际开发中,不可能取尽所以的 x,所以会采用一定的间隔来进行取点计算,然后使用 lineTo 函数将点连接起来,骗过肉眼,达到水平波浪线的效果。

倾斜波浪线

对于倾斜波浪线,最朴素的想法是对 y=sin(x) 进行平移+角度变换,然后使用同样的方式计算点集并连接。

这里提供另一个思路,就是先对画布进行平移、旋转,然后再逆旋转、逆平移。

  1. 我们根据起点和终点,计算出倾斜的角度 angle,主要用到 Math.atan 函数。
double angle = Math.atan((float) (end.y - start.y) / (float) (end.x - start.x)) * 180 / Math.PI;
  1. 对画布进行平移和旋转。

平移是为了将起点作为坐标原点,避免需要对 y=sin(x) 进行平移变换,旋转是为了画出水平波浪线。用到以下 API

canvas.translate(start.x, start.y);
canvas.rotate((float) angle);
  1. 进行正弦曲线的绘制,x 的取值范围是起始点之间的直线距离。

以下是参考代码

Paint wavePaint = new Paint(paint);
float length = (float) Math.sqrt((end.x - start.x) * (end.x - start.x) + (end.y - start.y) * (end.y - start.y));
Path path = new Path();
path.moveTo(0, sin(0));

int step = 3;
for (int x = step; x < length; x += step) {
  path.lineTo((float) x, sin(x));
}
canvas.drawPath(path, wavePaint);
  1. 对画布进行逆变换
canvas.rotate((float) (-angle));
canvas.translate(-start.x, -start.y);

这样就可以绘制出一个任意倾斜角度的波浪线了。有了这个思路后,类似倾斜椭圆等需求就可以举一反三了。

上一篇下一篇

猜你喜欢

热点阅读