概述
初中数学中的三角函数 sin,cos…是超越函数一类函数,属于初等函数,通常用平面直角坐标系来定义三角函数,如下图。
在中学中我们通常把 sin(x)的 x 赋值为角度,比如 sin(30°)=1/2,而在计算机语言中 x 通常是弧度,sin(π/6)=1/2。
完整的正弦函数是这样的 y = a * sin(wx + b) + h
: a 影响振幅,w 影响周期,h 影响 y 位置,b 为初相。
三角函数在 GUI 中的运用
Android 波浪控件原理
如上图流量管理中的水流效果,音乐频谱的波浪效果都是使用三角函数来实现:
流量管理 在屏幕上绘制出 sin(2π)曲线,然后通过移动 x 位置即可,类似卷轴游戏一样循环移动即可。
音乐频谱 其实和流量管理是一样的,分别代表高中低频的三条波浪,通过动态改变的 a 的值来改变振幅,根据频率强弱变换移动速度。
Android 波浪控件实现
计算坐标点
1 2 3 4 5 6 7 8
| ...
for (int i = 0; i < mViewWidth; i++) { mPointY[i] = (float) (30 * Math.sin(2 * Math.PI * i / mViewWidth)); } ...
|
绘制曲线
1 2 3 4 5
| ... for (int i = 0; i < mViewWidth; i++) { canvas.drawLine(i, mViewWidth - mDynamicPointY[i] - 400, i, mViewHeight, mPaint); } ...
|
卷轴移动
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| ... mXOffset += X_SPEED;
if (mXOffset > mViewWidth) { mXOffset = 0; } ...
...
int yInterval = mPointY.length - mXOffset; System.arraycopy(mPointY, 0, mDynamicPointY, mXOffset, yInterval); System.arraycopy(mPointY, yInterval, mDynamicPointY, 0, mXOffset); ...
|
性能优化
优化刷新率1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); long startTime = System.currentTimeMillis();
...
long endTime = System.currentTimeMillis();
int delay = 0; if ((endTime - startTime) < 30) { delay = (int) (30 - (endTime - startTime)); }
postInvalidateDelayed(delay); }
|
完整代码:https://github.com/gavinliu/BeautifulOfSin
三角函数在动画中的运用
插值器算法
sin(x)随着角度的增大(或减小)而增大(或减小)
cos(x)随着角度的增大(或减小)而减小(或增大)
sin,cos 也是围绕 y 轴不断循环的
所以可以很方便的用来算加速减速,循环,下面举个 Android Property Animation 中的 TimeInterploator 例子
android.view.animation.AccelerateDecelerateInterpolator1 2 3 4 5
| ... public float getInterpolation(float input) { return (float)(Math.cos((input + 1) * Math.PI) / 2.0f) + 0.5f; } ...
|
android.view.animation.CycleInterpolator1 2 3 4 5
| ... public float getInterpolation(float input) { return (float)(Math.sin(2 * mCycles * Math.PI * input)); } ...
|
三角函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115
| sin(a+b)=sinacosb+cosasinb
sin(a-b)=sinacosb-sinbcosa
cos(a+b)=cosacosb-sinasinb
cos(a-b)=cosacosb+sinasinb
tan(a+b)=(tana+tanb)/(1-tanatanb)
tan(a-b)=(tana-tanb)/(1+tanatanb)
cot(a+b)=(cotacotb-1)/(cotb+cota)
cot(a-b)=(cotacotb+1)/(cotb-cota)
倍角公式
tan2a=2tana/[1-(tana)^2]
cos2a=(cosa)^2-(sina)^2=2(cosa)^2 -1=1-2(sina)^2
sin2a=2sina*cosa
半角公式
sin(a/2)=√((1-cosa)/2) sin(a/2)=-√((1-cosa)/2)
cos(a/2)=√((1+cosa)/2) cos(a/2)=-√((1+cosa)/2)
tan(a/2)=√((1-cosa)/((1+cosa)) tan(a/2)=-√((1-cosa)/((1+cosa))
cot(a/2)=√((1+cosa)/((1-cosa)) cot(a/2)=-√((1+cosa)/((1-cosa))
tan(a/2)=(1-cosa)/sina=sina/(1+cosa)
和差化积
2sinacosb=sin(a+b)+sin(a-b)
2cosasinb=sin(a+b)-sin(a-b) )
2cosacosb=cos(a+b)-sin(a-b)
-2sinasinb=cos(a+b)-cos(a-b)
sina+sinb=2sin((a+b)/2)cos((a-b)/2
cosa+cosb=2cos((a+b)/2)sin((a-b)/2)
tana+tanb=sin(a+b)/cosacosb
积化和差公式
sin(a)sin(b)=-1/2*[cos(a+b)-cos(a-b)]
cos(a)cos(b)=1/2*[cos(a+b)+cos(a-b)]
sin(a)cos(b)=1/2*[sin(a+b)+sin(a-b)]
诱导公式
sin(-a)=-sin(a)
cos(-a)=cos(a)
sin(pi/2-a)=cos(a)
cos(pi/2-a)=sin(a)
sin(pi/2+a)=cos(a)
cos(pi/2+a)=-sin(a)
sin(pi-a)=sin(a)
cos(pi-a)=-cos(a)
sin(pi+a)=-sin(a)
cos(pi+a)=-cos(a)
tga=tana=sina/cosa
万能公式
sin(a)= (2tan(a/2))/(1+tan^2(a/2))
cos(a)= (1-tan^2(a/2))/(1+tan^2(a/2))
tan(a)= (2tan(a/2))/(1-tan^2(a/2))
其它公式
a*sin(a)+b*cos(a)=sqrt(a^2+b^2)sin(a+c) [其中,tan(c)=b/a]
a*sin(a)-b*cos(a)=sqrt(a^2+b^2)cos(a-c) [其中,tan(c)=a/b]
1+sin(a)=(sin(a/2)+cos(a/2))^2
1-sin(a)=(sin(a/2)-cos(a/2))^2
其他非重点三角函数
csc(a)=1/sin(a)
sec(a)=1/cos(a)
双曲函数
sinh(a)=(e^a-e^(-a))/2
cosh(a)=(e^a+e^(-a))/2
tgh(a)=sinh(a)/cosh(a)
|
结语
有没有觉得水波纹的效果的实现其实很简单呢,说明数学真的很重要,尤其是线性代数,遗忘得差不多了,回头好好补补课。