Giter Club home page Giter Club logo

blog's People

Contributors

iwsr avatar

Watchers

 avatar

blog's Issues

WSL开发环境搭建记录

原文发布在 Github

因为新换的电脑是Windows环境的,所以需要重新搭建开发环境。然而在按照 官方文档 进行搭建时总会被一些奇怪的细节卡住,因此写下这篇文章作为备忘录。后续也会在此补充新遇到的问题。

另外提一句,作为开发(只要不是 .NET 开发),永远不要将项目放到 Windows 环境中。微信小程序是特例(他们不愿意支持 WSL),当然能不碰小程序最好还是别碰小程序。

科学上网

Windows 下的科学上网工具并不直接影响 WSL 内的环境,需要 WSL 环境下对 .bashrc 或 .zshrc 内的配置进行修改。

以下例子基于 Clash for Windows,如果使用的是其他的工具,只需要替换例子中的端口与协议与你本地的环境相同即可。

sudo vim ~/.zshrc

# 获取 WSL 环境的 IP,毕竟其本质是一台虚拟机,因此与宿主环境并不享有同一 IP
## 主机 IP 保存在 /etc/resolv.conf 中
export hostip=$(cat /etc/resolv.conf |grep -oP '(?<=nameserver\ ).*')
# 此处只修改了 https 与 http 的 proxy
export https_proxy="http://${hostip}:7890"
export http_proxy="http://${hostip}:7890"
# 如果需要对所有协议都走代理
export all_proxy="http://${hostip}:7890"

退出 vim 后需要重新配置,或者直接关闭当前 WSL 环境重新打开即可。

更新配置命令如下

source ~/.zshrc

当然也可以将修改配置封装成对于的命令,这样就可以只在需要的时候让环境走代理。

alias proxy='export all_proxy="http://${hostip}:7890"; echo -e "proxy on"' 
alias unProxy='unset all_proxy; echo -e "proxy off"'

在配置完成后,可以使用以下命令检测环境

curl cip.cc

只要走了代理的路径基本就没问题了,如果还是本地运营商可以尝试将工具开启全局代理模式

image

NVM下载

curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/master/install.sh | bash

文档内直接使用该命令即可,但也可能因为不可言说的力量受到阻碍。

curl: (35) OpenSSL SSL_connect: Connection reset by peer in connection to raw.githubusercontent.com:443

此时需要修改 hosts 文件。

 sudo vim /etc/hosts

对应的 IP 地址可以去该 网址 查看

在进入 hosts 文件后在配置下加入

185.199.108.133 raw.githubusercontent.com

上述 IP 地址以你实际查找的结果为准!在成功下载后记得从 hosts 文件中删除,以减少人为原因对后续开发造成影响。

将 Windows 环境内的文件转移到 WSL 下

如果是前端开发,那肯定经常会遇到将项目资料从企业微信或者别的什么的转移到开发项目中,而通常开发项目都会在 Linux 环境下。此时要做的也很简单,直接在文件资源管理器中拖拽就行了。

image

找到对应的 WSL 文件,进入 home 文件夹找到对应的用户即可直接拖拽。

WSL2 占位程序接收到错误数据

电脑启动后立刻打开 WSL 有机会触发这个问题

PowerShell 以管理员权限运行下述命令再重启即可

netsh winsock reset

System has not been booted with systemd as init system (PID 1). Can't operate

参考 System has not been booted with systemd as init system (PID 1). Can't operate 高赞回答

这个问题是在安装 Docker 时遇到的,WSL2基本都支持这个命令,不过需要手动开启。步骤如下:

sudo vim /etc/wsl.conf

添加

[boot]
systemd=true

关闭 Ubuntu,并关闭 WSL

wsl --shutdown

重新打开 Ubuntu,并检查 systemctl 是否运行

sudo systemctl status

后续等我遇到再更新

记一次升级服务器至 https 的过程

省流:有了证书直接改 nginx 的配置即可。

背景

因为在自己的服务器上利用 Nexus 搭建了一个私有的 docker 镜像库,为了支持 K8s 的默认行为不得不将其升级至 https 。当然也有通过设置 /etc/docker/daemon.json 内的 insecure-registries 字段可支持拉取镜像时允许使用 http 请求,但很不幸在 v1.23.6 的 k8s 下这个配置死活不生效。在浪费了近两天的大好时光之后本着能靠花钱解决的问题绝对不死磕的原则,在花费 8 块钱之后顺利解决了(主要是因为买了个域名)。虽然升级服务器到 https 并不复杂,但作为人生的第一次还是觉得有记录一下的意义。

准备 SSL 证书

