直线的向量方程
三维欧几里得空间中,直线的关系为:相交、平行和异面直线三种情况。设点A、B决定了直线 ,点C、D决定了直线 。求直线 和 间的距离可以用以下方法实现。
令直线
的向量方程:
这里,
是直线
上的一点(向量),
是直线
的方向向量。
类似地,令直线
的向量方程:
同样,
是直线
上的一点(向量),
是直线
的方向向量。
令:
,则直线间距离:
注:如果
,则表示直线
和
平行。不能用此公式计算。这时候,只要任取直线
上一点,例如A点,那么点A到直线
的距离就是两平行线
和
间的距离。
程序说明
定义了一个类:点类。定义了向量的基本操作,如类初始化、参数参数的设置和读取、重载了“+”、“-”、“*”运算符实现向量的加、减、叉乘运算、定义了向量的点乘、模等运算。点到点、点到直线、直线到直线的距离在主程序中定义。
点类
定义了向量加(+)、减(-)、叉乘(*)、点乘、向量的模等。
头文件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
扫描二维码关注公众号,回复:
11147807 查看本文章