Three.js-任意平面的镜像矩阵

简介: 1. 什么是镜像变换直接看下面这张图:这张图很好的诠释了镜像变化,关于y轴的变化,关于x轴的变化。这种关于任意轴的变化,就是镜像了。2d下的镜像矩阵变化我们以图像关于Y轴镜像为例子:原图形和结果图形上所有点的都存在的关系就应该是  x = -x, 也就是都只有x发生变化。这种通用的变化其实可以用矩阵表示,2D空间中的点其实可以用[x,y ] 表示。对角线的两个1就是关于那个轴对称:这些都是关于x轴、 y轴的对称, 如果说关于2d平面的任意一条直线呢,当然有人已经帮我们推导出来了如下图:(数学证明我就不给出了,有兴趣的可以自行百度,本篇文章注重3d镜像矩证的推导)3d 图形下关

1. 什么是镜像变换



直接看下面这张图:


image.png


这张图很好的诠释了镜像变化,关于y轴的变化,关于x轴的变化。这种关于任意轴的变化,就是镜像了。


2d下的镜像矩阵变化


我们以图像关于Y轴镜像为例子:原图形和结果图形上所有点的都存在的关系就应该是  x = -x,


也就是都只有x发生变化。这种通用的变化其实可以用矩阵表示,2D空间中的点其实可以用[x,y ] 表示。对角线的两个1就是关于那个轴对称:


image.png


这些都是关于x轴、 y轴的对称, 如果说关于2d平面的任意一条直线呢,当然有人已经帮我们推导出来了如下图:(数学证明我就不给出了,有兴趣的可以自行百度,本篇文章注重3d镜像矩证的推导)


image.png


3d 图形下关于任意平面的镜像矩阵推导:


首先给大家介绍下three.js 中的Plane  有两部分构成一个是平面的法向量(normal - 单位向量)和原点到平面的距离(constant); 平面上的点都满足 Ax + By + Cz + D = 0;  这个平面推导过程不清楚的同学可以看下这里:点击这里


  • A, B ,C 这3个参数代表的是平面法向量的(x,y,z)

 

  • D  就是上文的constant这个参数


问题很简单假设空间中存在点P 和(x,y,z) 以及平面(n,D) 求P点关于平面的镜像矩阵如图:


image.png


 简单解释一下图中内容:


设点P(x, y, z)为平面正方向上的一点,点OP(x, y, z)在平面上的投影,点A(xa, ya, za)是平面上任取的一点,而P’(x’, y’, z’)则是点P(x, y, z)相对与平面的镜像点,另外的,我们还假设由点A到点P的向量为a(x - xa, y - ya, z - za),由点O到点P的向量为b,平面法向量为n(xn, yn, zn),平面到原点的带符号距离为D.


其实说白了我就是推导P’ = mirrorMatrix * P 。


从图片中可以的出  P’P = 2 b   所以可以得出P’ = P  - 2b


所以我们现在的问题是如何求解b向量 ?  其实只要求解 a 向量在法向量上的投影就好了

所以就能够得到 b =  a * n * n


ok 由于 a* n 是一个标量所以在这里我们先求解一下


a * n = (x - xa,  y - ya,  z - za ) * (xn,  yn,  zn) = (x - xa) * xn + (y - ya) * yn + (z - za) * zn = x * xn + y * yn + z * zn - xa * xn - ya * yn - za * zn

