最近接触一个墨水屏的项目,有个需求就是会进行一些标记绘制,类似直线、自由曲线、波浪线等,所以就涉及到波浪线如何绘制。
本篇文章并不会告诉你在
Android
中如何利用Canvas
去绘制线条。
水平波浪线
其实波浪线就是一段正弦曲线,调整一下振幅、周期,即可达到一段波浪线的效果。
但 Android
并未提供绘制正弦曲线的 API
,所以只能采取描点并连接的方式来绘制。
对于一个函数 y=sin(x)
的图像,即是给定一个 x
的取值范围,然后计算出对应的 y
值,所有的 y
值的描点就构成了 y=sin(x)
的图像。
在实际开发中,不可能取尽所以的 x
,所以会采用一定的间隔来进行取点计算,然后使用 lineTo
函数将点连接起来,骗过肉眼,达到水平波浪线的效果。
倾斜波浪线
对于倾斜波浪线,最朴素的想法是对 y=sin(x)
进行平移+角度变换,然后使用同样的方式计算点集并连接。
这里提供另一个思路,就是先对画布进行平移、旋转,然后再逆旋转、逆平移。
- 我们根据起点和终点,计算出倾斜的角度
angle
,主要用到Math.atan
函数。
double angle = Math.atan((float) (end.y - start.y) / (float) (end.x - start.x)) * 180 / Math.PI;
- 对画布进行平移和旋转。
平移是为了将起点作为坐标原点,避免需要对 y=sin(x)
进行平移变换,旋转是为了画出水平波浪线。用到以下 API
:
canvas.translate(start.x, start.y);
canvas.rotate((float) angle);
- 进行正弦曲线的绘制,
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);
- 对画布进行逆变换
canvas.rotate((float) (-angle));
canvas.translate(-start.x, -start.y);
这样就可以绘制出一个任意倾斜角度的波浪线了。有了这个思路后,类似倾斜椭圆等需求就可以举一反三了。