贝济埃曲线
- Path中有很多函数,但是除了一些简单的设置和绘图用法之外,还有一个贝济埃曲线,它可以利用moveTo、LineTo连接的生硬路径边的平滑,也能实现像水波纹那样的效果
- 一阶贝济埃曲线公式:
P0表示起始点,P1表示终点,t表示当前时间,B(t)表示结果值,曲线的意义在于随着时间的变化,B(t)所形成的轨迹,可以理解为在起始点和终点之间形成在直线上匀速移动的点
B(t) = (1-t)P0 + tP1 t属于[0, 1]
- 二阶贝济埃曲线公式:
P0是起始点, P2是终点,P1是控制点,在交叉的贝济埃曲线上形成的点的连线运动的点的轨迹就是二阶贝济埃曲线
B(t) = (1-t)^2P0 + 2t(1-t)P1+t^2P2 t属于[0,1]
- 三阶贝济埃曲线公式:
P0是起始点,P3是终点,P1是第一个控制点,P2是第二个控制点
在三条线形成的框架内,Q0与Q1, Q1与Q2的路径上的点连线的的运动的点的轨迹就是三阶贝济埃曲线
B(t) = P0(1-t)^3 + 3P1(1-t)^2 + 3P2t^2(1-t) + P3t^3 t属于[0, 1]
Android中应用贝济埃曲线:
Path中的贝济埃曲线:
- 函数:
//二阶贝济埃曲线
public void quadTo(float x1, float y1, float x2, float y2)
public void rQuadTo(float x1, float y1, float x2, float y2)
//三阶贝济埃曲线
public void cubicTo(float x1, float y1, float x2, float y2, float x3, float y3)
public void rCubicTo(float x1, float y1, float x2, float y2, float x3, float y3)
- quadTo使用原理:
(x1,y1)是控制点坐标, (x2, y2)是终点坐标
public void quadTo(float x1, flaot y1, float x2, float y2)
- 整条线的起始点是通过Path.moveTo(x,y)来指定的,而如果连续调用quadTo()函数,那么前一个quadTo()的终点就是下一个quadTo()的起点,如果没有调用Path.moveTo()来指定起始点,默认以控件的左上角点(0, 0)为起始点
eg: 实现一个波浪曲线
Path path = new Path();
Paint paint = new Paint();
paint.setColor(Color.BLACK);
paint.setStrokeWidth(2);
paint.setStyle(Paint.Style.STROKE);
path.moveTo(100, 300);
path.quadTo(200, 200, 300, 300);
path.quadTo(400, 400, 500, 300);
canvas.drawPath(path, paint);
- 贝济埃曲线rQuadTo()
//dx1是控制点X的坐标,表示相对上一个终点的x坐标的位移坐标,可为负值,可为正值
//dy1控制点y坐标,表示相对于上一个终点的y坐标的位移坐标
//dx2终点x坐标,相对上一个终点的位移坐标
//dy2终点y坐标,表示相对于上一个终点的y坐标的位移坐标
public void rQuadTo(float dx1, float dy1, float dx2, float dy2)
//比如上一个终点是(300, 400)利用rQuadTo(100, -100, 200, 100)得到的控制点坐标是(300+100,400-100),得到的终点坐标为(300+200, 400+100)
setShadowLayer与阴影效果:
- Android中实现一个为了添加阴影效果的函数,可以定制阴影模糊程度,定制阴影的偏移距离,清除和显示阴影
- 构造函数:
radius:模糊半径,越大越模糊,越小越清晰,如果radius设置为0, 则阴影消失不见
float dx:阴影横向偏移距离,正值向右偏移,负值向左偏移
float dy:阴影的纵向偏移距离,正值向下偏移,复制向上偏移
int color:绘制阴影的画笔颜色,即阴影的颜色(对图片阴影无效)
public void setShadowLayer(float radius, float dx, float dy, int color)
- 该函数使用的是高斯模糊算法,一般在openCV中对图片进行去噪处理。
具体算法是:对于正在处理的每一个像素,取周围若干个像素的RGB值并且平均,这个平均值就是模糊处理的像素,如果对图片的所有像素都这么处理,那么处理完的图片会变得模糊,其中所取的半径就是模糊半径,模糊半径越大,所得的平均像素与原始像素差距就越大,也就越模糊
-
颜色处理对图片无效的原因:
- 使用setShadowLayer()函数所产生的阴影,文字和绘制的图形的阴影都是使用自定义的阴影画笔颜色来绘制的 ,而图片的阴影则是直接产生一张相同的图片,仅对阴影的图片的边缘进行模糊,之所以产生一张相同的阴影图片,是因为如果使用某种颜色来进行绘制,可能会与图片颜色有很大的差距,所以为了解决这个问题就将图片复制一张,然后进行边缘模糊化
- 注意:setShadowLayer()函数只有文字绘制阴影支持硬件加速,其他都不支持硬件加速,所以为了统一标准,就直接在自定义空间中禁用硬件加速
-
setShadowLayer()函数各参数意义:
dx就是将阴影的水平位置进行移动
dy就是将阴影的竖直位置进行移动
radius就是将模糊度进行增加或者减小
注意:
图片的阴影是不受画笔颜色影响的,是一张图片的副本
无论是图片还是副本模糊的位置仅模糊图片的边界部分,随着 radius的扩大,再向内向外延伸
- 清除阴影:
1. 将setShadowLayer()函数的radius参数值设置为0
2. public void clearShadowLayer() 清除阴影的函数
调用:Paint.clearShaddowLayer()函数即可
eg: 给文字添加阴影:
- 在API 1中添加了TextView和TextView派生类来支持阴影效果,有两种方式添加阴影:
- 只有TextView和TextView派生类才有的xml属性:
<TextView
android:shadowRadius = "3"
android:shadowDx = "5"
android:shadowDy = "5"
android:shadowColor="@android:color/darker_gray/>
2. 通过代码添加阴影:
TextView和派生类都有一个Paint.setShadowLayer的同名函数
public void setShadowLayer(float radius, float dx, float dy, int color)
TextView textView = (TextView)findViewById(R.id.tv);
textView.setShadowLayer(2,5,5, Color.GRAY);
```·