又因为点A是平面上的点,所以自然满足平面方程 (不清楚的同学点击这里:点击

xa *  xn + ya * yn + za * zn + D =  0

D = - (xa * xn + ya * yn + za * zn****)


带入到上面 a * n 的方程 :


a*n =  x * xn + y*yn + z *zn + D

所以这时候b向量就可以很好的表示了

b =  ( x * xn + y*yn + z*zn + D ) * n

截止到这里我们已经成功的消元了, 因为A 点是空间中任意一点嘛。


P’ =  P - 2b =  P - 2 *( x * xn + y*yn + z*zn + D ) * n

到这里我们已经成功求出 P 和 P’ 的关系

接下来就是求出 在 x ,y ,z 上的分量。


首先尝试计算点P’的x分量,我们有:

P’x = x - 2 * (x * xn + y * yn + z * zn + D) * xn

= (1 - 2 * xn * xn) * x - 2 * xn * yn * y - 2 * xn * zn * z - 2 * xn * D


根据这个表达式,并根据矩阵乘法规则,我们便可以得到变换矩阵的第一行元素:


m11 = 1 - 2 * xn * xn


m12 = -2 * xn * yn


m13 = -2 * xn * zn


m14 = -2 * xn * D


同样的方法,点P’的y,z分量分别为:


P’y  =  y - 2 * (x * xn + y * yn + z * zn + D) * yn


= - 2 * xn * yn * x + (1 - 2 * yn * yn) * y - 2 * yn * zn * z - 2 * yn * D


P’z = z - 2 * (x * xn + y * yn + z * zn + D) * zn


= - 2 * xn * zn * x - 2 * yn * zn * y + (1 - 2 * zn * zn) * z - 2 * zn * D


对应的,矩阵的第二行元素和第三行元素分别为:


m21 = -2 * xn * yn


m22 = 1 - 2 * yn * yn


m23 = -2 * yn * zn


m24 = -2 * yn * D


m31 = -2 * xn * zn


m32 = -2 * yn * zn


m33 = 1 - 2 * zn * zn


m34 = -2 * zn * D


矩阵的最后一行 我们暂时不关心设置为默认:


m41 = 0


m42 = 0


m43 = 0


m44 = 1


最后的提醒:


  • 空间中如果是圆者是弧这种图像 关于任意平面对称, 这时候的图像的nomal 应该是 Matrix3 不带位移的。 也就是将文中的Matrix4 转为Matrix3


  • 本文是矩阵乘以向量所以是矩阵在前,如果在实际运用中你是后乘,也就是矩阵在后面 需要将m14 和  m41 、 m24 和 m42  、 m34 和 m43  、 互换位置。不清楚的同学百度搜索向量和矩阵相乘。



相关文章
|
JavaScript
Node.js npm设置淘宝npm镜像
Node.js npm设置淘宝npm镜像
1554 0
|
JSON JavaScript 定位技术
echarts:从github及其镜像下载china.js和china.json
echarts:从github及其镜像下载china.js和china.json
2908 0
|
2月前
关于three.js中的矩阵更新
关于three.js中的矩阵更新
42 1
|
2月前
|
存储 JavaScript vr&ar
three.js中的矩阵变换(模型视图投影变换)
three.js中的矩阵变换(模型视图投影变换)
62 1
|
5月前
|
机器学习/深度学习 JavaScript Python
GEE机器学习——混淆矩阵Classifier.confusionMatrix()和errorMatrix()和exlain()的用法(js和python代码)
GEE机器学习——混淆矩阵Classifier.confusionMatrix()和errorMatrix()和exlain()的用法(js和python代码)
165 0
|
JavaScript Linux C++
Docker构建Node.js应用镜像
Docker构建Node.js应用镜像
522 0
|
JavaScript Docker Windows
Windows下构建Node.js的Docker Nano Server基础镜像
本文讲的是Windows下构建Node.js的Docker Nano Server基础镜像【编者的话】本文介绍了如何在Windows下制作Nano Server的Docker镜像,并用镜像来部署Node.js应用。
2580 0
|
算法 JavaScript
JS算法练习—二叉树的镜像和对称的二叉树
JS算法练习—二叉树的镜像和对称的二叉树
|
JavaScript
剑指Offer——顺时针打印矩阵(JS实现)
剑指Offer——顺时针打印矩阵(JS实现)
302 0
剑指Offer——顺时针打印矩阵(JS实现)
|
JavaScript
剑指Offer——矩阵中的路径(JS实现)
剑指Offer——矩阵中的路径(JS实现)
268 0
剑指Offer——矩阵中的路径(JS实现)