“抛开常见的三维坐标系. ”
最近在整理代码,偶然看到以前用了普吕克坐标系来处理元素相交问题。回头看,已经全部看不懂了,所以打算写个博客来记录普吕克坐标系的用法。
普吕克坐标系是直线几何中的一种坐标系和普通我们用的三维笛卡尔坐标系不太相同,它是一个齐次坐标系,既然是齐次,我们就用用投影的思想来看待它。
首先来理解下点在齐次坐标系下的直观意义。将三维退化为二维更好理解。
如上图所示,图中的点是线和平面的交点,换种思想就是说线上的所有点沿着线的方向进行投影,得到的永远是图中所示的点,则这条线就是这个点的齐次方程,齐次的w是投影长度。
同样我们表示一个三维点在普吕克坐标系下为表示为
普吕克坐标系最常见的两个操作是 join 和 meet。join表示两个元素组成新的元素,meet表示两个元素相交出的元素。比如point join point 得到 line ,point join line 得到 plane ,line meet line 得到 point ,line meet plane 得到point。为了简单的工程应用,后续就围绕着这几个操作进行分析。推导的详细过程可以查看wiki的普吕克坐标系
point join point
我们定义线为:
p01,p02…之类的怎么来的呢?假设这条线段上面有两个点(x0:x1:x2:x3)和(y0:y1:y2:y3),我们将以下面的规则定义pij:
为什么只取这6个数呢?因为pii = 0 并且 pij = -pji,所以取6个数就能代表整个矩阵。
以两个点得出线的操作称为point join point。
—–这么理解是不是很复杂,那么我介绍一种简单的理解,上面的线的表达式可以退化为(d:m),假设直线上有两个点p1和p2则d = p2 - p1, m = p1 x p2。将 p1和p2 看作从(0,0,0)出发的两条线段。这样理解d可以筛选出系列的线段,可以看作绕着原点,方向为朝向屏幕的直线集合,如下图所示。m的作用就是唯一能确定一条线段垂线方向与其相同,且离原点距离为|m|。这样空间中的直线就能被唯一确定下来。
point join line
在空间中的一个点和一条线我们可以唯一确定一个平面。point join line就是用来确定空间中一个平面的操作。
我们定义平面为:
假设空间中的点坐标为(x0:x1:x2:x3),空间中的线段的定义为如point join point中pij中的定义。
这里为了简便直接给出ai的定义:
其实有平面方程的就很好理解,平面方程的系数就是上述的a。
line meet line
有了上面的点、线、面的定义以后我们可以通过利用普吕克坐标系进行相应的相交操作。我们首先来讲线线相交。
在普吕克坐标系中如果两条直线有相交,则其交点为(d · m’ : m x m’ ),通过齐次位是否为0可以判断两条线段是否相交,这个很好理解d’ 和m’是正交的,如果d · m’ 为0,表示d 和m’也是是正交,则 d 和d’是平行的所以没有交点。
m x m’ 也很好理解,两条直线的交点实则是求一个从原点出发的向量,m x m’ 表示这个向量的方向,如下图中0和C组成的向量方向。
line meet plane
在普吕克坐标系下,直线(d : m)和平面(a0 : a)如果有相交则,其交点为(a · d : a x m - a0d),很好理解是否相交的条件a · d 是否等于0。 d是直线的方向,a是平面的法向,如果它们的点乘等于0表示这两个向量正交,所以一定没有交点。
上述是我列举的几个在工作中常用的例子,其余用法可在维基百科中查询。
用普吕克坐标系的优势在于可以用简单的几个运算就能处理常见的相交问题,特别在判断相交的问题上。在实际编程中去除了除法运算,所以效率有很大的提升。