C++ 实现三维空间点、直线和平面解析几何
C++ 实现三维空间点、直线和平面解析几何
本文提供一个 C++ 代码示例,用于实现三维解析几何中的点、直线和平面类,包含距离计算、单位向量计算、位置关系判断等功能。
#include <iostream>
#include <cmath>
class Point {
private:
double x, y, z;
public:
Point(double _x = 0, double _y = 0, double _z = 0) : x(_x), y(_y), z(_z) {}
double getX() const { return x; }
double getY() const { return y; }
double getZ() const { return z; }
};
class Line {
private:
Point p1, p2;
public:
Line(const Point& _p1, const Point& _p2) : p1(_p1), p2(_p2) {}
const Point& getP1() const { return p1; }
const Point& getP2() const { return p2; }
};
class Plane {
private:
double a, b, c, d;
public:
Plane(double _a = 0, double _b = 0, double _c = 0, double _d = 0) : a(_a), b(_b), c(_c), d(_d) {}
double getA() const { return a; }
double getB() const { return b; }
double getC() const { return c; }
double getD() const { return d; }
};
double distance(const Point& p1, const Point& p2) {
double dx = p1.getX() - p2.getX();
double dy = p1.getY() - p2.getY();
double dz = p1.getZ() - p2.getZ();
return std::sqrt(dx*dx + dy*dy + dz*dz);
}
double distance(const Point& p, const Line& l) {
const Point& p1 = l.getP1();
const Point& p2 = l.getP2();
double dx = p2.getX() - p1.getX();
double dy = p2.getY() - p1.getY();
double dz = p2.getZ() - p1.getZ();
double t = ((p.getX() - p1.getX())*dx + (p.getY() - p1.getY())*dy + (p.getZ() - p1.getZ())*dz) / (dx*dx + dy*dy + dz*dz);
double lx = p1.getX() + t*dx;
double ly = p1.getY() + t*dy;
double lz = p1.getZ() + t*dz;
return distance(p, Point(lx, ly, lz));
}
double distance(const Point& p, const Plane& pl) {
double a = pl.getA();
double b = pl.getB();
double c = pl.getC();
double d = pl.getD();
return std::abs(a*p.getX() + b*p.getY() + c*p.getZ() + d) / std::sqrt(a*a + b*b + c*c);
}
Point unitDirectionVector(const Line& l) {
double dx = l.getP2().getX() - l.getP1().getX();
double dy = l.getP2().getY() - l.getP1().getY();
double dz = l.getP2().getZ() - l.getP1().getZ();
double length = std::sqrt(dx*dx + dy*dy + dz*dz);
return Point(dx/length, dy/length, dz/length);
}
Point unitNormalVector(const Plane& pl) {
double a = pl.getA();
double b = pl.getB();
double c = pl.getC();
double length = std::sqrt(a*a + b*b + c*c);
return Point(a/length, b/length, c/length);
}
bool isPointOnLine(const Point& p, const Line& l) {
double dx = l.getP2().getX() - l.getP1().getX();
double dy = l.getP2().getY() - l.getP1().getY();
double dz = l.getP2().getZ() - l.getP1().getZ();
double t = ((p.getX() - l.getP1().getX())*dx + (p.getY() - l.getP1().getY())*dy + (p.getZ() - l.getP1().getZ())*dz) / (dx*dx + dy*dy + dz*dz);
double lx = l.getP1().getX() + t*dx;
double ly = l.getP1().getY() + t*dy;
double lz = l.getP1().getZ() + t*dz;
return std::abs(lx - p.getX()) < 1e-6 && std::abs(ly - p.getY()) < 1e-6 && std::abs(lz - p.getZ()) < 1e-6;
}
bool isLineIntersectLine(const Line& l1, const Line& l2) {
const Point& p1 = l1.getP1();
const Point& p2 = l1.getP2();
const Point& p3 = l2.getP1();
const Point& p4 = l2.getP2();
double dx1 = p2.getX() - p1.getX();
double dy1 = p2.getY() - p1.getY();
double dz1 = p2.getZ() - p1.getZ();
double dx2 = p4.getX() - p3.getX();
double dy2 = p4.getY() - p3.getY();
double dz2 = p4.getZ() - p3.getZ();
double d = dx1*dy2*dz2 - dx2*dy1*dz1;
return std::abs(d) > 1e-6;
}
bool isPointOnPlane(const Point& p, const Plane& pl) {
double a = pl.getA();
double b = pl.getB();
double c = pl.getC();
double d = pl.getD();
return std::abs(a*p.getX() + b*p.getY() + c*p.getZ() + d) < 1e-6;
}
bool isLineIntersectPlane(const Line& l, const Plane& pl) {
const Point& p1 = l.getP1();
const Point& p2 = l.getP2();
double a = pl.getA();
double b = pl.getB();
double c = pl.getC();
double d = pl.getD();
double d1 = a*p1.getX() + b*p1.getY() + c*p1.getZ() + d;
double d2 = a*p2.getX() + b*p2.getY() + c*p2.getZ() + d;
return (d1 >= 0 && d2 <= 0) || (d1 <= 0 && d2 >= 0);
}
bool isPlaneIntersectPlane(const Plane& pl1, const Plane& pl2) {
double a1 = pl1.getA();
double b1 = pl1.getB();
double c1 = pl1.getC();
double d1 = pl1.getD();
double a2 = pl2.getA();
double b2 = pl2.getB();
double c2 = pl2.getC();
double d2 = pl2.getD();
double d = a1*b2*c2 - a2*b1*c1;
return std::abs(d) > 1e-6;
}
int main() {
Point p1(1, 2, 3);
Point p2(4, 5, 6);
Line l(p1, p2);
Plane pl(1, 2, 3, 4);
std::cout << "Distance between p1 and p2: " << distance(p1, p2) << std::endl;
std::cout << "Distance between p1 and l: " << distance(p1, l) << std::endl;
std::cout << "Distance between p1 and pl: " << distance(p1, pl) << std::endl;
Point dir = unitDirectionVector(l);
std::cout << "Direction vector of l: (" << dir.getX() << ", " << dir.getY() << ", " << dir.getZ() << ")" << std::endl;
Point normal = unitNormalVector(pl);
std::cout << "Normal vector of pl: (" << normal.getX() << ", " << normal.getY() << ", " << normal.getZ() << ")" << std::endl;
std::cout << "p1 is on l: " << isPointOnLine(p1, l) << std::endl;
std::cout << "l intersects pl: " << isLineIntersectPlane(l, pl) << std::endl;
std::cout << "pl intersects pl: " << isPlaneIntersectPlane(pl, pl) << std::endl;
return 0;
}
该代码实现了以下功能:
- 定义了
Point、Line和Plane类,分别用于表示空间点、直线和平面。 - 提供了各种成员函数来创建点、直线和平面,以及获取它们的属性。
- 提供了计算距离的函数,包括两点之间的距离、点到直线的距离、点到平面的距离。
- 提供了计算单位方向向量和单位法向量的函数。
- 提供了判断位置关系的函数,包括点和线的关系、线和线的关系、点和平面的关系、线和平面的关系、平面和平面的关系。
- 在
main函数中创建了一些示例对象,并使用这些函数进行测试。
代码说明:
- 所有函数都使用了适当的精度误差判断,以避免浮点数计算的精度问题。
- 代码中使用了
std::abs函数来计算绝对值,并使用了1e-6作为精度误差判断的阈值。 - 代码中使用了
std::sqrt函数来计算平方根。 - 代码中使用了
std::cout函数来输出结果。
使用方法:
- 将代码保存为
.cpp文件。 - 使用 C++ 编译器编译代码,例如 g++:
g++ your_file.cpp -o your_file - 运行可执行文件:
./your_file
注意:
- 此代码仅供参考,实际应用中可能需要根据具体需求进行修改和扩展。
- 为了提高可读性和代码结构,您可以考虑将代码拆分成多个
.cpp文件,并使用头文件进行管理。 - 您可以根据需要添加更多的功能,例如:
- 计算空间直线的方程。
- 计算空间平面的方程。
- 计算空间直线的交点。
- 计算空间平面的交线。
- 计算空间直线和空间平面的交点。
- 计算两个空间平面之间的夹角。
- 判断空间直线是否平行于空间平面。
- 判断空间直线是否垂直于空间平面。
- 判断两个空间平面是否平行。
- 判断两个空间平面是否垂直。
- 判断两个空间平面是否重合。
- 您可以根据实际需求选择合适的精度误差判断阈值。
总结:
本文提供了 C++ 代码示例,用于实现三维空间点、直线和平面解析几何,并提供了距离计算、单位向量计算、位置关系判断等功能。希望本文能够帮助您学习和应用 C++ 语言实现三维几何计算。
其他相关资源:
原文地址: https://www.cveoy.top/t/topic/qr8i 著作权归作者所有。请勿转载和采集!