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;
}

该代码实现了以下功能:

  • 定义了 PointLinePlane 类,分别用于表示空间点、直线和平面。
  • 提供了各种成员函数来创建点、直线和平面,以及获取它们的属性。
  • 提供了计算距离的函数,包括两点之间的距离、点到直线的距离、点到平面的距离。
  • 提供了计算单位方向向量和单位法向量的函数。
  • 提供了判断位置关系的函数,包括点和线的关系、线和线的关系、点和平面的关系、线和平面的关系、平面和平面的关系。
  • main 函数中创建了一些示例对象,并使用这些函数进行测试。

代码说明:

  • 所有函数都使用了适当的精度误差判断,以避免浮点数计算的精度问题。
  • 代码中使用了 std::abs 函数来计算绝对值,并使用了 1e-6 作为精度误差判断的阈值。
  • 代码中使用了 std::sqrt 函数来计算平方根。
  • 代码中使用了 std::cout 函数来输出结果。

使用方法:

  1. 将代码保存为 .cpp 文件。
  2. 使用 C++ 编译器编译代码,例如 g++:
    g++ your_file.cpp -o your_file
    
  3. 运行可执行文件:
    ./your_file
    

注意:

  • 此代码仅供参考,实际应用中可能需要根据具体需求进行修改和扩展。
  • 为了提高可读性和代码结构,您可以考虑将代码拆分成多个 .cpp 文件,并使用头文件进行管理。
  • 您可以根据需要添加更多的功能,例如:
    • 计算空间直线的方程。
    • 计算空间平面的方程。
    • 计算空间直线的交点。
    • 计算空间平面的交线。
    • 计算空间直线和空间平面的交点。
    • 计算两个空间平面之间的夹角。
    • 判断空间直线是否平行于空间平面。
    • 判断空间直线是否垂直于空间平面。
    • 判断两个空间平面是否平行。
    • 判断两个空间平面是否垂直。
    • 判断两个空间平面是否重合。
  • 您可以根据实际需求选择合适的精度误差判断阈值。

总结:

本文提供了 C++ 代码示例,用于实现三维空间点、直线和平面解析几何,并提供了距离计算、单位向量计算、位置关系判断等功能。希望本文能够帮助您学习和应用 C++ 语言实现三维几何计算。

其他相关资源:

C++ 实现三维空间点、直线和平面解析几何

原文地址: https://www.cveoy.top/t/topic/qr8i 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录