三维空间中直线间距离的计算

目录

直线的向量方程

三维欧几里得空间中,直线的关系为:相交、平行和异面直线三种情况。设点A、B决定了直线 L 1 L_1 L1,点C、D决定了直线 L 2 L_2 L2。求直线 L 1 L_1 L1 L 2 L_2 L2间的距离可以用以下方法实现。

令直线 L 1 L_1 L1的向量方程: x = a + λ b , ( a 、 b 、 x ∈ R 3 , λ ∈ R , a = O A ‾ , b = A B ‾ = O B ‾ − O A ‾ ) x=a+\lambda{b}, ({a、b、x}\in{R^3}, \lambda\in{R}, a=\overline{OA}, b=\overline{AB}=\overline{OB}-\overline{OA}) x=a+λb,(abxR3,λR,a=OA,b=AB=OBOA)
这里, a a a是直线 L 1 L_1 L1上的一点(向量), b b b是直线 L 1 L_1 L1的方向向量。

类似地,令直线 L 2 L_2 L2的向量方程: y = c + μ d , ( c 、 d 、 y ∈ R 3 , μ ∈ R , c = O C ‾ , d = C D ‾ = O D ‾ − O C ‾ ) y=c+\mu{d},({c、d、y}\in{R^3}, \mu\in{R}, c=\overline{OC}, d=\overline{CD}=\overline{OD}-\overline{OC}) y=c+μd,(cdyR3,μR,c=OC,d=CD=ODOC)
同样, c c c是直线 L 2 L_2 L2上的一点(向量), d d d是直线 L 2 L_2 L2的方向向量。

令: n = b × d ∣ ∣ b × d ∣ ∣ n=\dfrac{ {b}\times{d}}{||{b}\times{d}||} n=b×db×d,则直线间距离: l = ∣ n ⋅ ( c − a ) ∣ l=|{n}\cdot{(c-a)}| l=n(ca)
注:如果 ∣ ∣ b × d ∣ ∣ = 0 ||{b}\times{d}||=0 b×d=0,则表示直线 L 1 L_1 L1 L 2 L_2 L2平行。不能用此公式计算。这时候,只要任取直线 L 1 L_1 L1上一点,例如A点,那么点A到直线 L 2 L_2 L2的距离就是两平行线 L 1 L_1 L1 L 2 L_2 L2间的距离。

程序说明

定义了一个类:点类。定义了向量的基本操作,如类初始化、参数参数的设置和读取、重载了“+”、“-”、“*”运算符实现向量的加、减、叉乘运算、定义了向量的点乘、模等运算。点到点、点到直线、直线到直线的距离在主程序中定义。

点类

定义了向量加(+)、减(-)、叉乘(*)、点乘、向量的模等。
头文件Point.h

#ifndef POINT_H
#define POINT_H

#include<iostream>
#include<cmath>

class Point
{ 
    public:
        Point(double _x=0.0, double _y=0.0, double _z=0.0):X(_x), Y(_y), Z(_z) { };
        virtual ~Point() { };
        Point(const Point &other) {  X=other.X; Y=other.Y; Z=other.Z; };
        Point &operator=(const Point&);
        Point operator+(const Point&);
        Point operator+=(const Point&);
        Point operator-(const Point&);
        Point operator-();  // opposite number
        Point operator-=(const Point&);
        Point operator*(const Point&); // cross product
        friend std::ostream &operator<<(std::ostream &output, const Point &rhs);

        double GetX() {  return X; }
        void SetX(double val) {  X = val; }
        double GetY() {  return Y; }
        void SetY(double val) {  Y = val; }
        double GetZ() {  return Z; }
        void SetZ(double val) {  Z = val; }
        double dotX(const Point &pt) {  return (pt.X*X+pt.Y*Y+pt.Z*Z); }
        double mod() {  return sqrt(dotX(*this)); }

    protected:

    private:
        double X;
        double Y;
        double Z;
};

#endif // POINT_H

类的实现:Point.cpp

#include "Point.h"

