Press "Enter" to skip to content

利用齐次坐标进行二维坐标转换

利用齐次坐标进行坐标转换

 

Games 101 第0次作业可视化表示

 

作业要求:给定一个点 P = (2,1) , 将该点绕原点先逆时针旋转 45°,再平移 (1,2), 计算出

 

变换后点的坐标(要求用齐次坐标进行计算)

 

目的

 

 

    1. 了解齐次坐标表示矩阵的意义

 

    1. 使用

threejs

tweenjs

    1. 模拟坐标转换过程

 

    1. 创建矩阵进行运算

 

    1. 给定点 P =(2,1),先旋转,后平移,计算变换后的坐标

 

 

程序结果

 

 

第一阶段:描述球绕原点旋转 45°

 

第二阶段:描述球移动 (2, 1)

 

理论基础

 

在二维世界中,旋转和缩放都能使用二维矩阵表示,但平移变换不行

 

为了统一三种坐标变换,使用齐次坐标,利用 3*3 的矩阵进行运算

 

点的表示:(x, y, 1) 向量表示:(x, y, 0)

 

点+向量=向量 向量+向量=向量 点+点=两点中点

 

齐次坐标表示

 

齐次坐标下的旋转矩阵

 

\[\left[ \begin{matrix} cos(θ) & -sin(θ) & 0\\ sin(θ) & cos(θ) & 0 \\ 0 & 0 & 1 \end{matrix} \right] \\ 公式\:1 \]

 

推导过程

 

\[\left( \begin{matrix} x^` \\ y^` \\ 1 \end{matrix} \right) = \left[ \begin{matrix} a & b & 0 \\ c & d & 0 \\ 0 & 0 & 1 \end{matrix} \right] * \left( \begin{matrix} x \\ y \\ 1 \end{matrix} \right) \\ 公式\:2 \]

 

将点 (1, 0, 1) => (cos(θ), sin(θ), 1) 和点 (0, 1, 0) => (-sin(θ), cos(θ), 1) 到公式2,可得到

 

\[a=cos(θ)\\ b=-sin(θ)\\ c=sin(θ)\\ d=cos(θ) \]

 

注意点:旋转矩阵描述的是绕原点,逆时针旋转 θ 角度

 

齐次坐标下的平移变换

 

\[\left[ \begin{matrix} 1 & 0 & t_{x} \\ 0 & 1 & t_{y} \\ 0 & 0 & 1 \end{matrix} \right] \\ 公式\:3 \]

 

平移变换比较简单,推导公式就不表述出来了

 

分析

 

 

    1. 点 P(2, 1) 转换为齐次坐标 P(2, 1, 0)

 

    1. 构建逆时针旋转矩阵 MR,与 P 向量相乘 MR * P 得到旋转后的 P 坐标,P = MR * P

 

    1. 构建平移矩阵 MT, 与 P 向量相乘,P = MT * P

 

    1. 最终得到转换后的结果

 

 

代码实现

 

 

    1. 设置点 P 的坐标

 

 

sphere.position.set(2, 1, 0);

 

 

    1. 构建旋转矩阵

 

 

rotateMatrix.set(
    Math.cos(deg), -Math.sin(deg), 0,
    Math.sin(deg), Math.cos(deg), 0,
    0, 0, 1,
);

 

 

    1. 构建平移矩阵

 

 

transformMatrix.set( 
    1, 0, 1,
    0, 1, 2,
    0, 0, 1
);

 

 

    1. 矩阵运算

 

 

// 原始 P 点
const step0 = vec1.clone();
// 旋转后 P 点
const step1 = step0.clone().applyMatrix3(rotateMatrix);
// 平移后 P 点
const step2 = step1.clone().applyMatrix3(transformMatrix);

 

 

    1. 整个过程采用 tweenjs 进行动画处理

 

 

const tween = new TWEEN.Tween(sphere.position)
    .to({x: step1.x, y:step1.y,z:0 }, 2000)
    .onUpdate(()=>{
        changeText2();
    })
const tween2 = new TWEEN.Tween(sphere.position)
    .to({x: step2.x, y: step2.y, z: 0}, 2000)
    .onUpdate(() => {
        changeText2();
    });

Be First to Comment

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注