线性代数:空间点与平面

转载自: https://blog.csdn.net/yinhun2012/article/category/7491185


这一篇作为线性代数栏目的扩展篇之一,是因为随着学习的深入,必须提前学习一些具有应用针对性的数学计算方法,这次我们就来观察立体几何空间中点和面的关系,主要还是为了CG中着色应用,比如真实反射和光追计算。

       好接下来进入正题,首先观察一下空间中一个质点和平面的关系,如下图:

       

       三维空间中顶点D(x0,y0,z0)在平面镜面P(Ax+By+Cz+D = 0)的倒影点D'(x',y',z'),这一篇的主要内容就是学习整个求法过程和程序验证了。

       首先来看一下三维空间中平面的方程表达式Ax+By+Cz+D = 0,为什么写成这样?前面虽然我们讲解过直线和平面,这里为了保证思维的step by step,我们继续学习一遍,如下图:

       

       上面咋一看就存在一个先有鸡还是先有蛋的问题。

       ①.比如我们是先存在平面G,然后在已存在的平面G上取一点A,再做出以A为起点的平面G的单位法向量AN,接着单位法向量AN与平面G内任意一点P构成垂直关系,所以AN与AP的点积就等于0。

       ②.再比如我们先假定三维空间内存在一点A,以A为起点做一条单位向量AN,再使用一个直角三角形的尺子(一条直角边重合于AN)做出AN的任意长度的垂直向量AP,动点P就构成了平面G。

       其实这两种都对,在计算机三维世界中,我们生成一个平面,如果以第一种情况来讲,首先我们肯定要随意选取三维空间内不重合不共线的三个坐标点X Y Z(这三个坐标点组成三角形就是一个平面G了),那么我们通过向量XY和XZ的叉积就能得到平面G的法向量N了,再使N单位化得到单位法向量n,随后我们通过假定平面任意点P(x,y,z),通过向量XP与单位法向量n的点积等于0就能得到平面G内任意点P的方程,也就是平面方程了(顺便再次强调,不了解点积和叉积的同学一定要回到前面几何向量进行详细理解),顺便绘制一个示意图,如下:

       

扫描二维码关注公众号,回复: 5068379 查看本文章

      第二种情况就稍微简单一点,先确定三维空间内一点A,然后做任意单位向量AN,随后假设一动点P(x,y,z),同时向量AP与单位向量AN的点积等于0,求P点的方程,也就是平面方程,示意图如下:

      

      上面就是对平面方程比较详细的理解了,主要还是点叉积的应用之一。

      那么接下来就开始求解平面一侧空间任意点P在平面中的倒影点(对称点)P'了,如下图:

      

      推导过程无非就是建立平面G和空间点P以及对称点P'和相交点P0,根据向量P0P为K倍的平面单位法向量n以及P0处于平面计算出P0点的坐标,然后通过向量P'P0等于向量P0P算出对称点P'的坐标。

      接下来我们就是程序模拟验证了,毕竟推导出公式得实际用得上才能说学以致用,如下:


  
  
  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. public class PlaneRefl : MonoBehaviour
  5. {
  6. public MeshFilter mMeshFilter;
  7. public Transform mPA;
  8. public Transform mPB;
  9. public Transform mPC;
  10. public Transform mObjP;
  11. public Transform mObjPRefl;
  12. private Vector3 mX;
  13. private Vector3 mY;
  14. private Vector3 mZ;
  15. private Vector3 mP;
  16. private Vector3 mPRefl;
  17. private Mesh mesh;
  18. void Start()
  19. {
  20. mesh = new Mesh();
  21. mMeshFilter.mesh = mesh;
  22. }
  23. void Update()
  24. {
  25. //根据pa pb pc三个顶点构建三角形平面
  26. Vector3[] vertices = new Vector3[]
  27. {
  28. mPA.position,
  29. mPB.position,
  30. mPC.position
  31. };
  32. int[] triangles = new int[]
  33. {
  34. 0, 1, 2
  35. };
  36. mesh.vertices = vertices;
  37. mesh.triangles = triangles;
  38. //构建平面三点和空间点坐标
  39. mP = mObjP.position;
  40. mX = mPA.position;
  41. mY = mPB.position;
  42. mZ = mPC.position;
  43. //首先把平面公式计算出来
  44. //优先根据叉积计算平面的单位法向量
  45. Vector3 XY = mY - mX;
  46. Vector3 XZ = mZ - mX;
  47. Vector3 n = Vector3.Normalize(Vector3.Cross(XZ, XY));
  48. //根据推导公式得到A*x + B*y +C*z +D = 0
  49. float A = n.x;
  50. float B = n.y;
  51. float C = n.z;
  52. float D = -n.x * mX.x - n.y * mX.y - n.z * mX.z;
  53. //继续根据推导出的公式算出对称点的坐标
  54. float X = mP.x;
  55. float Y = mP.y;
  56. float Z = mP.z;
  57. float K = (A * X + B * Y + C * Z + D) / (A * A + B * B + C * C);
  58. float xRefl = X - 2 * K * A;
  59. float yRefl = Y - 2 * K * B;
  60. float zRefl = Z - 2 * K * C;
  61. mPRefl = new Vector3(xRefl, yRefl, zRefl);
  62. mObjPRefl.position = mPRefl;
  63. }
  64. }

      上面注释也算是详细,先创建一个任意三角形平面G,计算ObjP相对于平面G的对称坐标,实时赋予ObjRefl,效果如下:

 

      讲到这里大致学习完空间中点与平面的一些关系了,后续我们就根据学习到的数学只是来一些着色效果。

      so,我们接下来继续。

这一篇作为线性代数栏目的扩展篇之一,是因为随着学习的深入,必须提前学习一些具有应用针对性的数学计算方法,这次我们就来观察立体几何空间中点和面的关系,主要还是为了CG中着色应用,比如真实反射和光追计算。

猜你喜欢

转载自blog.csdn.net/cui6864520fei000/article/details/86554931