zoukankan      html  css  js  c++  java
  • 利用齐次坐标进行二维坐标转换

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

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

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

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

    目的

    1. 了解齐次坐标表示矩阵的意义
    2. 使用 threejstweenjs 模拟坐标转换过程
    3. 创建矩阵进行运算
    4. 给定点 P =(2,1),先旋转,后平移,计算变换后的坐标

    程序结果

    第0次作业

    第一阶段:描述球绕原点旋转 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)
    2. 构建逆时针旋转矩阵 MR,与 P 向量相乘 MR * P 得到旋转后的 P 坐标,P = MR * P
    3. 构建平移矩阵 MT, 与 P 向量相乘,P = MT * P
    4. 最终得到转换后的结果

    代码实现

    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();
        });
    
    希望读者在看完后能提出意见, 点个赞, 鼓励一下, 我们一起进步. 加油 !!
  • 相关阅读:
    java 获取两个日期相差的毫秒数
    list 去重复
    java日期处理 calendar 和date
    CSS文字超出div或者span时显示省略号
    null类型的字段加1
    CSS或者JS实现鼠标悬停显示另一元素
    去除空格的js 和 使用正则表达式替换
    php preg_replace正则表达式除去<a>
    PHP页面编码问题
    用php生成09,az
  • 原文地址:https://www.cnblogs.com/xiaxiangx/p/15703212.html
Copyright © 2011-2022 走看看