空间点、线和面

1. 空间点、线和面
实现三维解析几何中的点、直线和平面类,
1 ) 能够实现直线的不同创建方式(例如,两个点确定一条直
线,两个相交的平面确定一条直线,空间曲线的点斜式)和平面的
不同创建方式(例如,三个不共线的点确定一个平面,一个点和一
个法向量确定一个平面);
2 ) 能够计算相应的距离:两点之间的距离,点到直线的距离,
点到平面的距离;
3 ) 能够计算空间直线的单位方向向量(长度为 1 ),空间平面的
单位法向量(长度为 1 );
4 ) 能够判断点和线的关系,线和线的关系,点和平面的关系,
线和平面的关系,平面和平面的关系。
5 注意:要考虑计算机中实数计算的精度误差(不同精度的数
值相等判断不能使用 == )。
提示:
点、直线和平面分别用类来封装,每个类的数据为该表示该类
需要的参数,例如,对于空间平面的一般方程为 ax+by+cz+d =
0 ,那么私有数据成员为 a, b, c d
空间直线和平面的不同创建方式定义为对应类的成员函数;
空间点和点、点和直线、点和平面、直线和直线、直线和平
面、平面和平面位置关系的判断定义为一般的函数;
要在 main 函数中对上述功能进行调用和验证。
代码示例:

#include<iostream>
#include<cmath>
#include<cstdio>

using namespace std;

//点类
class Point
{
public:
    double x,y,z;
    Point(double xp=0,double yp=0,double zp=0):x(xp),y(yp),z(zp){}
    void display()
    {
        cout<<"("<<x<<","<<y<<","<<z<<")  ";
    }
};

//面类
class Plane
{
public:
    double a,b,c,d;
    //直接输入平面的一般式
    Plane (double ap,double bp,double cp,double dp):a(ap),b(bp),c(cp),d(dp){}
    //三个不共线的点确定一个平面
     Plane(const Point& point1, const Point& point2, const Point& point3) {
        Point v1(point2.x - point1.x, point2.y - point1.y, point2.z - point1.z);
        Point v2(point3.x - point1.x, point3.y - point1.y, point3.z - point1.z);
        Point normal((v1.y * v2.z - v1.z * v2.y), (v1.z * v2.x - v1.x * v2.z), (v1.x * v2.y - v1.y * v2.x));
        a = normal.x;
        b = normal.y;
        c = normal.z;
        d = -(a * point1.x + b * point1.y + c * point1.z);
    }
    //一个点和一个法向量确定一个平面
    Plane(const Point &pp1,const Point &pp2)
    {
        a=pp2.x;
        b=pp2.y;
        c=pp2.z;
        d=-(pp1.x*a+pp1.y*b+pp1.z*c);
    }
    //求该平面的单位法向量,返回值是Point类,此时表示的不是点,表示单位法向量
    Point oneplane() const
    {
        double lengths=sqrt(a*a+b*b+c*c);
        return Point(a/lengths,b/lengths,c/lengths);
    }
    void display()
    {
        cout<<"平面的一般方程为:("<<a<<")*x+("<<b<<")*y+("<<c<<")*z+("<<d<<")=0"<<endl;
    }
};

//线类
class Line
{
public:
    Point p1,p2;
    //两点确定一条直线
    Line(const Point & pp1,const Point & pp2):p1(pp1),p2(pp2){}
    //两个平面确定一条直线
    Line(const Plane &pp1,const Plane &pp2)
    {
        double d=(pp1.a)*(pp2.b)-(pp2.a)*(pp1.b);
        if(d==0) cout<<"两平面重合或平行,没有交线"<<endl;
        else
        {
            double x = (pp1.b * pp2.d - pp2.b * pp1.d) / d;
            double y = (pp2.a * pp1.d - pp1.a * pp2.d) / d;
            p1=Point(x,y,0);
            p2=Point(x+1,y+1,0);
        }
    }
    //点斜式
    //pp1是点,pp2是斜率
    //pp3是为了与两点式区分开来,没有其他意义pp3和pp2一样就行
    Line(const Point &pp1,const Point &pp2,const Point &pp3)
    {
        p1=pp1;
        p2=Point(pp1.x+pp2.x,pp1.y+pp2.y,pp1.z+pp2.z);
    }

