Vec3.h
#pragma once
#include <iostream>
#include <cmath>
#include <cassert>
using namespace std;
class Vec3 {
double x, y, z;
public:
Vec3(double x, double y, double z) :x(x), y(y), z(z) {}
Vec3(){}
~Vec3(){}
Vec3 (const Vec3& v) {
x = v.x;
y = v.y;
z = v.z;
}
void change(double tox, double toy, double toz) {
x = tox;
y = toy;
z = toz;
}
Vec3 operator +(const Vec3& v) const {
return Vec3(x + v.x, y + v.y, z + v.z);
}
Vec3 operator - (const Vec3& v) const {
return Vec3(x - v.x, y - v.y, z - v.z);
}
Vec3 operator * (const Vec3& v) const {
return Vec3(x * v.x, y * v.y, z * v.z);
}
void operator = (const Vec3& v) {
x = v.x;
y = v.y;
z = v.z;
}
Vec3 operator+=(const Vec3& v)const {
return Vec3(x + v.x, y + v.y, z + v.z);
}
void get_change(double tox, double toy, double toz) {
x = tox;
y = toy;
z = toz;
}
bool vertical(const Vec3& v) const{
//cos
if (fabs(v.x * x + v.y * y + v.z * z) <1e-10) {
return true;
}
return false;
}
void multi_cross(const Vec3& v,double &xcoe,double &ycoe,double &zcoe) const{
//向量叉乘
xcoe = y * v.z-z * v.y;
ycoe = z * v.x - x * v.z;
zcoe = x * v.y - y * v.x;
}
bool parallel(const Vec3& v) const{
//用cos计算
if (fabs(1 - fabs((x * v.x + y * v.y + z * v.z)\
/ (sqrt(x * x + y * y + z * z) * sqrt(v.x * v.x + v.y * v.y + v.z * v.z)))) < 1e-10) {
return true;
}
return false;
}
double length() {
return sqrt(x * x + y * y + z * z);
}
void operator /(double n) {
assert(fabs(n) > 1e-10);//除数不可以为0
x /= n;
y /= n;
z /= n;
}
bool operator == (const Vec3& v) const {
return x == v.x && y == v.y && z == v.z;
}
friend istream& operator>>(istream& is, Vec3& v) {
return is >> v.x >> v.y >> v.z;
}
friend ostream& operator<<(ostream& os, const Vec3& v) {
cout << "x==";
os << v.x << endl;
cout << "y==";
os << v.y << endl;
cout << "z==";
os << v.z << endl;
return os;
}
double get_x() const{
return x;
}
double get_y() const{
return y;
}
double get_z() const{
return z;
}
friend class Line;
};
Line.h
#pragma once
#include "Vec3.h"
#include<iostream>
#include <cmath>
using namespace std;
class Line {
Vec3 _p;//点
Vec3 _direction;//方向向量
public:
Line(double px, double py, double pz, double vx, double vy, double vz) {
_p.get_change(px, py, pz);
_direction.get_change(vx, vy, vz);
}
~Line(){}
Line(const Line& l) {
_p = l._p;
_direction = l._direction;
}
void change_pos(double tox, double toy, double toz) {
_p.change(tox, toy, toz);
}
void change_dire(double tox, double toy, double toz) {
_direction.change(tox, toy, toz);
}
void change(double px, double py, double pz, double dx, double dy, double dz) {
change_pos(px, py, pz);
change_dire(dx, dy, dz);
}
//重合
bool overlap(const Line& l) {
if (_direction.parallel(l._direction)) {
double t;
//计算参数方程中的参数
if (fabs(_direction.x) > 1e-10) {
t = (_p.x - l._p.x) / _direction.x;
}
else if (fabs(_direction.y) > 1e-10) {
t = (_p.y - l._p.y) / _direction.y;
}
else if (fabs(_direction.z) > 1e-10) {
t = (_p.z - l._p.z) / _direction.z;
}
if (fabs(_p.x - l._p.x - _direction.x * t) < 1e-10 \
&& fabs(_p.y - l._p.y - _direction.y * t) < 1e-10 \
&& fabs(_p.z - l._p.z - _direction.z * t) < 1e-10)
{
return true;
}
return false;
}
return false;
};
//平行
bool parallel(const Line& l) {
if (_direction.parallel(l._direction) ) {
return true;
}
return false;
}
bool cross(const Line& l) {
if (coplane(l) && !parallel(l)) {
return true;
}
return false;
}
bool coplane(const Line& l) const {//共面
double i, j, k;
i = _p.x - l._p.x;
j = _p.y - l._p.y;
k = _p.z - l._p.z;
if (i * (_direction.y * l._direction.z - _direction.z * l._direction.y)\
+ j * (_direction.z * l._direction.x - _direction.x * l._direction.z)\
+ k * (_direction.x * l._direction.y - _direction.y * l._direction.x) \
< 1e-10)
{
return true;
}
return false;
}
bool out_of_plane(const Line& l)const {
return !coplane(l);
}
int compute_dis(const Line& l, double& dis) {
//0 respresents overlap , 1 respresents parallel
//2 respresents cross ,3 respresents out of plane
if (overlap(l)) {
dis = 0;
return 0;
}
else if (coplane(l)) {
if (parallel(l)) {
double xcoe, ycoe, zcoe;
double tx, ty, tz;
tx = l._p.x - _p.x;
ty = l._p.y - _p.y;
tz = l._p.z - _p.z;
Vec3 tv(tx, ty, tz);
_direction.multi_cross(tv, xcoe, ycoe, zcoe);//叉乘不要搞错了
dis = sqrt(xcoe*xcoe+ycoe*ycoe+zcoe*zcoe) / _direction.length();
return 1;
}
else {
dis = 0;
return 2;
}
}
else {
double xcoe, ycoe, zcoe;
_direction.multi_cross(l._direction, xcoe, ycoe, zcoe);
dis = fabs(xcoe * (_direction.x - l._direction.x) \
+ ycoe * (_direction.y - l._direction.y) \
+ zcoe * (_direction.z - l._direction.z) \
/ (xcoe * xcoe + ycoe * ycoe + zcoe * zcoe));
return 3;
}
}
friend ostream& operator<<(ostream& os, const Line& l) {
cout << "p坐标:" << endl;
cout << l._p;
cout << "direction:" << endl;
cout << l._direction;
return os;
}
};
main
#include<iostream>
#include"Vec3.h"
#include"Line.h"
using namespace std;
int main() {
Line L1(9, 7, 2, 1, 0, 0);
Line L2 = L1;
double dis;
//overlap test
cout << L1.compute_dis(L2, dis) << endl;
cout << "L1 L2的距离是" <<dis<< endl;
//parallel test
L2.change(0, 7, -2, 1, 0, 0);
cout<<L1.compute_dis(L2, dis)<<endl;
cout << "L1 L2的距离是" << dis<<endl;
//cross test
L2.change(0,-7,2,1,5,0);
cout << L1.compute_dis(L2, dis) << endl;
cout << "L1 L2的距离是" << dis << endl;
//out of plane test
L1.change_dire(9, 0, -2);
cout << L1.compute_dis(L2, dis) << endl;
cout << "L1 L2的距离是" << dis << endl;
return 0;
}