由于我的服务器是在阿里云那买的,因此后续的域名与证书也是直接通过阿里云获取的。关于申请免费证书的步骤可以看 [这里](https://developer.aliyun.com/article/875508)。当然如果是公司的项目那还是得去花钱买个靠谱证书(2k多一年这特么也太贵了吧!)。不过需要注意的是在获取 SSL 证书前还需要为自己的服务器准备一个域名,毕竟申请的证书需要与域名绑定,虽然也存在与 IP 绑定的 SSL 证书,但这种东西并不常见(至少阿里云没有)。申请域名之后比较麻烦的事情主要在于把域名挂上 DNS 解析(解析服务也能被分档次卖钱。。。建站实在是太贵了!虽然也有免费的QAQ)

将证书上传到服务器

在申请到证书后还需要将证书上传到目标服务器中,可以借助 scp 这一命令

scp fileName user@targetIp:目标文件路径

在连接到远程服务器后需要输入密码进行验证,随后上传到文件便会出现在目标服务器上。

配置 nginx

修改 /etc/nginx/nginx.conf 内的 server 项

server {
        listen       443 ssl http2 default_server;
        listen       [::]:443 ssl http2 default_server;
        server_name  _;
        root         /usr/share/nginx/html;

        ssl_certificate "修改为密钥文件路径";
        ssl_certificate_key "修改为密钥key的路径";
        ssl_session_cache shared:SSL:1m;
        ssl_session_timeout  10m;
        ssl_ciphers PROFILE=SYSTEM;
        ssl_prefer_server_ciphers on;

        # Load configuration files for the default server block.
        include /etc/nginx/default.d/*.conf;

        location / {
        }

        error_page 404 /404.html;
            location = /40x.html {
        }

        error_page 500 502 503 504 /50x.html;
            location = /50x.html {
        }
    }

上面的配置也顺便把服务器开了 http2,也算是个小优化。

配置后重启 nginx 便可生效,随后可通过 curl -I hostName 来进行验证访问,当然也可以使用浏览器来测试,但如果证书出现问题,你只能在浏览器上看见 502 而缺少信息来定位具体问题。

虽然内容有点水,但水文章真开心哇!特别是这种花不了半小时写的东西实在是太快乐了。

欧拉角与万向锁

欧拉角与万向锁

说明

  • 前置阅读:三维图形基本几何变换的矩阵推导
  • 对于在三维空间里的一个参考系,任何坐标系的取向,都可以用三个欧拉角来表现。(三个欧拉角变换可以描述当前物体的姿态)
  • 俯仰(绕z轴旋转)、偏航(绕y轴旋转)、滚动(绕x轴旋转)了解下就行
  • 由于线性变换不符合交换律,那么旋转顺序的不同便会影响结果,下文以动态欧拉角(z-y-x)分析

动态欧拉角

在 [三维图形基本几何变换的矩阵推导](#2) 中已经推导出了分别绕 X、Y、Z轴旋转的旋转矩阵即

$$ R_{z}γ = \begin{pmatrix} cosγ & -sinγ & 0 & 0 \\ sinγ & cosγ & 0 & 0 \\ 0 & 0 & 1 & 0 \\ 0 & 0 & 0 & 1 \end{pmatrix} $$

$$ R_{y}β = \begin{pmatrix} cosβ & 0 & sinβ & 0 \\ 0 & 1 & 0 & 0 \\ -sinβ & 0 & cosβ & 0 \\ 0 & 0 & 0 & 1 \end{pmatrix} $$

$$ R_{x}α = \begin{pmatrix} 1 & 0 & 0 & 0 \\ 0 & cosα & -sinα & 0 \\ 0 & sinα & cosα & 0 \\ 0 & 0 & 0 & 1 \end{pmatrix} $$

那么如果按动态欧拉角的变换顺序,我们将得到变换矩阵 $R=R_{x}αR_{y}βR_{z}γ$

$$ R= R_{x}αR_{y}βR_{z}γ = \begin{pmatrix} \cos β\cos γ & -\cos α\sin γ + \sin α\sin β\cos γ & \sin α \sin γ+ \cos α \sin β \cos γ & 0 \\ \cos β\sin γ & \cos α\cos γ + \sin α\sin β\sin γ & -\sin α \cos γ+ \cos α \sin β \sin γ & 0 \\ -\sin β & \sin α\cos β & \cos α\cos β & 0 \\ 0 & 0 & 0 & 1 \end{pmatrix} $$

万向锁

一旦选择±90°作为pitch角,就会导致第一次旋转和第三次旋转等价,整个旋转表示系统被限制在只能绕竖直轴旋转,丢失了一个表示维度。

上面那段引言用人话说就是当 β 为 ±90°时,绕 x 旋转与绕 z 轴旋转在结果上会等效。

万向锁这个问题如果直接使用变换矩阵 R 来解释的话会很直观,就如下面我们把 β = 90° 代入方程并化简

$$ R = R_{x}αR_{y}90°R_{z}γ = \begin{pmatrix} 1 & 0 & 0 & 0 \\ 0 & cosα & -sinα & 0 \\ 0 & sinα & cosα & 0 \\ 0 & 0 & 0 & 1 \end{pmatrix} \begin{pmatrix} 0 & 0 & 1 & 0 \\ 0 & 1 & 0 & 0 \\ -1 & 0 & 0 & 0 \\ 0 & 0 & 0 & 1 \end{pmatrix} \begin{pmatrix} cosγ & -sinγ & 0 & 0 \\ sinγ & cosγ & 0 & 0 \\ 0 & 0 & 1 & 0 \\ 0 & 0 & 0 & 1 \end{pmatrix} = \begin{pmatrix} 0 & 0 & 1 & 0 \\ sin(α + γ) & cos(α + γ) & 0 & 0 \\ -cos(α + γ) & sin(α + γ) & 0 & 0 \\ 0 & 0 & 0 & 1 \end{pmatrix} $$

很容易发现影响变换矩阵 R 的变量为 α + γ,而在几何上则体现为绕 x 轴的旋转表现与绕 z 轴等效,举例说明则是

$$ R_{x}30°R_{y}90°R_{z}50° = R_{x}0°R_{y}90°R_{z}80° $$

这里需要强调一下,本文中的旋转顺序为 z-y-x,上面的例子可描述为物体绕 z 轴旋转 80°、绕 y 轴旋转90°、绕 x 轴旋转0°其姿态与绕 z 轴旋转80°、绕 y 轴旋转90°、绕 x 轴旋转0°相同。也就是产生万向锁时,空间中物体可通过多种不同的旋转方式转变为某一个特定姿态,即变换与其结果并非一一对应,而这在工程上的体现便是动画插帧会变得极其诡异。

Dec-05-2022 17-25-40

泰勒级数(待补全)

泰勒级数是在数学中极其强大的函数近似工具 —— 3Blue1Brown

这两天重新学习了关于泰勒展开式的内容,决定趁热打铁水一篇文章出来作为学习记录。

泰勒定理的大致**为如果一个函数足够光滑,在已知函数某一点各阶导数的前提下,便可以利用这些导数值作为系数构建一个多项式来近似该函数在这一点的邻域中的值。

公式表达为

$$ g(x) = f(a) + \frac{f^{\prime}(x)}{1!} (x - a) + \frac{f^2(x)}{2!} (x - a)^2 + ... + \frac{f^n(x)}{n!} (x - a)^n + R_n(x) $$

上面的式子暂且先放到一边,这里先解释什么样的函数会被认为是光滑的,一个光滑的函数是具有无限阶导数的函数,它在定义域内的每个点处都可以被无限次微分,且导数在该点处连续。比如 $$y = x$$ ,它的导数为 $$y^{\prime} = 1$$,常数再导下去就一直是 0 了,因此称 $$y = x$$ 是一个一阶光滑的函数。再比如像 $$ y = \sin x $$,它就是一个无限阶光滑的函数,因为其导数无非就是一直循环 $$cos x$$、$$-sin x$$、$$-cos x$$、$$sin x$$。

什么是近似

函数的近似是指使用另一个函数来逼近原函数,使得它们在某个范围内仅存在较小的误差。从这段描述中可以看出,近似可以作为一种计算复杂函数的手段,只需要将一些不好计算的函数近似成好计算的函数即可,仅从语言上理解总觉得有些怪,举个例子或许会更加的直观,比如说遇到需要手算求解 $$\sin 2$$ 的场景通常会将其在零点进行泰勒展开为 $$\varSigma_{n=0}^{+\infty} \frac{(-1)^n}{(2n+1)!} (2)^{2n+1}$$ (这里仅仅是举个例子,后面会介绍如何展开),只需要取前几项便可以求出一个近似解。但不管怎么近似最后必然还是存在误差的(即表达式中$$R_n(x)$$),当然在后面我们还会再讨论到。

如何去近似一个函数

函数在某一点的导数是指这个函数在这一点附近的变化率(可[参考](https://www.bilibili.com/video/BV1Lx411m7Vj/?vd_source=087a5c011e05e20afe8b532203a38c3f)),那么如果对求导后的结果再求导则对应的是该点变化率的变化率,这个关系如果继续向下推的话会变得无穷无尽,总的来说如果想要近似一个函数,那么只要做到使它们的任意 n 阶导数相同即可(只要变化率、变化率的变化率...等等都相同,它们的函数图像必然会无限的接近)。因此如果我们想要近似一个函数 f(x) 可以假设一个对应的 $$g(x) = a_0 + a_1(x) + a_2(x^2) + ... + a_n(x^n)$$ 其中 n 为任意正整数,之所以这么设 g(x) 的目的也很简单,这种形式的表达更方便对其求任意 n 阶段的导数。

对其进行在零点的展开
$$
\begin{cases}
f(0) = g(0) \
f^{\prime}(0) = g^{\prime}(0) \
f^{2}(0) = g^{2}(0) \
. \
. \
f^{n}(0) = g^{n}(0)
\end{cases}
$$
以下是 $$a_n$$ 阶导数的求解过程
$$
\because f^{n}(0) = g^{n}(0) \
\therefore f^{n}(0) = a_n n! \
\therefore a_n = \frac{f^{n}(0)}{n!}
$$

$$ \begin{cases} a_0 = f(0) \\ a_1 = \frac{f^{\prime}(0)}{1!} \\ a_2 = \frac{f^2(0)}{2!} \\ . \\ . \\ a_n = \frac{f^n(0)}{n!} \end{cases} $$

于是我们得到了在零点处泰勒展开的式子(麦克劳林展开)
$$
g(x) = f(0) + \frac{f^{\prime}(0)}{1!} (x) + \frac{f^2(0)}{2!} (x)^2 + ... + \frac{f^n(0)}{n!} (x)^n + R_n(x)
$$
把这个展开变成通式,比如说对 a 点展开,只需要进行一个右移即可
$$
g(x) = f(a) + \frac{f^{\prime}(a)}{1!} (x - a) + \frac{f^2(a)}{2!} (x - a)^2 + ... + \frac{f^n(a)}{n!} (x - a)^n + R_n(x)
$$
我们称上式的 $$R_n(x)$$ 为余项,接下来会进行单独处理。倘若将此项删除,上述等式只能画上约等号,毕竟即使 n 为无穷也会有 n+1 的存在。

对余项 $$R_n(x)$$ 进行处理

推起来太麻烦了,留着以后写。

不管是过程还是结果其实都在表达——目标点与展开点越远,其误差就越大。比如说我们对 sin x 在零点处展开,但是求值时带入的 2,那么这个 2 就是目标点,但为什么允许在零点展开后带入 2 去计算 $$\sin 2$$ 呢?这又与收敛区间有关系,因为 sin 的收敛区间在 ($$-\infty +\infty$$) 上,所以可以直接带入计算。以后再写、以后再写。

齐次坐标与二维图形基本几何变换的矩阵推导

齐次坐标与二维图形基本几何变换的矩阵推导

前言

相比三维的变换,二维的推导还是比较简单的。不过原理都差不多

齐次坐标

“齐次坐标表示是计算机图形学的重要手段之一,它既能够用来明确区分向量和点,同时也更易用于进行仿射(线性)几何变换。”—— F.S. Hill, JR。

正如引用中所说,齐次坐标最大的特点在于它的存在可以区分描述 坐标向量

简单的来说,在普通的直角坐标系(或者说笛卡尔坐标系也行)中,(xA, yA) 可以表示点 A,也可以用来表示向量 $\vec{oA}$。这种含糊不清的表述方式并不利于准确的抽象描述给计算机。

而齐次坐标通过将 n 维提升到 n+1 维从而解决了这个问题。

我们可以在一个2D笛卡尔坐标末尾加上一个额外的变量w来形成2D齐次坐标,因此,一个点(X,Y)在齐次坐标里面变成了(x,y,w),并且有

X = x/w

Y = y/w

如在齐次坐标中

  • 描述一个点 A,其表示为(xA, yA, 1)
  • 描述一个向量 $\vec{oA}$,其表示为(xA, yA, 0)

试着将 w=1,0 带入 x/w,便可以理解为何 1 表示点(位置)、0表示向量(方向)了。

除此之外也方便进行向量加法之类的操作

image

当然除了描述向量与点外,齐次坐标的引入也方便描述几何变换(线性变换)。

比如如果不用齐次坐标表示的二维平移是下图这样的

image

二维图形基本几何变换

二维图形变换大致分为以下五类 —— 平移(Translate)、缩放(Scale)、旋转(Rotate)、反射(Reflect)和错切(shear)

1. 平移

描述从点(x, y)到(x + dx, y+ dy)

引入齐次坐标,可表述为 (x, y, 1) 变形推导为 (x + dx, y+ dy, 1)

此时线性变换便可作为工具描述变换过程了,引入变换矩阵后,该问题就变成了求解变换矩阵

已知:

$$ \begin{pmatrix} a & b & c \\ d & e & f \\ g & h & i \end{pmatrix} \begin{pmatrix} x \\ y \\ 1 \end{pmatrix} = \begin{pmatrix} x + dx \\ y+ dy \\ 1 \end{pmatrix} $$

$$ \begin{cases} ax + by + c = x + dx \\ dx + ey + f = y + dy \\ gx + hy + i = 1 \end{cases} $$

解得变换矩阵为

$$ \begin{pmatrix} 1 & 0 & dx \\ 0 & 1 & dy \\ 0 & 0 & 1 \end{pmatrix} $$

于是在数学层面我们就可以用这个变换矩阵来描述平移过程了。

2. 缩放

描述从点 (x, y) 到 (sx*x, sy*y),sx 与 sy 为常量。

引入齐次坐标,可表述为 (x, y, 1) 变形推导为 (sx*x, sy*y, 1)

引入变换矩阵

已知:

$$ \begin{pmatrix} a & b & c \\ d & e & f \\ g & h & i \end{pmatrix} \begin{pmatrix} x \\ y \\ 1 \end{pmatrix} = \begin{pmatrix} sx * x \\ sy * y \\ 1 \end{pmatrix} $$

$$ \begin{cases} ax + by + c = sx * x \\ dx + ey + f = sy * y \\ gx + hy + i = 1 \end{cases} $$

解得变换矩阵为

$$ \begin{pmatrix} sx & 0 & 0 \\ 0 & sy & 0 \\ 0 & 0 & 1 \end{pmatrix} $$

3. 旋转

解释旋转需要引入单位圆。

image

如图,点 B 旋转至 点 C 处,AB 与 X轴的夹角为 α,AC 与 AB 夹角为 β

则 B 点坐标可表示为(cosα, sinα), C 点坐标为(cos(α + β), sin(α + β))

将 C点坐标展开,则 C 点为 (cosα cosβ - sinα sinβ, sinα cosβ + cosα sinβ)

记 B点坐标为 (x, y), C 点坐标则为 (x cosβ - y sinβ, y cosβ + x sinβ)

引入齐次坐标,可表述为 (x, y, 1) 变形推导为 (x cosβ - y sinβ, y cosβ + x sinβ, 1)

引入变换矩阵

已知:

$$ \begin{pmatrix} a & b & c \\ d & e & f \\ g & h & i \end{pmatrix} \begin{pmatrix} x \\ y \\ 1 \end{pmatrix} = \begin{pmatrix} xcosβ - ysinβ \\ ycosβ + xsinβ \\ 1 \end{pmatrix} $$

$$ \begin{cases} ax + by + c = xcosβ - ysinβ \\ dx + ey + f = ycosβ + xsinβ \\ gx + hy + i = 1 \end{cases} $$

解得变换矩阵为

$$ \begin{pmatrix} cosβ & -sinβ & 0 \\ sinβ & cosβ & 0 \\ 0 & 0 & 1 \end{pmatrix} $$

4. 反射

在数学中,反射是把一个物体变换成它的镜像的映射。要反射一个平面图形,需要“镜子”是一条直线(反射轴),对于三维空间中的反射就要使用平面作为镜子。

如果根据引用,那么反射可分为根据 X 轴反射与根据 Y 轴反射,但实际上也存在中心反射(点反射)这一概念

根据 X 轴反射

描述点 (x, y) 到点 (x, -y)

已知:

$$ \begin{pmatrix} a & b & c \\ d & e & f \\ g & h & i \end{pmatrix} \begin{pmatrix} x \\ y \\ 1 \end{pmatrix} = \begin{pmatrix} x \\ -y \\ 1 \end{pmatrix} $$

得:

$$ \begin{cases} ax + by + c = x \\ dx + ey + f = -y \\ gx + hy + i = 1 \end{cases} $$

解得变换矩阵:

$$ \begin{pmatrix} 1 & 0 & 0 \\ 0 & -1 & 0 \\ 0 & 0 & 1 \end{pmatrix} $$

根据 Y 轴反射

描述点 (x, y) 到点 (-x, y)

已知:

$$ \begin{pmatrix} a & b & c \\ d & e & f \\ g & h & i \end{pmatrix} \begin{pmatrix} x \\ y \\ 1 \end{pmatrix} = \begin{pmatrix} -x \\ y \\ 1 \end{pmatrix} $$

得:

$$ \begin{cases} ax + by + c = -x \\ dx + ey + f = y \\ gx + hy + i = 1 \end{cases} $$

解得变换矩阵:

$$ \begin{pmatrix} -1 & 0 & 0 \\ 0 & 1 & 0 \\ 0 & 0 & 1 \end{pmatrix} $$

根据 点(p, q)反射

描述点 (x, y) 到点 (2p-x, 2q-y)

已知:

$$ \begin{pmatrix} a & b & c \\ d & e & f \\ g & h & i \end{pmatrix} \begin{pmatrix} x \\ y \\ 1 \end{pmatrix} = \begin{pmatrix} 2p-x \\ 2q-y \\ 1 \end{pmatrix} $$

得:

$$ \begin{cases} ax + by + c = 2p-x \\ dx + ey + f = 2q-y \\ gx + hy + i = 1 \end{cases} $$

解得变换矩阵:

$$ \begin{pmatrix} -1 & 0 & 2p \\ 0 & -1 & 2q \\ 0 & 0 & 1 \end{pmatrix} $$

5. 错切

定义见图,其实就像是图形在某一方向上的扭曲,底下只贴推导过程。需注意的是 α 与 β 范围为 [0, 90°)

image

y轴为依赖轴的错切变换

描述点 (x, y) 到点 (x + y.tanα, y)

已知:

$$ \begin{pmatrix} a & b & c \\ d & e & f \\ g & h & i \end{pmatrix} \begin{pmatrix} x \\ y \\ 1 \end{pmatrix} = \begin{pmatrix} x+y.tanα \\ y \\ 1 \end{pmatrix} $$

得:

$$ \begin{cases} ax + by + c = x+y.tanα \\ dx + ey + f = y \\ gx + hy + i = 1 \end{cases} $$

解得变换矩阵:

$$ \begin{pmatrix} 1 & tanα & 0 \\ 0 & 1 & 0 \\ 0 & 0 & 1 \end{pmatrix} $$

x轴为依赖轴的错切变换

描述点 (x, y) 到点 (x, y + x.tanβ)

已知:

$$ \begin{pmatrix} a & b & c \\ d & e & f \\ g & h & i \end{pmatrix} \begin{pmatrix} x \\ y \\ 1 \end{pmatrix} = \begin{pmatrix} x \\ y + x.tanβ \\ 1 \end{pmatrix} $$

得:

$$ \begin{cases} ax + by + c = x \\ dx + ey + f = y + x.tanβ \\ gx + hy + i = 1 \end{cases} $$

解得变换矩阵:

$$ \begin{pmatrix} 1 & 0 & 0 \\ tanβ & 1 & 0 \\ 0 & 0 & 1 \end{pmatrix} $$

三维图形基本几何变换的矩阵推导

三维图形基本几何变换的矩阵推导

前言

此文是 齐次坐标与二维图形基本几何变换的矩阵推导 的衍生。理解二维的变换就能轻松推导三维的。

三维图形基本几何变换

平移

描述从点(x, y, z)到(x + dx, y+ dy, z + dz)

引入齐次坐标,可表述为 (x, y, z, 1) 变形推导为 (x + dx, y+ dy, z + dz, 1)

已知:

$$ \begin{pmatrix} a_{11} & a_{12} & a_{13} & a_{14} \\ a_{21} & a_{22} & a_{23} & a_{24} \\ a_{31} & a_{32} & a_{33} & a_{34} \\ a_{41} & a_{42} & a_{43} & a_{44} \\ \end{pmatrix} \begin{pmatrix} x \\ y \\ z \\ 1 \end{pmatrix} = \begin{pmatrix} x + d_x \\ y+ d_y \\ z + d_z \\ 1 \end{pmatrix} $$

$$ \begin{cases} a_{11}x + a_{12}y + a_{13}z + a_{14} = x + d_x \\ a_{21}x + a_{22}y + a_{23}z + a_{24} = y+ d_y \\ a_{31}x + a_{32}y + a_{33}z + a_{34} = z + d_z \\ a_{41}x + a_{42}y + a_{43}z + a_{44} = 1 \\ \end{cases} $$

解得

$$ \begin{pmatrix} 1 & 0 & 0 & dx \\ 0 & 1 & 0 & dy \\ 0 & 0 & 1 & dz \\ 0 & 0 & 0 & 1 \end{pmatrix} $$

缩放

描述从点 (x, y, z) 到 (sx*x, sy*y, sz*z),sx sy sz 为常量。

引入齐次坐标,可表述为 (x, y, z, 1) 变形推导为 (sx*x, sy*y, sz*z, 1)

已知:

$$ \begin{pmatrix} a_{11} & a_{12} & a_{13} & a_{14} \\ a_{21} & a_{22} & a_{23} & a_{24} \\ a_{31} & a_{32} & a_{33} & a_{34} \\ a_{41} & a_{42} & a_{43} & a_{44} \\ \end{pmatrix} \begin{pmatrix} x \\ y \\ z \\ 1 \end{pmatrix} = \begin{pmatrix} s_x * x \\ s_y * y \\ s_z * z \\ 1 \end{pmatrix} $$

$$ \begin{cases} a_{11}x + a_{12}y + a_{13}z + a_{14} = s_x * x \\ a_{21}x + a_{22}y + a_{23}z + a_{24} = s_y * y \\ a_{31}x + a_{32}y + a_{33}z + a_{34} = s_z * z \\ a_{41}x + a_{42}y + a_{43}z + a_{44} = 1 \\ \end{cases} $$

解得

$$ \begin{pmatrix} s_x & 0 & 0 & 0 \\ 0 & s_y & 0 & 0 \\ 0 & 0 & s_z & 0 \\ 0 & 0 & 0 & 1 \end{pmatrix} $$

旋转

对于三维的旋转可以分解为三个矩阵(绕 x轴旋转、绕 y 轴旋转、绕 z 轴旋转)的乘积

绕 z 轴旋转 —— Rz(β)

还记得我们对二维旋转的推导吗?我们在 x, y 轴构成的平面上进行旋转时其实也可以视为是在绕着 z 轴的旋转。那么其三维的旋转其实就很好理解了,无非就是增加一个固定不变的维度罢了。

即:

$$ \begin{pmatrix} a_{11} & a_{12} & a_{13} & a_{14} \\ a_{21} & a_{22} & a_{23} & a_{24} \\ a_{31} & a_{32} & a_{33} & a_{34} \\ a_{41} & a_{42} & a_{43} & a_{44} \\ \end{pmatrix} \begin{pmatrix} x \\ y \\ z \\ 1 \end{pmatrix} = \begin{pmatrix} xcosβ - ysinβ \\ ycosβ + xsinβ \\ z \\ 1 \end{pmatrix} $$

得:

$$ \begin{cases} a_{11}x + a_{12}y + a_{13}z + a_{14} = xcosβ - ysinβ \\ a_{21}x + a_{22}y + a_{23}z + a_{24} = ycosβ + xsinβ \\ a_{31}x + a_{32}y + a_{33}z + a_{34} = z \\ a_{41}x + a_{42}y + a_{43}z + a_{44} = 1 \\ \end{cases} $$

解:

$$ R_{z}β = \begin{pmatrix} cosβ & -sinβ & 0 & 0 \\ sinβ & cosβ & 0 & 0 \\ 0 & 0 & 1 & 0 \\ 0 & 0 & 0 & 1 \end{pmatrix} $$

绕 x 轴旋转 —— Rx(α)

同理可得(固定x)

$$ R_{x}α = \begin{pmatrix} 1 & 0 & 0 & 0 \\ 0 & cosα & -sinα & 0 \\ 0 & sinα & cosα & 0 \\ 0 & 0 & 0 & 1 \end{pmatrix} $$

绕 y 轴旋转 —— Ry(γ)

同理可得(固定y)

$$ R_{y}γ = \begin{pmatrix} cosγ & 0 & sinγ & 0 \\ 0 & 1 & 0 & 0 \\ -sinγ & 0 & cosγ & 0 \\ 0 & 0 & 0 & 1 \end{pmatrix} $$

于是我们得到了三维的旋转矩阵

$$ R = R_{x}αR_{y}γR_{z}β $$

但是看到这一定会产生这样的疑问 —— 我该如何将绕某个轴的 θ 角分解为 α β γ呢?欧拉角与罗德里格旋转公式间的相互转换,我后面再水一篇文章。

只不过目前旋转的轴都被限制在过原点这一前提下,如果旋转轴并不过原点的话,得先把轴平移到过原点,随后再旋转,旋转结束后再平移到原来的位置。任何复杂的变换都可以分解为数个简单变换的合成。

错切

沿着 X 轴切变

即描述从(x, y, z) 到 (x + my + nz, y, z) —— m, n参考二维的正切,根据选择的角度不同所采用的三角函数也不同

$$
\begin{pmatrix}
a_{11} & a_{12} & a_{13} & a_{14} \
a_{21} & a_{22} & a_{23} & a_{24} \
a_{31} & a_{32} & a_{33} & a_{34} \
a_{41} & a_{42} & a_{43} & a_{44} \
\end{pmatrix}
\begin{pmatrix}
x \
y \
z \
1
\end{pmatrix}
=
\begin{pmatrix}
x + my + nz \
y \
z \
1
\end{pmatrix}
$$

解得

$$ \begin{pmatrix} 1 & m & n & 0 \\ 0 & 1 & 0 & 0 \\ 0 & 0 & 1 & 0 \\ 0 & 0 & 0 & 1 \\ \end{pmatrix} $$

沿着 Y 轴切变

描述点 (x, y, z) 到点 (x, y + mx + nz, z)

求解就跳过了,相信聪明的大家一定看出来了行列项代表的意思了

$$ \begin{pmatrix} 1 & 0 & 0 & 0 \\ m & 1 & n & 0 \\ 0 & 0 & 1 & 0 \\ 0 & 0 & 0 & 1 \\ \end{pmatrix} $$

沿着 Z 轴切变

描述点 (x, y, z) 到点 (x, y, z + mx + ny)

$$ \begin{pmatrix} 1 & 0 & 0 & 0 \\ 0 & 1 & 0 & 0 \\ m & n & 1 & 0 \\ 0 & 0 & 0 & 1 \\ \end{pmatrix} $$

从傅立叶级数到傅立叶变换

从傅立叶级数到傅立叶变换

Games101的第6讲内有涉及到傅立叶变换的内容,课后花了点功夫才搞明白这东西(虽然大学学过但也忘得差不多了),于是写下这篇文章用以记录学习心得。

参考资料中我强烈推荐 DR_CAN 老师的《纯干货数学推导》系列!本文大多都是他课程内的笔记。

本文将从以下几个方面按序推导

  • 三角函数正交性
  • 对周期为2 $\pi$ 的函数进行傅立叶级数展开
  • 对周期为T的函数进行傅立叶级数展开
  • 傅立叶级数的复数形式
  • 对非周期函数进行傅立叶级数展开

需要注意的是,由于我的学识不足因此并不能给出关于傅立叶级数展开公式的证明,就像我不会证明为什么 G=mg 一样,对于真理也许直接拿来用会更简单。但如果觉得不搞明白不舒服的读者来说我更推荐王继良老师写的文章,这篇文章有详细介绍关于傅立叶如何从热传导方程中提炼出傅立叶级数的过程。

傅立叶级数展开 : $f(x) = \frac{a_0}{2} + \varSigma_{n=1}^{+\infty}(a_{n}\cos nx + b_{n}\sin nx)$

三角函数的正交性

如果存在函数 f(x) 与 g(x),且两者满足 $\int_{a}^{b} f(x)g(x) dx = 0$ 那么我们称函数 f(x) 与 g(x) 在区间 [a, b] 正交。

对于三角函数 $0(\sin 0), 1(\cos 0), \sin x, \cos x, \sin 2x, \cos 2x..... \sin nx, \cos nx$ 在区间[- $\pi$, $\pi$ ] 上正交。

$$ \begin{cases} \int_{-\pi}^{\pi} \cos (nx) \sin (mx) dx = 0, \\ \int_{-\pi}^{\pi} \cos (nx) \cos (mx) dx = 0, & n \neq m \\ \int_{-\pi}^{\pi} \sin (nx) \sin (mx) dx = 0 & n \neq m \end{cases} $$

以上积分可根据三角函数的积化和差方式求证,此处只给出其中一个计算过程作为参考

$$
\int_{-\pi}^{\pi} \cos (nx) \sin (mx) dx
= \frac{1}{2} \int_{-\pi}^{\pi} \sin(n+m)x dx - \frac{1}{2} \int_{-\pi}^{\pi} \sin(n-m)x dx \
= \frac{1}{2} [-\frac{1}{n+m} \cos (n+m)x |{-\pi}^{\pi} + \frac{1}{n-m} \cos (n-m)x |{-\pi}^{\pi}] \
= 0
$$

那假如 n = m 会怎么样?对于sin cos这样的组合来说没什么影响,但对于cos cos或者sin sin来说就相当于两个一样的三角函数相乘取积分了,以下给出关于 $\cos mx$$\cos mx$ 组合的求解

$$ \int_{-\pi}^{\pi} \cos (mx) \cos (mx) dx = \int_{-\pi}^{\pi} \frac{1 + \cos (2m)x}{2} dx \\ = \frac{1}{2} (x + \frac{1}{2m} \sin{2mx})|_{-\pi}^{\pi} = \pi $$

记住这里推导的结果,下一节的内容将会用到这些。

对周期为2 $\pi$ 的函数进行傅立叶级数展开

在开始时已经直接给出了傅立叶级数的相关公式,接下来开始介绍如何结合三角函数的正交性来求出公式内的系数。

$a_{0}$

对傅立叶级数展开公式两边求 $-\pi$$\pi$ 的积分

$$ \int_{-\pi}^{\pi} f(x) dx \\ = \int_{-\pi}^{\pi} (\frac{a_0}{2} + \varSigma_{n=1}^{+\infty}(a_{n}\cos nx + b_{n}\sin nx)) dx \\ = \int_{-\pi}^{\pi} \frac{a_0}{2} dx + a_{n} \int_{-\pi}^{\pi} \varSigma_{n=1}^{+\infty} 1 \cos nx dx + b_{n} \int_{-\pi}^{\pi} \varSigma_{n=1}^{+\infty} 1 \sin nx dx $$

在对两边积分后,很明显的能注意到1、 $\cos nx$ 与1、 $\sin nx$ 这两个组合,根据三角函数的正交性不难得出这两对组合的积分结果必然为 0。因此可以直接消去得到以下等式

$$
\int_{-\pi}^{\pi} f(x) dx = \int_{-\pi}^{\pi} \frac{a_0}{2} dx \
= \frac{a_0}{2} \int_{-\pi}^{\pi} 1 dx \
= \frac{a_0}{2} x|{-\pi}^{\pi} \
= a
{0} \pi
$$

于是可得 $a_{0}$

$$ a_{0} = \frac{1}{2}\int_{-\pi}^{\pi} f(x) dx $$

$a_{n}$

对傅立叶级数展开两边都乘上 $\cos mx$ 并求积分

$$ \int_{-\pi}^{\pi} f(x) \cos mx dx \\ = \int_{-\pi}^{\pi} (\frac{a_0}{2} \cos mx + \varSigma_{n=1}^{+\infty}(a_{n}\cos nx \cos mx + b_{n}\sin nx \cos mx)) dx \\ = \frac{a_0}{2} \int_{-\pi}^{\pi} 1 \cos mx dx + a_{n} \int_{-\pi}^{\pi} \varSigma_{n=1}^{+\infty} \cos nx \cos mx dx + b_{n} \int_{-\pi}^{\pi} \varSigma_{n=1}^{+\infty} \sin nx \cos mx dx $$

此时我们根据三角函数正交性可以直接删去 $\frac{a_0}{2} \int_{-\pi}^{\pi} 1 \cos mx dx$$b_{n} \int_{-\pi}^{\pi} \varSigma_{n=1}^{+\infty} \sin nx \cos mx dx$,毕竟最后都是0。但对于中间的 $a_{n} \int_{-\pi}^{\pi} \varSigma_{n=1}^{+\infty} \cos nx \cos mx dx$ 却不能直接整个删除,因为在 $m = n$ 的情况下,其积分结果为 $\pi$

于是我们得到

$$ \int_{-\pi}^{\pi} f(x) \cos mx dx = a_{n} \pi $$

变形得

$$ a_{n} = \frac{1}{\pi} \int_{-\pi}^{\pi} f(x) \cos mx dx $$

$b_{n}$

对傅立叶级数展开两边都乘上 $\sin mx$ 并求积分

$$ \int_{-\pi}^{\pi} f(x) \sin mx dx = \int_{-\pi}^{\pi} (\frac{a_0}{2} \sin mx + \varSigma_{n=1}^{+\infty}(a_{n}\cos nx \sin mx + b_{n}\sin nx \sin mx)) dx $$

省略求证过程,因为和上面的思路是一样的,得

$$ b_{n} = \frac{1}{\pi} \int_{-\pi}^{\pi} f(x) \sin mx dx $$

对周期为 T 的函数进行傅立叶级数展开

对周期为 T 的函数展开的办法有一点巧妙,总的来说是通过参数的变换将式子强行变成 $\pi$ 的形状

设 T = 2L,则有 f(t) = f(t + 2L)

设 x = $\frac{\pi}{L}$ t,则有t = $\frac{Lx}{\pi}$,于是有 f(t) = f( $\frac{Lx}{\pi}$ )

t x
0 0
2L 2 $\pi$
4L 4 $\pi$

如果将 g(x) 视为 f( $\frac{L}{\pi}$ (x)),由上表的对应关系可得,g(x) 的图形可与 f(t) 对应上,举例来说就是 f(2L) = g(2 $\pi$) 这样子。 g(x) 的周期为 2 $\pi$ ,不过在上一节我们便已经得到了关于周期为2 $\pi$的函数的傅立叶展开时的系数。

$$ \begin{cases} a_{0} = \frac{1}{2}\int_{-\pi}^{\pi} g(x) dx \\ a_{n} = \frac{1}{\pi} \int_{-\pi}^{\pi} g(x) \cos nx dx \\ b_{n} = \frac{1}{\pi} \int_{-\pi}^{\pi} g(x) \sin nx dx \end{cases} $$

那么接下来只需要把 x = $\frac{\pi}{L}$ t 带入,

$$ \begin{cases} \cos nx = \cos \frac{n \pi}{L}t \\ \sin nx = \sin \frac{n \pi}{L}t \\ \int_{-\pi}^{\pi} 1 dx = \int_{-L}^{L} 1 d\frac{\pi t}{L} \\ g(x) = f(t) \end{cases} $$

那么就得到了关于周期为 T 的傅立叶级数展开

$$ f(t) = \frac{a_0}{2} + \varSigma_{n=1}^{+\infty}(a_{n}\cos \frac{n \pi}{L}t + b_{n}\sin \frac{n \pi}{L}t) $$

其中(省略计算过程,解法和上一节一致)

$$ \begin{cases} a_{0} = \frac{1}{L}\int_{-L}^{L} f(t) dt \\ a_{n} = \frac{1}{L} \int_{-L}^{L} f(t) \cos \frac{n \pi}{L} t dt \\ b_{n} = \frac{1}{L} \int_{-L}^{L} f(t) \sin \frac{n \pi}{L} t dt \end{cases} $$

如果将 L 换成 T,那就会变成

$$ f(t) = \frac{a_0}{2} + \varSigma_{n=1}^{+\infty}(a_{n}\cos \frac{2n \pi}{T}t + b_{n}\sin \frac{2n \pi}{T}t) $$

$$ \begin{cases} a_{0} = \frac{2}{T}\int_{0}^{T} f(t) dt \\ a_{n} = \frac{2}{T} \int_{0}^{T} f(t) \cos \frac{2 n \pi}{T} t dt \\ b_{n} = \frac{2}{T} \int_{0}^{T} f(t) \sin \frac{2 n \pi}{T} t dt \end{cases} $$

傅立叶级数的复数形式

这一节会用到欧拉公式,对于欧拉公式的证明我后续会再写一篇文章(证明需要用到泰勒展开,尽管欧拉本人并不是用这个办法得到的)

$$ e^{i\theta} = \cos \theta + i \sin \theta $$

$$ \begin{cases} e^{i\theta} = \cos \theta + i \sin \theta \\ e^{i-\theta} = \cos -\theta + i \sin -\theta = \cos \theta - i \sin \theta \end{cases} $$

由上式可得

$$ \begin{cases} \sin \theta = \frac{e^{i \theta} - e^{-i \theta}}{2i} = -i \frac{e^{i \theta} - e^{-i \theta}}{2} \\ \cos \theta = \frac{e^{i \theta} + e^{- i \theta}}{2} \end{cases} $$

$x = \frac{2 \pi t}{T}$ 将这个式子带入到傅立叶级数可得

$$ f(x) = \frac{a_0}{2} + \varSigma_{n=1}^{+\infty}(a_{n} \frac{e^{i nx} + e^{- i nx}}{2} -i b_{n} \frac{e^{i nx} - e^{-i nx}}{2}) \\ = \frac{a_0}{2} + \varSigma_{n=1}^{+\infty} \frac{a_{n} - i b_{n}}{2} e^{i nx} + \varSigma_{n=1}^{+\infty} \frac{a_{n}+i b_{n}}{2} e^{-i nx} $$

接下来的变换会让人脑瓜子疼,但想明白了又会觉得啊原来是这么回事。

$\frac{a_{0}}{2}$ 视为 $\varSigma_{n=0}^{0} \frac{a_{0}}{2} e^{i nx}$,毕竟当 n = 0时, $e^{i nx}$ 也会等于 1,因此能够成立。

$\varSigma_{n=1}^{+\infty} e^{-i nx}$ 的变形也很有意思,将 n 视为 -1 到 - $\infty$,式子就会变成 $\varSigma_{n=-1}^{-\infty} e^{i nx}$

于是得到

$$ f(x) = \varSigma_{n = -\infty}^{+\infty} C_{n} e^{i nx} $$

替换 x

$$ f(t) = \varSigma_{n = -\infty}^{+\infty} C_{n} e^{i \frac{2 n \pi}{T} t} $$

其中

$$ Cn = \begin{cases} \frac{a_{0}}{2}, & n = 0 \\ \frac{a_{n} - i b_{n}}{2} & n = 1,2,3... \\ \frac{a_{-n}+i b_{-n}}{2} & n = -1, -2, -3... \end{cases} $$

由于我们在上一节已经求出了关于周期T函数的傅立叶级数展开

$$ \begin{cases} a_{0} = \frac{2}{T}\int_{0}^{T} f(t) dt \\ a_{n} = \frac{2}{T} \int_{0}^{T} f(t) \cos \frac{2 n \pi}{T} t dt \\ b_{n} = \frac{2}{T} \int_{0}^{T} f(t) \sin \frac{2 n \pi}{T} t dt \end{cases} $$

带入之后可得

$$ Cn = \begin{cases} \frac{1}{T}\int_{0}^{T} f(t) dt, & n = 0 \\ \frac{1}{T} \int_{0}^{T} f(t) (\cos \frac{2n\pi}{T} t - i \sin \frac{2n\pi}{T} t) dt & n > 0 \\ \frac{1}{T} \int_{0}^{T} f(t) (\cos \frac{2n\pi}{T} t - i \sin \frac{2n\pi}{T} t) dt & n < 0 \end{cases} $$

不过表达上有些丑,用欧拉公式化简

$$ \cos \frac{2n\pi}{T} - i \sin \frac{2n\pi}{T} = \cos -\frac{2n\pi}{T} + i \sin -\frac{2n\pi}{T} = e^{-i \frac{2n\pi}{T}} $$

$$ Cn = \begin{cases} \frac{1}{T}\int_{0}^{T} f(t) dt, & n = 0 \\ \frac{1}{T} \int_{0}^{T} f(t) e^{-i \frac{2n\pi}{T} t} dt & n > 0 \\ \frac{1}{T} \int_{0}^{T} f(t) e^{-i \frac{2n\pi}{T} t} dt & n < 0 \end{cases} $$

注意看,带入后 n > 0 与 n < 0 的结果相同,再看 n = 0,其实可以发现其表达与 n > 0 与 n < 0 也相同(带入n=0后 $e^{-i \frac{ 2n \pi }{T}}$ 结果为1)

于是 $C_{n}$ 的表达式可被统一为

$$ C_{n} = \frac{1}{T} \int_{0}^{T} f(t) e^{-i \frac{ 2n \pi }{T} t} dt $$

此时我们设 $\omega_{0}$$\frac{ 2 \pi }{T}$ (工程上的角速度),得到

$$ C_{n} = \frac{1}{T} \int_{0}^{T} f(t) e^{-i n \omega_{0} t} dt $$

于是我们得到了傅立叶级数的复数形式

$$ \begin{cases} f(t) = \varSigma_{n = -\infty}^{+\infty} C_{n} e^{i n \omega_{0} t} \\ C_{n} = \frac{1}{T} \int_{0}^{T} f(t) e^{-i n \omega_{0} t} dt \end{cases} $$

接下来做个小变换。

替换积分的上下限为 [-T/2, T/2] ,然后代入原式可得(周期函数的定积分上下限只要差值为一个周期那么得到的结果都一样)

$$ \begin{cases} f(t) = \varSigma_{n = -\infty}^{+\infty} C_{n} e^{i n \omega_{0} t} \\ C_{n} = \frac{1}{T} \int_{-\frac{T}{2}}^{\frac{T}{2}} f(t) e^{-i n \omega_{0} t} dt \end{cases} $$

对非周期函数进行傅立叶级数展开

对非周期函数进行傅里叶级数展开的处理也很巧妙,大致的**便是将非周期函数视为一个 周期为无穷 的周期函数,随后再用周期函数的展开公式进行变换。

$\frac{1}{T}$$f$ ,由于 T = $\infty$ 所以 $f$ 趋向于无穷小,于是得到

$$ f(t) = \varSigma_{n = -\infty}^{+\infty} (\int_{-\infty}^{\infty} f(t) e^{-i n \omega_{0} t} dt) e^{i n \omega_{0} t} f $$

看上去挺眼熟的不是吗(定积分的定义),由于 $f$ 无限趋近于0,且 $\omega_{0} = \frac{ 2 \pi }{T}$ = 2 $\pi$ f 根据 求和变积分 可得到。

$$ f(t) = \int_{-\infty}^{\infty} (\int_{-\infty}^{\infty} f(t) e^{-i 2 \pi f t} dt) e^{i 2 \pi f t} df $$

不过我想可能大家还是更熟悉下面这个形式

$$ f(t) = \frac{1}{ 2 \pi } \int_{-\infty}^{\infty} (\int_{-\infty}^{\infty} f(t) e^{-i \omega t} dt) e^{i \omega t} d \omega $$

两种表达方式其实都一样,无非一个从频率出发,一个从角速度出发。

其中

$$ F(\omega) = \int_{-\infty}^{\infty} f(t) e^{-i \omega t} dt $$

为傅里叶变换

其中

$$ f(t) = \frac{1}{ 2 \pi } \int_{-\infty}^{\infty} F(\omega) e^{i \omega t} d \omega $$

为傅里叶逆变换

参考资料

纯干货数学推导_傅里叶级数与傅里叶变换_Part5_从傅里叶级数推导傅里叶变换

物联网前沿实践-傅里叶级数

B站首发!草履虫都能看懂的【傅里叶变换】讲解,清华大学李永乐老师教你如何理解傅里叶变换,辨清美颜和变声原理...

形象展示傅里叶变换

罗德里格旋转公式(轴角法)

罗德里格旋转公式(轴角法)

前言

阅读本文需要一些前置知识,需理解向量点积与叉积的基本知识。以下给出大致定义(因为矩阵在这里用不到,就不写矩阵形式了)以帮助理解

  • 向量点积
    • $\vec {v} \cdot \vec {j} = ||\vec {v}|| ||\vec {j}|| \cos \theta$
    • 几何解释为 向量 v 在 向量 j 上投影的模长乘以向量 j 的模长
  • 向量叉积
    • $\vec {v} \times \vec {j} = ||\vec {v}|| ||\vec {j}|| \sin \theta$
    • 叉积只有在三维下才有几何意义,其解释为同时与向量 v 与向量 j 垂直的向量,且该向量模长为向量 v 与向量 j 构成的平行四边形的面积

另外需要注意的是,本文基于右手系分析,旋转方向正负可由右手定则判断。

右手系

右手定则

罗德里格旋转公式

已知旋转轴 $\vec{f}$ ,此时有向量 $\vec{v}$ 绕旋转轴旋转 $\theta$ 角,求旋转后的 $\vec {v^{\prime}}$。如下图

IMG_ECC68942A572-1

因为旋转轴的长度并不影响旋转,为了方便求解,定义 $||\vec {f}|| = 1$。此时分解 $\vec {v}$ 至平面( $\vec {v_\parallel}$ )与旋转轴( $\vec {v_\perp}$ )上。如下图

IMG_D190DB86E9D2-1

由于 $\vec{v_\parallel}$ 可视为 $\vec{v}$$\vec{f}$ 上的投影,显然可以使用点积来表示

$\vec {v_\parallel} = \frac{\vec {v} \cdot \vec {f}}{||\vec {f}||} \frac {\vec {f}}{||\vec {f}||}$

这里解释一下为什么这么写,上面对于点积的介绍已经很明确了即点积的结果表示为向量 v 在 向量 f 上投影的模长乘以向量 f 的模长,也就说我们如果需要单独获得 $|| \vec {v_\parallel} ||$ 时需要将结果除以 $||\vec {f}||$ ,而此时我们得到的是一个值而非向量,且 $\vec {v_\parallel} \parallel \vec {f}$ 也就是两者同向,于是我们可通过将值乘以 $\vec {f}$ 的方向即可得到 $\vec {v_\parallel}$。而又因为 $||\vec {f}||$ 为 1,则可化简为

$$ \vec {v_\parallel} = (\vec {v} \cdot \vec {f})\vec {f} $$

此时也可以得到 $\vec {v_\perp}$

$$ \vec {v_\perp} = \vec {v} - \vec {v_\parallel} = \vec {v} - (\vec {v} \cdot \vec {f})\vec {f} $$

目前已经得到的结果

$$ \begin{cases} \vec {v_\parallel} = (\vec {v} \cdot \vec {f})\vec {f} \\ \vec {v_\perp} = \vec {v} - (\vec {v} \cdot \vec {f})\vec {f} \end{cases} $$

现在我们对 $\vec {v^{\prime}}$ 进行分解,可发现 $\vec {v_\parallel} = \vec {v^{\prime}_\parallel}$ ,唯一的不同在平面上的分解。

IMG_8ADF34270E8C-1

此时我们引入辅助向量 $\vec {w}$ 该向量垂直于 $\vec {v_\perp}$

$$ \because \begin{cases} \vec {w} \perp \vec {f} \\ \vec {w} \perp \vec {v_\perp} \\ || \vec {f} || = 1 \\ || \vec {w} || = || \vec {v_\perp} || \\ \end{cases} $$

$$ \therefore \vec {w} = \vec {f} \times \vec {v_\perp} $$

因为我们最终的目标是通过 $\vec {v一撇垂直}$ 求解 $\vec {v^{\prime}}$ ,那么接下来需要分解 $\vec {v一撇垂直}$$\vec {v_1}$$\vec {v_2}$ ,通过已知的 $\vec {w}$$\vec {v_\perp}$ 来表达(求解思路和上面的 v 平行是一样的)

$$ \vec {v_1} = \frac {\vec {v^{\prime}\perp} \cdot \vec {w}}{||\vec {w}||} \frac {\vec {w}}{||\vec {w}||} = \frac {||\vec {v^{\prime}\perp}|| || \vec {w} || \cos(90° - \theta)}{|| \vec {w} ||} \frac {\vec {w}}{||\vec {w}||} = \vec {w} \sin\theta $$

$$ \vec {v_2} = \frac {\vec {v^{\prime}\perp} \cdot \vec {v\perp}}{||\vec {v_\perp}||} \frac {\vec {v_\perp}}{||\vec {v_\perp}||} = \frac {||\vec {v^{\prime}\perp}|| || \vec {v\perp} || \cos(\theta)}{|| \vec {v_\perp} ||} \frac {\vec {v_\perp}}{||\vec {v_\perp}||} = \vec {v_\perp} \cos\theta $$

$$ \vec {v^{\prime}\perp} = \vec {v_1} + \vec {v_2} = \vec {w} \sin\theta + \vec {v\perp} \cos\theta $$

$$ \because \vec {w} = \vec {f} \times \vec {v_\perp} $$

$$ \therefore \vec {v^{\prime}\perp} = \vec {v\perp} \cos\theta + (\vec {f} \times \vec {v_\perp}) \sin \theta $$

$$ \vec {v^{\prime}} = \vec {v^{\prime}\perp} + \vec {v^{\prime}\parallel} = \vec {v_\perp} \cos\theta + (\vec {f} \times (\vec {v} - \vec {v_\parallel})) \sin \theta + \vec {v_\parallel} $$

$$ \because \vec {f} \parallel \vec {v_\parallel} \therefore \vec {f} \times \vec {v_\parallel} = 0 $$

$$ \vec {v^{\prime}} = \vec {v_\parallel} + \cos \theta \vec {v_\perp} + (\vec {f} \times \vec {v}) \sin \theta $$

$$ \because \begin{cases} \vec {v_\parallel} = (\vec {v} \cdot \vec {f})\vec {f} \\ \vec {v_\perp} = \vec {v} - (\vec {v} \cdot \vec {f})\vec {f} \end{cases} $$

$$ \therefore \vec {v^{\prime}} = (1 - \cos \theta)(\vec {f} \cdot \vec {v}) \vec {f} + \cos \theta \vec {v} + \sin \theta (\vec {f} \times \vec {v})$$

求证结束,此时我们得到了轴角式的旋转公式。

参考资料

《动手学机器人学》(5)(一般形式旋转矩阵公式)或(罗德里格旋转公式)或(轴角法)证明 and 齐次坐标变换

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.