« 伺机而动,设计模式之观察者(Observer)Shader快速复习:Per Pixel Lighting(逐像素光照) »

3D数学:求点到直线的投影

今天思考一个问题的时候,考虑到把空间中一个点投影到一个向量上,也就是project-point-to-vector,发现原来自己想不出来,惟有求助google,算法理解。——ZwqXin.com

本文来源于 ZwqXin (http://www.zwqxin.cn/), 转载请注明
      原文地址:http://www.zwqxin.cn/archives/arithmetic/project-point-to-line.html

事情是这样的,在OPENGL中,点的坐标定义于其模型坐标系XYZ,现在我经过某个转换生成了另一个3维坐标系X'Y'Z',反映于原坐标系,就是三个满足正交的方向向量,干脆叫做X'和Y'和Z'。现在我有一个定义于模型坐标系XYZ的点阵,我需要把这些点分别投影到X'和Y'和Z'上,求投影点坐标。

问题有点虚,所以考虑把这三个正交向量看作三条直线,问题就变成了:求点到直线的投影。考虑一个点和一条直线,描述这条直线需要两个点P1和P2 (顺带一提,P2 -P1就是相应的那向量),待投影的点叫P3。不妨设P3投影到该直线后所得的点是P3'注意P3'与P1、P2 共线,因此必然有一个比例因子t,令

t * (P- P1) =   P3' - P1

因此问题变为:已知P1、P2 、P3 , P1和P2 共线,求比例因子t 。令vec1 = P3 - P1  , vec2 = P- P1,显然dis = vec1 * vec2(点乘)就是vec1在vec2上的投影,既然vec1与vec2共享一个起点P1,那么dis就是P1到投影点P3'的距离了。于是

t = dis / length(P 1P2) = vec1 * vec2 / length(P 1P2)
                                                 = (P3 - P1) * (P- P1)  / abs (P- P1)
                                                          = (P3 - P1) * (P- P1)  / (P- P1) *(P- P1)

abs (P- P1)表示求模(也就是线段P 1P2的长度),abs (P- P1) = (P- P1) *(P- P1) 。由上两式子就能求出P3' 了。这么简单..........看来脑袋锈豆不浅。算法写进我的CVector3类里了。直线还原成向量的样子,相当于把直线用一个向量和一个参考点描述。

 
  1.  //点到矢量vec2的投影,ori_vec2表示vec2起点(投影参照点)
  2.   inline CVector3 Project2Vector(CVector3& vec2, CVector3 ori_vec2){
  3.       CVector3 dir = (*this) - ori_vec2;
  4.       double t = dir.DotProd(vec2) / vec2.DotProd(vec2);
  5.  
  6.       return ori_vec2 + vec2 * t;
  7.   };
  8.  
  9.  
  10. //例子
  11. {
  12. CVector3 pt = CVector3(.....);//待投影的点
  13. CVector3 ori_pt = CVector3(.....);//投影参考点,也就是上文的P1
  14. CVector3 vector = CVector3(.....);//待投影于其上的某向量
  15.  
  16. CVector3 point;
  17. point = pt .Project2Vector(vector, ori_pt );
  18. }

另:点到线段P 1P2的投影:

 
  1. CVector3 ClosestPointOnSegment(CVector3 p, CVector3 p1, CVector3 p2)
  2. {
  3.     CVector3 diff = p-p1;
  4.     CVector3 dir = p2-p1;
  5.     float dot1 = dot(diff,dir);
  6.     if (dot1 <= 0.0f) {
  7.         return p1;
  8.     }    
  9.     float dot2 = dot(dir,dir);
  10.     if (dot2 <= dot1) {
  11.         return p2;
  12.     }
  13.     float t=dot1/dot2;
  14.     return p1 + t * dir;
  15. }
本文来源于 ZwqXin (http://www.zwqxin.cn/), 转载请注明
      原文地址:http://www.zwqxin.cn/archives/arithmetic/project-point-to-line.html

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

IE下本页面显示有问题?

→点击地址栏右侧【兼容视图】←

日历

Search

网站分类

最新评论及回复

最近发表

Powered By Z-Blog 1.8 Walle Build 100427

Copyright 2008-2024 ZwqXin. All Rights Reserved. Theme edited from ipati.