缓动数学知识
转自 http://easings.net/en
CSS
CSS properties transition
and animation
allow you to pick the easing function. Unfortunately, theydon’t support all easings and you must specify the desiredeasing function yourself (as a Bezier curve).
Selectan easing function to show its Bezier curve notation.
div {
-webkit-transition: all 600ms
easing’s Bezier curve;
transition: all 600ms
easing’s Bezier curve; }
SCSS
Sass/SCSS candescribe animations too! Compass removes prefixes before the transition
and animation
properties,and the CompassCeaser plugin lets youpass the easing function by name (without specifying the exact Beziercurves).
div {
@include transition(all 600ms ceaser(
$easing name)); }
JavaScript
jQuery with the jQueryEasing Plugin is theeasiest way to describe animation with easing. Pass the easing name (like easeInCirc
) to the .animate()
function as the third argument, or use itas the value of the easing
option.
div.animate({ top: '-=100px' }, 600, '
easing name', function () { … })
unity 由两个向量求夹角
在Unity3D中,有时候我们需要计算二维向量的夹角。二维向量夹角一般在0~180度之前,可以直接调用Vector2.Angle(Vector2 from, Vector2 to)来计算。
但是在有些场景,我们需要-180~180度的夹角,此时可以用下面的脚本进行计算:
float VectorAngle(Vector2 from, Vector2 to)
{
float angle;
Vector3 cross=Vector3.Cross(from, to);
angle = Vector2.Angle(from, to);
return cross.z > 0 ? -angle : angle;
}
1.
1 2 3 |
|
2.
1 2 |
|
3.
数学法:已知a,b两个向量
cosθ=X; (X=(a*b)/(|a|*|b|))
然后求θ=arccosX c#里是Mathf.Acos(X);
如下图
Vector3 srcPos = new Vector3(0,0,0);
Vector3 tarPos = new Vector3(0,0,-1);
Vector3 srcRot = new Vector3(0,90,0);
Quaternion srcQua = Quaternion.Euler(srcRot);
Vector3 direction = tarPos - srcPos;
Vector3 r = Quaternion.Inverse(srcQua) * direction;
Debug.Log(r);
float angle = Mathf.Atan2(r.x, r.z) * Mathf.Rad2Deg;
Debug.Log(angle);
其中结果r为(1,0,0),angle为90 ;
关于Quaternion * Vector3
Quaternion * Vector3就是Vector3进行一次Quaternion 旋转。理论总是枯燥的,下面以实际项目代码为例,这是简化之后的部分项目代码:(c#)
[csharp] view plain copy
Vector3 directionVector = tarPosition - srcPosition;
Vector3 resultDirection = transform.rotation * directionVector;
代码的目的就是计算出当前帧人物应该移动的方向。提一下这是一个FPS项目,即第一人称射击类,当玩家按住向右移动时,人物的旋转是不变的,只是移动
方向相对于玩家是向右,理解这一点很重要。
那么为什么movingDirection就是当前帧人物应该移动的方向呢?
我们不妨假设directionVector=(1,0,1);这就表示玩家想让人物向右移动的同时向前移动,且移动量相同。
至于具体的移动量没有意义,我们随便加一个系数就可以调节移动快慢。
关于Atan2
结果为正表示从 X 轴逆时针旋转的角度,结果为负表示从 X 轴顺时针旋转的角度。
ATAN2(a, b) 与 ATAN(a/b)稍有不同,ATAN2(a,b)的取值范围介于 -pi 到 pi 之间(不包括 -pi),
而ATAN(a/b)的取值范围介于-pi/2到pi/2之间(不包括±pi/2)。
若要用度表示反正切值,请将结果再乘以 180/3.14159。
另外要注意的是,函数atan2(y,x)中参数的顺序是倒置的,atan2(y,x)计算的值相当于点(x,y)的角度值。
Vector3 srcPos = new Vector3(0,0,0);
Vector3 tarPos = new Vector3(0,0,-1);
Vector3 srcRot = new Vector3(0,90,0);
Quaternion srcQua = Quaternion.Euler(srcRot);
Vector3 direction = tarPos - srcPos;
Vector3 r = Quaternion.Inverse(srcQua) * direction;
Debug.Log(r);
float angle = Mathf.Atan2(r.x, r.z) * Mathf.Rad2Deg;
Debug.Log(angle);
其中结果r为(1,0,0),angle为90 ;
关于Quaternion * Vector3
Quaternion * Vector3就是Vector3进行一次Quaternion 旋转。理论总是枯燥的,下面以实际项目代码为例,这是简化之后的部分项目代码:(c#)
[csharp] view plain copy
Vector3 directionVector = tarPosition - srcPosition;
Vector3 resultDirection = transform.rotation * directionVector;
代码的目的就是计算出当前帧人物应该移动的方向。提一下这是一个FPS项目,即第一人称射击类,当玩家按住向右移动时,人物的旋转是不变的,只是移动
方向相对于玩家是向右,理解这一点很重要。
那么为什么movingDirection就是当前帧人物应该移动的方向呢?
我们不妨假设directionVector=(1,0,1);这就表示玩家想让人物向右移动的同时向前移动,且移动量相同。
至于具体的移动量没有意义,我们随便加一个系数就可以调节移动快慢。
关于Atan2
结果为正表示从 X 轴逆时针旋转的角度,结果为负表示从 X 轴顺时针旋转的角度。
ATAN2(a, b) 与 ATAN(a/b)稍有不同,ATAN2(a,b)的取值范围介于 -pi 到 pi 之间(不包括 -pi),
而ATAN(a/b)的取值范围介于-pi/2到pi/2之间(不包括±pi/2)。
若要用度表示反正切值,请将结果再乘以 180/3.14159。
另外要注意的是,函数atan2(y,x)中参数的顺序是倒置
旋转矩阵(Rotation Matrix)的推导及其应用//
世界坐标中的一个点乘以一个四维矩阵,可以实现平移,旋转和缩放等等。
平移就是,旋转和缩放就是(M分别是对应的旋转缩放矩阵)
当中为0时,是向量,为1时,是坐标。
旋转:
缩放:
矩阵如何进行计算呢?之前的文章中有简介一种方法,把行旋转一下,然后与右侧对应相乘。在谷歌图片搜索旋转矩阵时,看到这张动图,觉得表述的很清晰了。
稍微复杂一点的是旋转,如果只是二维也很简单(因为很直观),但因为是三维的,有xyz三个轴,先推导二维的再延伸到三维。
YouTube上有很好的推导过程,视频链接地址(需穿.墙) https://www.youtube.com/watch?v=8XRvpDhTJpw
有点P(Xa,Ya),当坐标由 x –> y 旋转 θ 度后,求该点在新坐标轴的坐标是多少
所以对于二维旋转来讲,旋转矩阵就是
三维旋转,需要先搞清楚正、负方向(使用的是右手法则,在二维平面增加一维z,它的正方向朝向屏幕外)。
绕x轴进行旋转(在yz平面顺时针旋转)
绕y轴进行旋转(在zx平面顺时针旋转)
绕z轴进行旋转(在xy平面顺时针旋转)
— 图片来源:Rotation Matrix -- from Wolfram MathWorld
参考:https://zh.wikipedia.org/wiki/旋转矩阵
了解这些有什么用处呢?之前有讲到渲染被分为三个阶段:应用 –> 几何 –> 栅格化,其中几何阶段做了大量的变换工作。
模型空间 –>( 模型矩阵) –> 世界空间 –> (视图矩阵) –> 观察空间(摄像机,右手坐标系,其余均采用左手) –> (投影矩阵) –> 裁剪空间 –> 屏幕空间,每一次变换都对应着相应的矩阵。
而Unity中的 UNITY_MATRIX_MVP 矩阵表示的是从模型到裁剪坐标的矩阵变换,Model Matrix ● View Matrix ● Projection Matrix。在Unity2017中使用 UnityObjectToClipPos 进行了替换,MVP也即是 模型(M)、视图(V)、透视(P)三个单词的首字母简写。
了解上面这些,才更容易理解Unity内置的变换矩阵
对照下面这张图,更容易理解一些。
VIEW MATRIX
下面是3类基本的2D图形变换。
平移:
设某点向x方向移动 dx, y方向移动 dy ,[x,y]为变换前坐标, [X,Y]为变换后坐标。
则 X = x+dx; Y = y+dy;
以矩阵表示:
1 0 0
[X, Y, 1] = [x, y, 1][ 0 1 0 ] ;
dx dy 1
1 0 0
0 1 0 即平移变换矩阵。
dx dy 1
旋转:
旋转相比平移稍稍复杂:
设某点与原点连线和X轴夹角为b度,以原点为圆心,逆时针转过a度 , 原点与该点连线长度为R, [x,y]为变换前坐标, [X,Y]为变换后坐标。
x = Rcos(b) ; y = Rsin(b);
X = Rcos(a+b) = Rcosacosb - Rsinasinb = xcosa - ysina; (合角公式)
Y = Rsin(a+b) = Rsinacosb + Rcosasinb = xsina + ycosa ;
用矩阵表示:
cosa sina 0
[X, Y, 1] = [x, y, 1][-sina cosa 0 ]
0 0 1
cosa sina 0
-sina cosa 0 为旋转变换矩阵。
0 0 1
缩放
设某点坐标,在x轴方向扩大 sx倍,y轴方向扩大 sy倍,[x,y]为变换前坐标, [X,Y]为变换后坐标。
X = sx*x; Y = sy*y;
则用矩阵表示:
sx 0 0
[X, Y, 1] = [x, y, 1][ 0 sy 0 ] ;
0 0 1
sx 0 0
0 sy 0 即为缩放矩阵。
0 0 1
2D基本的模型视图变换,就只有上面这3种,所有的复杂2D模型视图变换,都可以分解成上述3个。