在三维图形问题中,点和直线计算是很常见的,比如,已知三维空间中一条直线和任意非直线上的点,求点到直线的垂线(或垂点),这个问题比较典型,基本上就属于一系列三维空间点与直线关系的代表。
首先如下图:
学到现在的几何向量,一眼就看得出来,只需要根据向量PC1与向量PV的点积等于0,得到方程组就可以最终计算出P点坐标了。首先我们确定三维空间中P点表示法,使用C1 + n*dir的形式,其中C1为起始点,dir为单位朝向向量,n为模长。那么计算如下:
推算出来计算公式,那么程序中验证一下就好了,代码如下:
using System.Collections; using System.Collections.Generic; using UnityEngine; public class VerticalVertex : MonoBehaviour { public Transform C1; public Transform C2; public Transform Vertex; private Vector3 c2; void Start() { c2 = C2.position; } void Update() { C2.position = c2 + new Vector3(0, 0, Mathf.Sin(Time.time)); Vector3 c = C1.position; Vector3 dir = (C2.position - C1.position).normalized; Vector3 v = Vertex.position; Vector3 vv = getVerticalVertex(c, dir, v); #if UNITY_EDITOR Debug.DrawLine(c, C2.position, Color.black); Debug.DrawLine(v, vv, Color.red); #endif } private Vector3 getVerticalVertex(Vector3 c, Vector3 dir, Vector3 v) { //首先写出推导过程(不参与计算) float n = 0; Vector3 p = c + n * dir; Vector3 pc = n * dir; Vector3 pv = v - p; pv = v - c - n * dir; //接着根据公式计算一元二次方程的根 //pc.x * pv.x + pc.y * pv.y + pc.z * pv.z = 0; //n^2*(dir.x^2+dir.y^2+dir.z^2)+n*(dir.x*c.x-dir.x*v.x+dir.y*c.y-dir.y*v.y+dir.z*c.z-dir.z*v.z)=0 //构建一元二次方程组参数 float A = dir.x * dir.x + dir.y * dir.y + dir.z * dir.z; float B = dir.x * c.x - dir.x * v.x + dir.y * c.y - dir.y * v.y + dir.z * c.z - dir.z * v.z; float C = 0; //去掉n为0的根 float n1 = (-B + Mathf.Sqrt(B * B - 4 * A * C)) / (2 * A); if (n1 != 0) { return c + n1 * dir; } float n2 = (-B - Mathf.Sqrt(B * B - 4 * A * C)) / (2 * A); if (n2 != 0) { return c + n2 * dir; } return c; } }
这里我们将n=0的情况的方程根去掉,因为n=0的情况下,C1和P重合,就失去了计算点积和垂直的意义。最后效果图如下:
看得出来,计算的垂点正确。
————————————————
版权声明:本文为CSDN博主「羊羊2035」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/yinhun2012/article/details/97797410

