空间点到直线垂足坐标的解算方法

假设空间某点O的坐标为(Xo,Yo,Zo),空间某条直线上两点A和B的坐标为:(X1,Y1,Z1),(X2,Y2,Z2),设点O在直线AB上的垂足为点N,坐标为(Xn,Yn,Zn)。点N坐标解算过程如下:

首先求出下列向量:

   

由向量垂直关系:

       

上式记为(1)式。

   点N在直线AB上,根据向量共线:

      (2)

  由(2)得:

    (3)

   把(3)式代入(1)式,式中只有一个未知数k,整理化简解出k:

     (4)
   把(4)式代入(3)式即得到垂足N的坐标。

 

// 二维空间点到直线的垂足
struct Point
{
  double x,y;
}
Point GetFootOfPerpendicular(
    const Point &pt,     // 直线外一点
    const Point &begin,  // 直线开始点
    const Point &end)   // 直线结束点
{
    Point retVal;
 
    double dx = begin.x - end.x;
    double dy = begin.y - end.y;
    if(abs(dx) < 0.00000001 && abs(dy) < 0.00000001 )
    {
        retVal = begin;
        return retVal;
    }
 
    double u = (pt.x - begin.x)*(begin.x - end.x) +
        (pt.y - begin.y)*(begin.y - end.y);
    u = u/((dx*dx)+(dy*dy));
 
    retVal.x = begin.x + u*dx;
    retVal.y = begin.y + u*dy;
 
    return retVal;
}

 

// 三维空间点到直线的垂足
struct Point
{
  double x,y,z;
}
Point GetFootOfPerpendicular(
    const Point &pt,     // 直线外一点
    const Point &begin,  // 直线开始点
    const Point &end)   // 直线结束点
{
    Point retVal;
 
    double dx = begin.x - end.x;
    double dy = begin.y - end.y;
  double dz = begin.z - end.z;
    if(abs(dx) < 0.00000001 && abs(dy) < 0.00000001 && abs(dz) < 0.00000001 )
    {
        retVal = begin;
        return retVal;
    }
 
    double u = (pt.x - begin.x)*(begin.x - end.x) +
        (pt.y - begin.y)*(begin.y - end.y) + (pt.z - begin.z)*(begin.z - end.z);
    u = u/((dx*dx)+(dy*dy)+(dz*dz));
 
    retVal.x = begin.x + u*dx;
    retVal.y = begin.y + u*dy;
  retVal.y = begin.z + u*dz;
  
    return retVal;
}

————————————————
版权声明:本文为CSDN博主「zhouschina」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/zhouschina/article/details/14647587

空间中点 $P(x_0, y_0, z_0)$ 到直线 $l$ 的垂足 $H$ 坐标的计算方法如下: 1. 直线 $l$ 的方向向量 $\vec{d}$。 2. 出点 $P$ 到直线 $l$ 的距离 $d$。 3. 设直线上任意一点为 $Q$,则 $\vec{PQ}$ 与 $\vec{d}$ 垂直,即 $\vec{PQ} \cdot \vec{d} = 0$。由此可以出 $Q$ 的坐标。 4. 点 $H$ 为点 $Q$ 在直线 $l$ 上的投影点,可用向量表示为 $\vec{OH} = \vec{OQ} - \frac{\vec{OQ} \cdot \vec{d}}{\vec{d} \cdot \vec{d}}\vec{d}$,其中 $\vec{O}$ 为直线上的任意一点。 下是实现代码: ```c++ #include <iostream> #include <cmath> using namespace std; struct Point { double x, y, z; }; struct Line { Point p; // 直线上一点 Point v; // 方向向量 }; double dist(Point p, Line l) { Point q; double t = ((p.x-l.p.x)*l.v.x + (p.y-l.p.y)*l.v.y + (p.z-l.p.z)*l.v.z) / (l.v.x*l.v.x + l.v.y*l.v.y + l.v.z*l.v.z); q.x = l.p.x + t * l.v.x; q.y = l.p.y + t * l.v.y; q.z = l.p.z + t * l.v.z; return sqrt((p.x-q.x)*(p.x-q.x) + (p.y-q.y)*(p.y-q.y) + (p.z-q.z)*(p.z-q.z)); } Point projection(Point p, Line l) { Point q, h; double t = ((p.x-l.p.x)*l.v.x + (p.y-l.p.y)*l.v.y + (p.z-l.p.z)*l.v.z) / (l.v.x*l.v.x + l.v.y*l.v.y + l.v.z*l.v.z); q.x = l.p.x + t * l.v.x; q.y = l.p.y + t * l.v.y; q.z = l.p.z + t * l.v.z; h.x = q.x - (q.x-l.p.x)*l.v.x/(l.v.x*l.v.x+l.v.y*l.v.y+l.v.z*l.v.z); h.y = q.y - (q.y-l.p.y)*l.v.y/(l.v.x*l.v.x+l.v.y*l.v.y+l.v.z*l.v.z); h.z = q.z - (q.z-l.p.z)*l.v.z/(l.v.x*l.v.x+l.v.y*l.v.y+l.v.z*l.v.z); return h; } int main() { Point p = {1, 2, 3}; Line l = {{0, 0, 0}, {1, 1, 1}}; Point h = projection(p, l); cout << "垂足坐标:" << h.x << " " << h.y << " " << h.z << endl; cout << "距离:" << dist(p, l) << endl; return 0; } ``` 其中 `Point` 结构体表示点的坐标,`Line` 结构体表示直线上一点和方向向量。`dist` 函数计算点到直线的距离,`projection` 函数计算点到直线垂足坐标
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值