我的博客和笔记我的博客和笔记
首页
文章
  • TurboLink
  • TinyEncrypt
  • UnrealStyleGuide
  • AxTrace
  • Cyclone
  • 数学相关
  • 图形学
  • 密码学
  • 编程语言
关于
GitHub
首页
文章
  • TurboLink
  • TinyEncrypt
  • UnrealStyleGuide
  • AxTrace
  • Cyclone
  • 数学相关
  • 图形学
  • 密码学
  • 编程语言
关于
GitHub
  • 我的文章

    • 从抛币协议到智能合约

      • Part1
      • Part2
    • JPEG算法解密

      • Part1
      • Part2
      • Part3
      • Part4
      • Part5
      • Github
    • SPH算法简介

      • Part1
      • Part2
      • Part3
      • Part4
      • Github
    • 赌博中的数学:Martingle策略
    • 如何生成一个随机的圆形
    • 一个简单的DH密钥协商算法的实现
    • 如何计算线段和圆的交点
    • 一道数学趣题
    • 斐波那契数列和1/89
    • 匀速贝塞尔曲线运动的实现
  • 开源项目

    • TurboLink
    • TinyEncrypt
    • UnrealStyleGuide
    • AxTrace
    • Cyclone
  • 学习笔记

    • 数学相关

      • 常用数学符号
      • 群
      • 数论(一)
      • 数论(二)
      • 数论(三)
      • 概率
    • 密码学

      • RSA
      • 抛币协议
      • 智能扑克协议
    • 图形学

      • 数学基础

        • 矢量
        • 矩阵
        • 立体角
        • 几何变换(一)
          • 1. 线性变换
            • 1.1 定义
            • 1.2 举例
            • 1.3 使用矩阵表示
          • 2. 缩放变换
            • 2.1 定义
          • 3. 旋转变换
            • 3.1 正方向约定
            • 3.2 围绕标准轴旋转
            • 3.3 围绕任意轴
        • 几何变换(二)
        • 法线变换
        • 摄像机变换
      • 光照模型

        • 传统光照模型
        • 光度学
        • 双向反射分布函数(BRDF)
        • 微平面理论(一)
        • 微平面理论(二)
        • 微平面理论(三)
        • 光照方程
      • 环境光渲染

        • 环境光渲染(一)
        • 环境光渲染(二)
    • 编程语言

      • JavaScript

        • 环境搭建
        • 基本语法
        • 函数
        • 对象和类

几何变换(一)


1. 线性变换

1.1 定义

假设有某种数学函数τ,输入矢量u→,输出的仍然是一个矢量,且满足以下条件

τ(u+v)=τ(u)+τ(v)τ(ku)=kτ(u)

那么定义τ为线性变换

1.2 举例

比如τ(ux,uy,uz)=(ux2,uy2,uz2)就不是线性变换,因为不满足第二条

1.3 使用矩阵表示

一般使用矩阵表示一个线性变换,设一个三维矢量v→=[x,y,z]T=xi→+yj→+zk→,那么对其做线性变换

(1.3.1)τ(v→)=τ(xi→+yj→+zk→)=τ(i→)x+τ(j→)y+τ(k→)z=[↑↑↑τ(i→)τ(j→)τ(k→)↓↓↓][xyz]=[T11T12T13T21T22T23T31T32T33][xyz]

2. 缩放变换

2.1 定义

定义放缩变换为

S(x,y,z)=(Sxx,Syy,Szz)

用矩阵表示

S=[Sx000Sy000Sz]

3. 旋转变换

以右手坐标系为例

3.1 正方向约定

描述一个旋转角度时,一般约定沿着坐标轴负方向向原点看,逆时针为正方向

3.2 围绕标准轴旋转

3.2.1 结果

围绕x,y,z轴旋转θ的旋转矩阵

Rx=[1000cos⁡(θ)−sin⁡(θ)0sin⁡(θ)cos⁡(θ)]Ry=[cos⁡(θ)0sin⁡(θ)010−sin⁡(θ)0cos⁡(θ)]Rz=[cos⁡(θ)−sin⁡(θ)0sin⁡(θ)cos⁡(θ)0001]

3.2.2 求解过程

以Rz为例

标准矢量i→=[1,0,0]T,j→=[0,1,0]T,k→=[0,0,1]T,经过旋转θ后,结果为

Rz(i→)=[cos⁡(θ),sin⁡(θ),0]TRz(j→)=[−sin⁡(θ),cos⁡(θ),0]TRz(k→)=[0,0,1]T

所以根据公式1.3.1