    //求该线的方向向量,返回值是Point类,此时表示的不是点,表示方向向量
    Point oneline() const
    {
        double lengths=sqrt(((p1.x-p2.x)*(p1.x-p2.x))+((p1.y-p2.y)*(p1.y-p2.y))+((p1.z-p2.z)*(p1.z-p2.z)));
        return Point((p1.x-p2.x)/lengths,(p1.y-p2.y)/lengths,(p1.z-p2.z)/lengths);
    }
    void display()
    {
        cout<<"线上存在两点:p1";
        p1.display();
        cout<<"p2";
        p2.display();
        cout<<endl;
    }
};

//两点间的距离
double d1(const Point &pp1,const Point &pp2)
{
    double lengths=sqrt(((pp1.x-pp2.x)*(pp1.x-pp2.x))+((pp1.y-pp2.y)*(pp1.y-pp2.y))+((pp1.z-pp2.z)*(pp1.z-pp2.z)));
    return lengths;
}

//点到直线的距离
double d2(const Point &point,const Line &line)
{
    //设点p,和直线line,直线上两点o,d
    Line op(point,line.p1);
    Point oneop=op.oneline();//op的单位方向向量
    Point oline=line.oneline();//line的单位方向向量
    double coso=oneop.x*oline.x+oneop.y*oline.y+oneop.z*oline.z;
    double sino=sqrt(1-coso*coso);
    double length=d1(point,line.p1);
    double d=abs(length*sino);
    return d;
}

//点到面的距离
double d3(const Point &point,Plane &plane)
{
    double pointd=-(point.x*plane.a+point.y*plane.b+point.z*plane.c);
    double d=abs((pointd-plane.d)/sqrt(plane.a*plane.a+plane.b*plane.b+plane.c*plane.c));
    return d;
}

//判断点和线的关系
void pointandline(const Point &point,const Line &line)
{
    //设点p,和直线line,直线上两点o,d
    Line op(point,line.p1);
    Point oneop=op.oneline();//op的单位方向向量
    Point oline=line.oneline();//line的单位方向向量
    if((oneop.x/oline.x)==(oneop.y/oline.y)&&(oneop.x/oline.x)==(oneop.z/oline.z))
    {
        cout<<"点在线上"<<endl;
    }
    else cout<<"点在线外"<<endl;
}

//判断线和线的关系
void lineandline(const Line &line1,const Line &line2)
{
    Point oline1=line1.oneline();//line1的单位方向向量
    Point oline2=line2.oneline();//line2的单位方向向量
    if((oline1.x/oline2.x)==(oline1.y/oline2.y)&&(oline1.x/oline2.x)==(oline1.z/oline2.z))
    {
        cout<<"两条直线平行或重合"<<endl;
    }
    else if((oline1.x*oline2.x+oline1.y*oline2.y+oline1.z*oline2.z)==0)
    {
        cout<<"两条直线垂直"<<endl;
    }
    else
        cout<<"两条直线相交但不垂直"<<endl;
}

//判断点和平面的关系
void pointandplane(const Point &point,const Plane &plane)
{
    if(point.x*plane.a+point.y*plane.b+point.z*plane.c+plane.d==0)
        cout<<"点在面上"<<endl;
    else
        cout<<"点不在面上"<<endl;
}

//判断线和平面的关系
void lineandplane(const Line &line,const Plane &plane)
{
    Point oline=line.oneline();//线的单位方向向量
    Point oplane=plane.oneplane();//面的法向量
    if((line.p1.x*plane.a+line.p1.y*plane.b+line.p1.z*plane.c+plane.d==0)&&(line.p2.x*plane.a+line.p2.y*plane.b+line.p2.z*plane.c+plane.d==0))
        cout<<"现在面上"<<endl;
    else if((oline.x/oplane.x)==(oline.y/oplane.y)&&(oline.x/oplane.x)==(oline.z/oplane.z))
        cout<<"线与面平行"<<endl;
    else if((oline.x*oplane.x+oline.y*oplane.y+oline.z*oplane.z)==0)
        cout<<"线垂直于面"<<endl;
    else
        cout<<"线交于面但不垂直"<<endl;
}

