1️⃣2️⃣three.js_物体的镜像

12、物体的镜像

12.1、克隆镜像的另一半

  • 镜像(Mirror Reflection)是指物体相对于某个参考平面或坐标轴进行对称变换的操作。
    请添加图片描述

  • 在父级坐标系中,物体镜像变换的数学本质是对指定轴向的坐标值进行取反操作。

     //先定位货车左边
     const tempScene = scene.children.find(t => t.name == 'Scene')
     const tempTruck = tempScene.children.find(t => t.name == 'Truck');//父级,空物体
     const tempTruckLeft = tempTruck.children.find(t => t.name == 'TruckLeft'); //货车左边
     //克隆出货车右边
     const newTruck1Right= tempTruckLeft.clone() 
     newTruck1Right.name = 'TruckRight'
     //矩阵镜像变换
     const mirrorMatrix = new THREE.Matrix4().makeScale(-1, 1, 1); 
     newTruck1Right.applyMatrix4(mirrorMatrix)
     newTruck1Right.updateMatrix();
     console.log('当前矩阵:', newTruck1Right.matrix);
     //newTruck1Right.translateX(3)
     tempTruck.add(newTruck1Right)
    
  • 现实世界中广泛存在对称结构的物体(如人体、车辆、建筑等)。通过镜像变换技术,可以高效生成对称部分,不仅能大幅降低建模工作量,还能有效优化模型存储空间。
    请添加图片描述

  • 镜像前矩阵与镜像后矩阵对比(如需了解矩阵,请参考物体的平移、缩放、旋转说明 )
    M = [ 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 ] M = [ − 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 ] M = \begin{bmatrix} 1 & 0 & 0 & 0 \\ 0 & 1 & 0 & 0 \\ 0 & 0 & 1 & 0 \\ 0 & 0 & 0 & 1 \end{bmatrix} \quad \quad M = \begin{bmatrix} -1 & 0 & 0 & 0 \\ 0 & 1 & 0 & 0 \\ 0 & 0 & 1 & 0 \\ 0 & 0 & 0 & 1 \end{bmatrix} M= 1000010000100001 M= 1000010000100001

  • 任意一顶点:
    v = ( 2 ,   5 ,   6 ,   1 ) v = (2,\ 5,\ 6,\ 1) v=(2, 5, 6, 1)

  • 计算步骤
    v ′ = M ∗ v = [ − 1 ∗ 2 + 0 ∗ 5 + 0 ∗ 6 + 0 ∗ 1 0 ∗ 2 + 1 ∗ 5 + 0 ∗ 6 + 0 ∗ 1 0 ∗ 2 + 0 ∗ 5 + 1 ∗ 6 + 0 ∗ 1 0 ∗ 2 + 0 ∗ 5 + 0 ∗ 6 + 1 ∗ 1 ] = [ − 2 5 6 1 ] v' = M \ast v = \begin{bmatrix} -1 * 2 + 0 * 5 + 0 * 6 + 0 * 1 \\ 0 * 2 + 1 * 5 + 0 * 6 + 0 * 1 \\ 0 * 2 + 0 * 5 + 1 * 6 + 0 * 1 \\ 0 * 2 + 0 * 5 + 0 * 6 + 1 * 1 \end{bmatrix} = \begin{bmatrix} -2 \\ 5 \\ 6 \\ 1 \end{bmatrix} v=Mv= 12+05+06+0102+15+06+0102+05+16+0102+05+06+11 = 2561

  • 从变换结果可以看出,关键代码 mirrorMatrix = new THREE.Matrix4().makeScale(-1, 1, 1); 使得物体在X轴方向的坐标值发生了符号反转。

  • 🛑需要特别注意的是,货车的镜像变换是在父级坐标系(空物体坐标系)下进行的,其变换效果是使货车相对于父级坐标原点的X轴坐标值发生符号反转。

12.2、物体镜像变换

  • 物体经过镜像变换后,其原有的空间关系会发生对调。例如,若原始物体一侧为墙、另一侧为窗户,镜像后二者的左右位置将完全互换。

  • 在涉及复合变换(如平移、旋转和镜像同时操作)的项目需求中,理清父级坐标系的层级关系就显得尤为重要。

    const tempScene = scene.children.find(t => t.name == 'Scene')
    const tempDoor = tempScene.children.find(t => t.name == '门卫');
    const tempDoorSouth = tempDoor.children.find(t => t.name == '门卫室南');  
    const newDoor= tempDoorSouth.clone() 
    newDoor.translateX(30);
    newDoor.translateZ(15); 
    const mirrorMatrix = new THREE.Matrix4().makeScale(-1, 1, 1); //x轴镜像
    newDoor.applyMatrix4(mirrorMatrix) 
    newDoor.rotateY(-Math.PI/2) //顺时针旋转90度 
    tempDoor.add(newDoor)
    
  • 在常规认知中,首先定位到门卫室南,沿X轴平移30米,沿Z轴平移15米,应用镜像变换,顺时针旋转90度。然而,实际执行结果与预期不符:
    请添加图片描述

  • ❓❓❓右侧箭头处是预期位置,红圈⭕为父级坐标系原点。实际X轴移动了-30米(与预期相反),旋转方向也变为逆时针90度(与预期顺时针相反)。

  • 下面比较烧脑,谨慎观看!
    请添加图片描述

  • 由于父级坐标系原点必须保持固定,因此我们首先在初始坐标系下执行镜像变换。
    请添加图片描述

  • 在镜像变换后的坐标系中,现实世界中的顺时针90度旋转,将对应表现为镜像中逆时针90度旋转
    请添加图片描述

  • 最终,将镜子旋转至X轴方向,得到红圈标记的坐标系。随后执行以下平移操作:Z轴平移30米,X轴平移-15米。
    根据上述分析,代码修正如下:

    const tempScene = scene.children.find(t => t.name == 'Scene')
    const tempDoor = tempScene.children.find(t => t.name == '门卫');
    const tempDoorSouth = tempDoor.children.find(t => t.name == '门卫室南');  
    const newDoor= tempDoorSouth.clone() 
    
    const mirrorMatrix = new THREE.Matrix4().makeScale(-1, 1, 1); //x轴镜像
    newDoor.applyMatrix4(mirrorMatrix) 
    newDoor.rotateY(Math.PI/2) //逆时针旋转90度 
    
    newDoor.translateZ(30);
    newDoor.translateX(-15); 
    tempDoor.add(newDoor)
    

    ✅执行结果: 请添加图片描述

  • 图中看到,X轴移动30米,Z轴移动15米,顺时针旋转90度,应用了X镜像,窗户朝东开,符合预期。

  • 点击【专栏目录】查看专栏其他内容。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

3D虚拟工厂

您的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值