1. 什么是镜像变换

直接看下面这张图:

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

2d下的镜像矩阵变化

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

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

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

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点关于平面的镜像矩阵如图:

简单解释一下图中内容:

设点P(x, y, z)为平面正方向上的一点,点O是P(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  、 互换位置。不清楚的同学百度搜索向量和矩阵相乘。

Three.js-任意平面的镜像矩阵的更多相关文章

  1. 2D平面中关于矩阵(Matrix)跟图形变换的讲解

    在二维平面上,常用的有以下三种基本的图形变化: 1)Translation 2)Scale 3)Rotation 在canvas的开发中,我们也经常会用到这样的一些图形变换,尤其是我们在写自定义Vie ...

  2. js任意位数求和

    <script> //任意位数求和 function sum(){ if(arguments.length==1) { console.log(arguments[0]) return; ...

  3. JS任意文件转base64

    <!doctype html><html><head><meta charset="utf-8"><meta name=&qu ...

  4. js任意数组按下标相加

    let a=[1,2,3], b=[4,5,6]; let s = a.map(function(v, i) { return v + b[i]; }); console.log(s);

  5. node.js 设置 淘宝 镜像

    npm config set registry "https://registry.npm.taobao.org" npm info underscore (如果上面配置正确这个命 ...

  6. DirectX 总结和DirectX 9.0 学习笔记

    转自:http://www.cnblogs.com/graphics/archive/2009/11/25/1583682.html DirectX 总结 DDS DirectXDraw Surfac ...

  7. 3D数学基础 KeyNote 1

    [计算几何复习要点] 1.向量加法的几何含意: a+b的释意为:a的尾连上b的头,新建一条从a的尾指向b的头的向量. 2.向量减法的几何含意: a-b的释意为:尾部相连,新建一个从b的头指向a的头的向 ...

  8. 《逐梦旅程 WINDOWS游戏编程之从零开始》笔记8——载入三维模型&Alpha混合技术&深度测试与Z缓存

    第17章 三维游戏模型的载入 主要是如何从3ds max中导出.X文件,以及如何从X文件加载三维模型到DirextX游戏程序里.因为复杂的3D物体,要用代码去实现,那太反人类了,所以我们需要一些建模软 ...

  9. 3D数学 ---- 矩阵和线性变换[转载]

    http://blog.sina.com.cn/s/blog_536e0eaa0100jn7c.html 一般来说,方阵能描述任意线性变换.线性变换保留了直线和平行线,但原点没有移动.线性变换保留直线 ...

随机推荐

  1. cuGraph-GPU图形分析

    cuGraph-GPU图形分析 所述RAPIDS cuGraph库是GPU的集合加速图形算法,在GPU DataFrames中发现过程数据.cuGraph的愿景是使图分析无处不在,以至于用户只是根据分 ...

  2. NSight Compute 用户手册(下)

    主菜单 文件 新建项目使用"新建项目"对话框创建新的分析项目 4. Main Menu and Toolbar Information on the main menu and t ...

  3. 《python网络数据采集》笔记1

    第一部分-创建爬虫 1.urllib 1)urllib.request request.urlopen(url) request.urlretrieve 可以根据文件的 URL 下载文件 2)urll ...

  4. P4779 【模板】单源最短路径(标准版)单源最短路Dijkstra

    题目描述 给定一个$n$个点,$m$条有向边的带非负权图,请你计算从$s$出发,到每个点的距离. 数据保证你能从$s$出发到任意点. 输入格式 第一行为三个正整数$n,m,s$. 第二行起$m$行,每 ...

  5. 这 7 个 Linux 命令,你是怎么来使用的?

    使用 Linux 系统的开发者,很多人都有自己喜欢的系统命令,下面这个几个命令令是我平常用的比较多的,分享一下. 我不会教科书般的罗列每个指令的详细用法,只是把日常开发过程中的一些场景下,经常使用的命 ...

  6. 从一条sql报错解决过程学习程序员查bug的思路

    从oracle迁移数据到达梦后,发现数据库默认值都丢失了.于是我想从oracle数据库将默认值查出来,在达梦数据库加回去. 于是上网查了一下,看怎么获取oracle数据库字段默认值信息,找到了这个sq ...

  7. NetCore Dapper封装

    一.前期环境准备 1.创建一个core webapi的项目,基于core3.1版本创建一个项目. 2.Dapper安装,使用NuGet来安装Dapper程序包 Install-Package Dapp ...

  8. 【模拟8.10】Weed(线段树)

    考试只好随便骗骗分过去啦啦啦..... 正解是玄学线段树: 以每个操作为叶子节点,我们定义几个变量ce表示层数,h表示高度,add表示所减的层数 那么问题转化为单点修改的问题输出直接是根节点答案 但是 ...

  9. 数据泵导出报错ORA-31693 ORA-02354 ORA-01466

    1.Oracle数据泵导出schema时有报错: Connected to: Oracle Database 11g Enterprise Edition Release 11.2.0.3.0 - P ...

  10. 透彻理解液晶显示模组LCD1602指令集与驱动编程(1)

    LCD1602可以说是大多数单片机工程师了解液晶显示的入门级模组,其显示原理与其它很多显示模组也是相似的,今天我们就来详细讨论一下它的指令集.所谓模组的指令集,本质上是该模组使用的控制芯片的指令集,本 ...