-
- //点到矢量vec2的投影,ori_vec2表示vec2起点(投影参照点)
- inline CVector3 Project2Vector(CVector3& vec2, CVector3 ori_vec2){
- CVector3 dir = (*this) - ori_vec2;
- double t = dir.DotProd(vec2) / vec2.DotProd(vec2);
- return ori_vec2 vec2 * t;
- };
- //例子
- {
- CVector3 pt = CVector3(.....);//待投影的点
- CVector3 ori_pt = CVector3(.....);//投影参考点,也就是上文的P1
- CVector3 vector = CVector3(.....);//待投影于其上的某向量
- CVector3 point;
- point = pt .Project2Vector(vector, ori_pt );
- }
- CVector3 ClosestPointOnSegment(CVector3 p, CVector3 p1, CVector3 p2)
- {
- CVector3 diff = p-p1;
- CVector3 dir = p2-p1;
- float dot1 = dot(diff,dir);
- if (dot1 <= 0.0f) {
- return p1;
- }
- float dot2 = dot(dir,dir);
- if (dot2 <= dot1) {
- return p2;
- }
- float t=dot1/dot2;
- return p1 t * dir;
- }
今天思考一个问题的时候,考虑到把空间中一个点投影到一个向量上,也就是project-point-to-vector,发现原来自己想不出来,惟有求助google,算法理解。
事情是这样的,在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 * (P2 - P1) = P3' - P1
因此问题变为:已知P1、P2 、P3 , P1和P2 共线,求比例因子t 。令vec1 = P3 - P1 , vec2 = P2 - P1,显然dis = vec1 * vec2(点乘)就是vec1在vec2上的投影,既然vec1与vec2共享一个起点P1,那么dis就是P1到投影点P3'的距离了。于是
t = dis / length(P 1P2) = vec1 * vec2 / length(P 1P2)
= (P3 - P1) * (P2 - P1) / abs (P2 - P1)
= (P3 - P1) * (P2 - P1) / (P2 - P1) *(P2 - P1)
abs (P2 - P1)表示求模(也就是线段P 1P2的长度),abs (P2 - P1) = (P2 - P1) *(P2 - P1) 。由上两式子就能求出P3' 了。这么简单..........看来脑袋锈豆不浅。算法写进我的CVector3类里了。直线还原成向量的样子,相当于把直线用一个向量和一个参考点描述。
另:点到线段P 1P2的投影: