线性代数:空间点与平面

       这一篇作为线性代数栏目的扩展篇之一,是因为随着学习的深入,必须提前学习一些具有应用针对性的数学计算方法,这次我们就来观察立体几何空间中点和面的关系,主要还是为了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的方程,也就是平面方程了(顺便再次强调,不了解点积和叉积的同学一定要回到前面几何向量进行详细理解),顺便绘制一个示意图,如下:

       

      第二种情况就稍微简单一点,先确定三维空间内一点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'的坐标。

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

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PlaneRefl : MonoBehaviour
{
    public MeshFilter mMeshFilter;

    public Transform mPA;
    public Transform mPB;
    public Transform mPC;
    public Transform mObjP;
    public Transform mObjPRefl;

    private Vector3 mX;
    private Vector3 mY;
    private Vector3 mZ;

    private Vector3 mP;
    private Vector3 mPRefl;

    private Mesh mesh;

    void Start()
    {
        mesh = new Mesh();
        mMeshFilter.mesh = mesh;
    }

    void Update()
    {
        //根据pa pb pc三个顶点构建三角形平面
        Vector3[] vertices = new Vector3[]
        {
            mPA.position,
            mPB.position,
            mPC.position
        };
        int[] triangles = new int[]
        {
            0,1,2
        };
        mesh.vertices = vertices;
        mesh.triangles = triangles;
        //构建平面三点和空间点坐标
        mP = mObjP.position;
        mX = mPA.position;
        mY = mPB.position;
        mZ = mPC.position;
        //首先把平面公式计算出来
        //优先根据叉积计算平面的单位法向量
        Vector3 XY = mY - mX;
        Vector3 XZ = mZ - mX;
        Vector3 n = Vector3.Normalize(Vector3.Cross(XZ, XY));
        //根据推导公式得到A*x + B*y +C*z +D = 0
        float A = n.x;
        float B = n.y;
        float C = n.z;
        float D = -n.x * mX.x - n.y * mX.y - n.z * mX.z;
        //继续根据推导出的公式算出对称点的坐标
        float X = mP.x;
        float Y = mP.y;
        float Z = mP.z;

        float K = (A * X + B * Y + C * Z + D) / (A * A + B * B + C * C);
        float xRefl = X - 2 * K * A;
        float yRefl = Y - 2 * K * B;
        float zRefl = Z - 2 * K * C;

        mPRefl = new Vector3(xRefl, yRefl, zRefl);
        mObjPRefl.position = mPRefl;
    }
}

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

 

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

      so,我们接下来继续。

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值