Rz=[cos⁡(θ)−sin⁡(θ)0sin⁡(θ)cos⁡(θ)0001]

3.3 围绕任意轴

3.3.1 结果

有穿过原点单位轴n→

求围绕该轴旋转θ的旋转矩阵

3.3.2 求解过程

将矢量v→分解成两个矢量的和,一个是平行于n→的分量v→1和垂直于n→的分量v→2

v→=v→1+v→2∥v→1∥=∥v→∥cos⁡(α)∥v→2∥=∥v→∥sin⁡(α)

由于n→是单位矢量,∥n→∥=1,所以

(3.3.2.1)v→⋅n→=∥v→∥∥n→∥cos⁡(α)=∥v→∥cos⁡(α)=∥v→1∥(3.2.2.2)∥v→×n→∥=∥v→∥∥n→∥sin⁡(α)=∥v→∥sin⁡(α)=∥v→2∥

所以根据公式3.3.2.1,v→1和n→同方向,且长度和v→⋅n→相等,所以

(3.3.2.3)v→1=∥v→1∥n→=(v→⋅n→)n→

由于v→1不受旋转影响,所以

(3.3.2.4)Rn(v→)=v→1+Rn(v→2)

Rn(v→2)可以分解成两部分,一部分是平行于v→2的分量v→2cos⁡(θ)另一部分是垂直于v→2的分量v→2sin⁡(θ),联合公式3.2.2.2

(3.3.2.5)Rn(v→2)=v→2cos⁡(θ)+(n→×v→)sin⁡(θ)

代入3.3.2.4可以得到

(3.3.2.6)Rn(v→)=v→1+Rn(v→2)=v→1+v→2cos⁡(θ)+(n→×v→)sin⁡(θ)=v→1+(v→−v→1)cos⁡(θ)+(n→×v→)sin⁡(θ)=v→cos⁡(θ)+(1−cos⁡(θ))v→1+(n→×v→)sin⁡(θ)=v→cos⁡(θ)+(1−cos⁡(θ))(v→⋅n→)n→+(n→×v→)sin⁡(θ)

这个公式称为罗德里格旋转公式Rodrigues' rotation formula,使用以下方法得到其矩阵形式

3.3.3 一般形式

Rn(v→)=v→−v→+v→cos⁡(θ)+(1−cos⁡(θ))(v→⋅n→)n→+(n→×v→)sin⁡(θ)=v→−(1−cos⁡(θ))v→+(1−cos⁡(θ))(v→⋅n→)n→+(n→×v→)sin⁡(θ)=v→+(1−cos⁡(θ))[(v→⋅n→)n→−v→]+(n→×v→)sin⁡(θ)=v→+(1−cos⁡(θ))[(v→⋅n→)n→−(n→⋅n→)v→]+(n→×v→)sin⁡(θ)

根据矢量三重积公式,可以得到

(v→⋅n→)n→−(n→⋅n→)v→=n→×(n→×v→)

所以

Rn(v→)=v→+(1−cos⁡(θ))[n→×(n→×v→)]+(n→×v→)sin⁡(θ)

使用向量n→的叉乘矩阵[n]×来代替叉乘,这里记矩阵Mn为向量n→的叉积矩阵

Mn=[0−nznynz0−nx−nynx0]

使用矩阵形式表达罗德里格旋转公式

Rn(v→)=Iv→+(1−cos⁡(θ))[Mn(Mnv→)]+Mnv→sin⁡(θ)=[I+(1−cos⁡(θ))Mn2+Mnsin⁡(θ)]v→

所以矩阵形式的罗德里格旋转公式的公式为

Rn=I+Mn2(1−cos⁡(θ))+Mnsin⁡(θ)

3.3.4 三维行列式

设n→=[x,y,z]T,c=cos⁡(θ),s=sin⁡(θ)分别将i→,j→,k→带入3.3.2.6,得到

Rn(i→)=ci→+(1−c)(i→⋅n→)n→+(n→×i→)s=[c+(1−c)x2,(1−c)xy+sz,(1−c)xz−sy]TRn(j→)=[(1−c)xy−sz,c+(1−c)y2,(1−c)yz+sx]TRn(k→)=[(1−c)xz+sy,(1−c)yz−sx,c+(1−c)z2]T

代入公式1.3.1得到

Rn=[c+(1−c)x2(1−c)xy−sz(1−c)xz+sy(1−c)xy+szc+(1−c)y2(1−c)yz−sx(1−c)xz−sy(1−c)yz+sxc+(1−c)z2]
Edit this page
Contributors: thejinchao
Prev
立体角
Next
几何变换(二)