//判断平面和平面的关系
void planeandplane(const Plane &plane1,const Plane &plane2)
{
    double a1=plane1.a,b1=plane1.b,c1=plane1.c,d1=plane1.d;
    double a2=plane2.a,b2=plane2.b,c2=plane2.c,d2=plane2.d;
    if((a1/a2==b1/b2)&&(a1/a2==c1/c2)&&(a1/a2==d1/d2))
        cout<<"两平面重合"<<endl;
    else if((a1/a2==b1/b2)&&(a1/a2==c1/c2))
        cout<<"两平面平行"<<endl;
    else if(a1*a2+b1*b2+c1*c2==0)
        cout<<"两平面垂直"<<endl;
    else
        cout<<"两平面相交但不垂直"<<endl;

}


int main()
{
    cout<<"创建四个点:例(x,y,z)"<<endl;
    double x1,x2,x3,x4,y1,y2,y3,y4,z1,z2,z3,z4;
    scanf("(%lf,%lf,%lf)(%lf,%lf,%lf)(%lf,%lf,%lf)(%lf,%lf,%lf)",&x1,&y1,&z1,&x2,&y2,&z2,&x3,&y3,&z3,&x4,&y4,&z4);
    Point p1(x1,y1,z1),p2(x2,y2,z2),p3(x3,y3,z3),p4(x4,y4,z4);
    cout<<"p1";
    p1.display();
    cout<<"p2";
    p2.display();
    cout<<"p3";
    p3.display();
    cout<<"p4";
    p4.display();
    cout<<endl;

    cout<<"用两个点(p1、p2)创建一条直线line1:"<<endl;
    Line line1(p1,p2);
    line1.display();
    cout<<"直线line1的单位方向向量为:"<<endl;
    Point oline1=line1.oneline();
    oline1.display();
    cout<<endl;
    cout<<"用三个点(p1、p2、p3)创建一个平面plane1:"<<endl;
    Plane plane1(p1,p2,p3);
    plane1.display();
    cout<<"平面plane1的单位法向量为:"<<endl;
    Point oplane1=plane1.oneplane();
    oplane1.display();
    cout<<endl;
    cout<<"请输入一个单位方向向量:例x,y,z"<<endl;
    double xp,yp,zp;
    scanf("%ld,%ld,%ld",&xp,&yp,&zp);
    Point oplane(xp,yp,zp);
    cout<<"用p1和以上面的单位向量为斜率创建一条直线line2:"<<endl;
    Line line2(p1,oplane,oplane);
    line2.display();
    cout<<"用p1和以上面的单位向量为法向量创建一个平面plane2:"<<endl;
    Plane plane2(p1,oplane);
    plane2.display();
    cout<<"用两个平面(plane1和plane2)创建一条直线(line3):"<<endl;
    Line line3(plane1,plane2);
    line3.display();

    cout<<"两点(p1,p2)之间的距离为:"<<d1(p1,p2)<<endl;
    cout<<"点p3到直线line1的距离为:"<<d2(p3,line1)<<endl;
    cout<<"点p4到平面plane1的距离为:"<<d3(p4,plane1)<<endl;

    cout<<"判断点p1和线line1的关系:"<<endl;
    pointandline(p1,line1);
    cout<<"判断线line1与线line2的关系:"<<endl;
    lineandline(line1,line2);
    cout<<"判断点p1和平面plane1的关系:"<<endl;
    pointandplane(p1,plane1);
    cout<<"判断线line2和平面plane2的关系:"<<endl;
    lineandplane(line2,plane2);
    cout<<"判断平面和平面的关系:"<<endl;
    planeandplane(plane1,plane2);

    return 0;
}
//(1,2,3)(3,2,1)(1,3,5)(2,4,6)
//1,1,1
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值