Point &Point::operator=(const Point &rhs)
{ 
    if (this == &rhs) return *this; // self assignment
    X=rhs.X;
    Y=rhs.Y;
    Z=rhs.Z;
    return *this;
}

Point Point::operator+(const Point &rhs)
{ 
    return Point(X+rhs.X,Y+rhs.Y,Z+rhs.Z);
}

Point Point::operator+=(const Point &rhs)
{ 
    X+=rhs.X;
    Y+=rhs.Y;
    Z+=rhs.Z;
    return (*this);
}

Point Point::operator-(const Point &rhs)
{ 
    return Point(X-rhs.X, Y-rhs.Y, Z-rhs.Z);
}

Point Point::operator-() // opposite number
{ 
    return Point(-X, -Y, -Z);
}

Point Point::operator-=(const Point &rhs)
{ 
    X-=rhs.X;
    Y-=rhs.Y;
    Z-=rhs.Z;

    return (*this);
}

std::ostream &operator<<(std::ostream &output, const Point &rhs)
{ 
    output<<"("<<rhs.X<<","<<rhs.Y<<","<<rhs.Z<<")";
    return output;
}

Point Point::operator*(const Point &pt) // cross product
{ 
    double x1,x2,y1,y2,z1,z2,vx,vy,vz;

    x1=X;
    x2=pt.X;
    y1=Y;
    y2=pt.Y;
    z1=Z;
    z2=pt.Z;

    vx=y1*z2-y2*z1;
    vy=-x1*z2+x2*z1;
    vz=x1*y2-x2*y1;

    return Point(vx,vy,vz);
}

主程序:main.cpp

#include <iostream>
#include <cmath>
#include <fstream>
#include "Point.h"

using namespace std;

const double EPS=1e-10; // zero

double dist(Point &pt1, Point &pt2)  //Distance between two points
{ 
    return (pt2-pt1).mod();
}

double dist(Point &ptC, Point &ptA, Point &ptB)  //Distance between point C to line AB.
{ 
    double d=0.0;
    Point ac,ab;
    ac=ptC-ptA;
    ab=ptB-ptA;
    if (ab.mod() >= EPS) {  d=(ac*ab).mod()/ab.mod(); }
    else {  d=dist(ptC,ptA); } //The line is reduced to a point. point(ptC) to point(ptA) distance.

    return d;
}

double dist(Point &ptA, Point &ptB, Point &ptC, Point &ptD)  //Distance between line AB to line CD.
{ 
    double d=0.0;
    Point ab, cd, ad, axd;

    ab=ptB-ptA;
    cd=ptD-ptC;
    ad=ptD-ptA;
    axd=ab * cd;

    if ((axd.mod()) >= EPS) {  d = abs((axd.dotX(ad)))/axd.mod(); } //skew lines
    else {  d=dist(ptA, ptC, ptD); } //parallel lines
    return d;
}


int main()
{ 
    Point p0,p1(1.0, 0.0, 0.0), p2(0.0, 1.0, 0.0), p3(0.0, 0.0, 1.0), p4(1.0, 1.0, 1.0);
    Point p5(1.0, 1.0, 0.0), p6(0.0, 1.0, 1.0), p7(1.0, 0.0, 1.0);

    cout<<"\n---------------- Line to line --------------------"<<endl;
    cout<<"\nThe distance between the line p1p2 and the line p3p4 is : "<<dist(p1,p2,p3,p4)<<endl;
    cout<<"\nThe distance between the line p1p3 and the line p4p7 is : "<<dist(p1,p3,p4,p7)<<endl;
    cout<<"\nThe distance between the line p1p3 and the line p5p6 is : "<<dist(p1,p3,p5,p6)<<endl;
    cout<<"\nThe distance between the line p2p3 and the line p5p6 is : "<<dist(p2,p3,p5,p6)<<endl;
    cout<<"\nThe distance between the line p1p3 and the line p1p7 is : "<<dist(p1,p3,p1,p7)<<endl;

    return 0;
}

计算公式参考:https://en.wikipedia.org/wiki/Skew_lines

    原文作者:yang_deyuan
    原文地址: https://blog.csdn.net/yang_deyuan/article/details/79152647
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