We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
向量运算是计算机图形学的数学基础,而向量的旋转是向量的一种常见操作,本文将详细讲解向量在二维空间下的旋转原理。
在前端项目中,旋转一个元素我们会使用CSS的 rotate 函数,本文会让你对 rotate 有一个全新的认识。
rotate
二维中间中的向量其实就是一个包含了两个数值的数组,一个是 x 坐标值,一个是 y 坐标值。
向量既可以表示一个 “点”(x, y),也可以表示一个从原点(0,0)到坐标点(x, y)的 “线” 称为 “向量”。
向量的旋转指的是将一个已知向量旋转给定的弧度后得到一个旋转后的新向量,也就是说我们使用 “向量” 和 “弧度” 求出旋转后的“新向量”。我们通过一段伪代码来描述:
/** * v1: 原始向量 * v2: 旋转后的新向量 * rad: 旋转弧度 */ const v2 = v1.rotate(rad);
若想实现一个 rotate 函数来旋转向量,“矩阵的线性变换” 可以帮助我们做到这一点。
当一个矩阵和一个向量做乘法时,将产生一个新的向量(可以理解为:向量和矩阵做乘法描述了一个运动),矩阵描述了一个二维空间如何变换(旋转、拉伸等),向量相当于一个入参。
这与函数类似,当一个矩阵描述了二维空间逆时针旋转90°,那么任意一个向量与该矩阵做乘法时,都会得到一个逆时针旋转了90°的新向量。
$$ \begin{pmatrix} 1 & 2 \\ 3 & 4 \\ \end{pmatrix} \times \begin{pmatrix} x \\ y \\ \end{pmatrix} =x \begin{pmatrix} 1 \\ 3 \\ \end{pmatrix} + y \begin{pmatrix} 2 \\ 4 \\ \end{pmatrix} = \begin{pmatrix} 1x + 2y \\ 3x + 4y \\ \end{pmatrix} $$
上面公式中,左侧的 2x2 的矩阵描述了二维空间如何变换,右侧的 (x, y) 是一个向量,整体计算过程给出了矩阵和向量通过乘法得到一个新的向量。
2x2
(x, y)
为什么 2x2 的矩阵可以描述二维空间如何变换?这个问题很关键,因此这里单独用一个小节展开介绍一下。
空间中的任意线性变换都可以由“基向量”的变换来表示,而基向量的数量与维度保持一致,比如二维空间中,基向量就是两个被称为:i 帽和 j 帽的向量。这两个基向量都有各自的x坐标(1, 0)和y坐标(0, 1),因此加起来就是一个 2x2 的矩阵:
i
j
x
y
$$ \begin{pmatrix} 1 & 0 \\ 0 & 1 \\ \end{pmatrix} $$
左列表示 i 帽,右列表示 j 帽,上面的数字为 x 坐标,下面的数字为 y 坐标,空间中的表示如下图所示:
如上图所示,向量 v 是由基向量 i 帽和 j 帽相加得到的,因此当 i 帽和 j 帽的坐标发生变化时,向量 v 就会发生变化,比如逆时针旋转90°,那么矩阵值为:
v
此时 2x2 矩阵值为:
$$ \begin{pmatrix} 0 & -1 \\ 1 & 0 \\ \end{pmatrix} $$
空间中的表示如下图所示:
由于整个空间是线性变化的,因此基向量的变化等同于该空间下任意向量、坐标、图形的变化。
举个例子🌰:空间中任意一个向量 v→(3, 2),与上面的矩阵相乘,将得到一个全新的逆时针旋转90°后的新向量:
v→(3, 2)
$$ \begin{pmatrix} 0 & -1 \\ 1 & 0 \\ \end{pmatrix} \times \begin{pmatrix} 3 \\ 2 \\ \end{pmatrix} =3 \begin{pmatrix} 0 \\ 1 \\ \end{pmatrix} + 2 \begin{pmatrix} -1 \\ 0 \\ \end{pmatrix} = \begin{pmatrix} 3 * 0 + 2 * -1 \\ 3 * 1 + 2 * 0 \\ \end{pmatrix} = \begin{pmatrix} -2 \\ 3 \\ \end{pmatrix} $$
回到我们的主题,就是说,当我们拥有矩阵和向量时,我们就可以得到变换后的新向量。向量是我们已知的,矩阵我们暂时还没有,但我们有一个弧度值,所以我们要做一件事,就是将弧度转化为矩阵。然后再用这个矩阵和向量做乘法得出变换后的新向量。
本节介绍一种通过弧度值来计算旋转后基向量 i 帽与 j 帽坐标的方法。
旋转前,基向量 i 帽的坐标为:(1, 0),旋转后 i 帽的坐标是:(cosθ, sinθ)。
$$ 旋转前 i 帽的坐标: \begin{pmatrix} 1 \\ 0 \\ \end{pmatrix} \ \ \ \ \ \ \ \ \ \\ 旋转后 i 帽的坐标: \begin{pmatrix} cosθ \\ sinθ \\ \end{pmatrix} $$
计算 i 帽旋转后的坐标,本质上是计算旋转后的 i 帽在 x 轴的位置以及在 y 轴的位置。
旋转后的 i 帽在 x 轴的位置等同于旋转后的 i 帽在旋转前 i 帽上的投影,如下图所示:
向量 a 在向量 b 上的投影等于两个向量夹角的余弦值乘以向量 a 的长度,反过来 b 在 a 上的投影就是余弦值乘以向量 b 的长度。
a
b
在我们的场景里就是旋转后 i 帽和旋转前 i 帽夹角的余弦值乘以 i 帽的长度,而由于 i 帽的长度为 1,因此余弦值就是我们要的 i 帽旋转后在 x 轴的坐标。
至此,我们得到了旋转后 i 帽的 x 坐标:cosθ。
cosθ
旋转后的 i 帽在 y 轴的位置,我们可以用夹角的正弦值来计算。用夹角与边长来求出三角形的第三条边,而这第三条边的长度就是旋转后 i 帽在 y 轴的位置,如下图所示:
如上图所示,边 d 等于旋转后的 i 帽在 y 轴的位置等于 sinθ,我们用一个简单的推导步骤来证明:
d
sinθ
sinθ = 对边 / 斜边 已知斜边边长为 1(i帽长度为1,旋转后长度不变) sinθ = d / 1 d / 1 = sinθ d = sinθ * 1 d = sinθ
至此,我们得出旋转后 i 帽的 y 坐标:sinθ,同时我们也得到了旋转后 i 帽的完整坐标:
$$ \begin{pmatrix} cosθ \\ sinθ \\ \end{pmatrix} $$
获取 j 帽旋转后的坐标方法与获取 i 帽一样,仍然是通过夹角的正弦值与余弦值来获取坐标。旋转前,基向量 j 帽的坐标为:(0, 1),旋转后 j 帽的坐标是:(-sinθ, cosθ):
$$ 旋转前 j 帽的坐标: \begin{pmatrix} 0 \\ 1 \\ \end{pmatrix} \ \ \ \ \ \ \ \ \ \\ 旋转后 j 帽的坐标: \begin{pmatrix} -sinθ \\ cosθ \\ \end{pmatrix} $$
由于旋转后的 j 帽在旋转前 j 帽上的投影是投在了 y 轴,因此 cosθ 得到的是旋转后 j 帽在 y 轴的位置。同理,sinθ 则是旋转后 j 帽在 x 轴的位置,由于在 x 轴小于0的位置,因此需要给位置(sinθ)加一个负号:-sinθ,如下图所示:
-sinθ
至此,我们得到了旋转后 j 帽的完整坐标:
$$ \begin{pmatrix} -sinθ \\ cosθ \\ \end{pmatrix} $$
通过本小节的详细介绍,我们得知了一种通过弧度值来计算旋转矩阵(旋转后基向量 i 帽与 j 帽坐标)的方法,旋转矩阵如下:
$$ \begin{pmatrix} cosθ & -sinθ \\ sinθ & cosθ \\ \end{pmatrix} $$
向量的旋转指的是将一个已知向量旋转给定的弧度或角度后得到一个旋转后的新向量。矩阵描述了一个二维空间如何变换,当一个矩阵和一个向量做乘法时,将产生一个新的向量。而这个描述了空间如何变换的矩阵可以通过弧度计算得出。
至此,我们已经掌握了向量旋转的理论知识,一个完整的向量旋转矩阵计算如下所示:
$$ \begin{pmatrix} cosθ & -sinθ \\ sinθ & cosθ \\ \end{pmatrix} \times \begin{pmatrix} x \\ y \\ \end{pmatrix} =x \begin{pmatrix} cosθ \\ sinθ \\ \end{pmatrix} + y \begin{pmatrix} -sinθ \\ cosθ \\ \end{pmatrix} = \begin{pmatrix} x * cosθ + y * -sinθ \\ x * sinθ + y * cosθ \\ \end{pmatrix} $$
通过上一节详细的介绍,我们产出了一个公式:
最左侧的 2x2 矩阵是使用弧度计算出来的,与右边的向量做乘法,得出最后的一个新的向量,代码中直接使用最后一步生产出来的那个向量即可,代码如下:
/** * @param {[x, y]} v 原始向量 * @param {number} rad 旋转弧度 * @return {[x, y]} 旋转后的新向量 */ function rotate(v, rad) { const c = Math.cos(rad); const s = Math.sin(rad); const [x, y] = v; return [ x * c + y * -s, x * s + y * c ]; }
Demo designed by 月影
The text was updated successfully, but these errors were encountered:
Hi, 你那个2.1.1举个例子的那个例子的向量相乘少写了乘号哦
Sorry, something went wrong.
@LinearLaw 还真是,乘号左右没加空格渲染的时候竟然给隐藏了,已经改好啦~
berwin
No branches or pull requests
二维空间下的向量旋转
向量运算是计算机图形学的数学基础,而向量的旋转是向量的一种常见操作,本文将详细讲解向量在二维空间下的旋转原理。
1. 向量
二维中间中的向量其实就是一个包含了两个数值的数组,一个是 x 坐标值,一个是 y 坐标值。
向量既可以表示一个 “点”(x, y),也可以表示一个从原点(0,0)到坐标点(x, y)的 “线” 称为 “向量”。
2. 向量的旋转
向量的旋转指的是将一个已知向量旋转给定的弧度后得到一个旋转后的新向量,也就是说我们使用 “向量” 和 “弧度” 求出旋转后的“新向量”。我们通过一段伪代码来描述:
若想实现一个
rotate
函数来旋转向量,“矩阵的线性变换” 可以帮助我们做到这一点。2.1 矩阵的线性变换
当一个矩阵和一个向量做乘法时,将产生一个新的向量(可以理解为:向量和矩阵做乘法描述了一个运动),矩阵描述了一个二维空间如何变换(旋转、拉伸等),向量相当于一个入参。
这与函数类似,当一个矩阵描述了二维空间逆时针旋转90°,那么任意一个向量与该矩阵做乘法时,都会得到一个逆时针旋转了90°的新向量。
上面公式中,左侧的
2x2
的矩阵描述了二维空间如何变换,右侧的(x, y)
是一个向量,整体计算过程给出了矩阵和向量通过乘法得到一个新的向量。2.1.1 基向量
为什么
2x2
的矩阵可以描述二维空间如何变换?这个问题很关键,因此这里单独用一个小节展开介绍一下。空间中的任意线性变换都可以由“基向量”的变换来表示,而基向量的数量与维度保持一致,比如二维空间中,基向量就是两个被称为:
i
帽和j
帽的向量。这两个基向量都有各自的x
坐标(1, 0)和y
坐标(0, 1),因此加起来就是一个2x2
的矩阵:左列表示
i
帽,右列表示j
帽,上面的数字为x
坐标,下面的数字为y
坐标,空间中的表示如下图所示:如上图所示,向量
v
是由基向量i
帽和j
帽相加得到的,因此当i
帽和j
帽的坐标发生变化时,向量v
就会发生变化,比如逆时针旋转90°,那么矩阵值为:此时
2x2
矩阵值为:空间中的表示如下图所示:
由于整个空间是线性变化的,因此基向量的变化等同于该空间下任意向量、坐标、图形的变化。
举个例子🌰:空间中任意一个向量
v→(3, 2)
,与上面的矩阵相乘,将得到一个全新的逆时针旋转90°后的新向量:空间中的表示如下图所示:
2.1.2 小结
回到我们的主题,就是说,当我们拥有矩阵和向量时,我们就可以得到变换后的新向量。向量是我们已知的,矩阵我们暂时还没有,但我们有一个弧度值,所以我们要做一件事,就是将弧度转化为矩阵。然后再用这个矩阵和向量做乘法得出变换后的新向量。
2.2 将弧度值转化为矩阵
本节介绍一种通过弧度值来计算旋转后基向量
i
帽与j
帽坐标的方法。2.2.1 基向量
i
帽旋转后的坐标旋转前,基向量
i
帽的坐标为:(1, 0),旋转后i
帽的坐标是:(cosθ, sinθ)。计算
i
帽旋转后的坐标,本质上是计算旋转后的i
帽在x
轴的位置以及在y
轴的位置。旋转后的
i
帽在x
轴的位置等同于旋转后的i
帽在旋转前i
帽上的投影,如下图所示:向量
a
在向量b
上的投影等于两个向量夹角的余弦值乘以向量a
的长度,反过来b
在a
上的投影就是余弦值乘以向量b
的长度。在我们的场景里就是旋转后
i
帽和旋转前i
帽夹角的余弦值乘以i
帽的长度,而由于i
帽的长度为 1,因此余弦值就是我们要的i
帽旋转后在x
轴的坐标。至此,我们得到了旋转后
i
帽的x
坐标:cosθ
。旋转后的
i
帽在y
轴的位置,我们可以用夹角的正弦值来计算。用夹角与边长来求出三角形的第三条边,而这第三条边的长度就是旋转后i
帽在y
轴的位置,如下图所示:如上图所示,边
d
等于旋转后的i
帽在y
轴的位置等于sinθ
,我们用一个简单的推导步骤来证明:至此,我们得出旋转后
i
帽的y
坐标:sinθ
,同时我们也得到了旋转后i
帽的完整坐标:2.2.2 基向量
j
帽旋转后的坐标获取
j
帽旋转后的坐标方法与获取i
帽一样,仍然是通过夹角的正弦值与余弦值来获取坐标。旋转前,基向量j
帽的坐标为:(0, 1),旋转后j
帽的坐标是:(-sinθ, cosθ):由于旋转后的
j
帽在旋转前j
帽上的投影是投在了y
轴,因此 cosθ 得到的是旋转后j
帽在y
轴的位置。同理,sinθ 则是旋转后j
帽在x
轴的位置,由于在x
轴小于0的位置,因此需要给位置(sinθ)加一个负号:-sinθ
,如下图所示:至此,我们得到了旋转后
j
帽的完整坐标:2.2.3 小结
通过本小节的详细介绍,我们得知了一种通过弧度值来计算旋转矩阵(旋转后基向量
i
帽与j
帽坐标)的方法,旋转矩阵如下:2.3 小结
向量的旋转指的是将一个已知向量旋转给定的弧度或角度后得到一个旋转后的新向量。矩阵描述了一个二维空间如何变换,当一个矩阵和一个向量做乘法时,将产生一个新的向量。而这个描述了空间如何变换的矩阵可以通过弧度计算得出。
至此,我们已经掌握了向量旋转的理论知识,一个完整的向量旋转矩阵计算如下所示:
3. 向量旋转的代码实现
通过上一节详细的介绍,我们产出了一个公式:
最左侧的
2x2
矩阵是使用弧度计算出来的,与右边的向量做乘法,得出最后的一个新的向量,代码中直接使用最后一步生产出来的那个向量即可,代码如下:4. Demo展示:基于向量旋转实现的一棵树
The text was updated successfully, but these errors were encountered: