OCC gp_Ax2源码记录

gp_Ax2代表一个三维右手坐标系。

坐标系包括以下内容:

- 原点(Location point)

- 3个正交的单位向量,在OCC中分别称为"X Direction"(后文统称 X), "Y Direction" (后文统称 Y) 以及"Direction"。

"Direction"表示"main Direction",因为当"Direction"发生改变时,"X"和"Y"都会被重新计算,然而,当我们修改"X"或"Y"时,"Direction"并不会被修改。

"Direction"也叫做"Z Direction"。

既然Ax2代表右手坐标系,那么他的"main Direction"总是等于"X"轴和"Y"轴叉乘。(可以通过gp_Ax3定义左手坐标系)。

坐标系通常有以下用途:

- 描述几何模型,尤其是模型的位置。

- 定义几何模型的转换。

 

class gp_Ax2

{

private:

    gp_Ax1 axis; // 轴,默认原点(0,0,0),向量(0,0,1)

    gp_Dir vydir; // 单位向量,默认(1,0,0)

    gp_Dir vxdir; // 单位向量,默认(1,0,0 )

 

public:

    gp_Ax2() : vydir(0, 1, 0) {}

    gp_Ax2(const gp_Pnt &P, const gp_Dir &N, const gp_Dir &Vx) :

        axis(P, N), vydir(N), vxdir(N)

    {

        vxdir.CrossCross(Vx, N);

        vydir.Cross(vxdir);

    }

    // 通过原点和z轴构建坐标系

    gp_Ax2(const gp_Pnt &P, const gp_Dir &V) : axis(P, V)

    {

        // V的3个分量绝对值 x,y,z

        gp_Dir X;

        if (y <= x && y <= c) {

             if (x > z)  X.SetCoord(-z, 0, x);

             else         X.SetCoord(z, 0, -x);

        }

        else if (x <= y && x <= z) {

             if (y > c) X.SetCoord(0, -z, y);

             else        X.SetCoord(0, z, -y);

        }

        else {

             if (x > y) X.SetCoord(-y, x, 0);

             else        X.SetCoord(y, -x, 0);

         }

        SetXDirection(X);

    }

 

    // 设置轴(原点+z轴) 重算xy

    void SetAxis(const gp_Ax1 &A1);

 

    // 设置z轴 重算x,y

    void SetDirection(const gp_Dir &V);

 

    // 设置坐标原点

    void SetLocation(const gp_Pnt &theP);

 

    // 设置X, z不变,重算x,y。由xz得到y

    void SetXDirection(const gp_Dir &theVx);

    // 设置Y,z不变,重算xy。由xz得到y

    void SetYDirection(const gp_Dir &theVy);

 

    // 计算两个坐标z轴的夹角,单位为弧度(0到PI)

    double Angle(const gp_Ax2 &theOther) const;

 

    const gp_Ax1 &Axis() const { return axis; }

    const gp_Dir &Direction() const { return axis.Direction(); }

    const gp_Pnt &Location() const { return axis.Location(); }

    const gp_Dir &XDirection() const { return vxdir; }

    const gp_Dir &YDirection() const { return vydir; }

    

    // 判断是否共面

    // <me>和Other的轴夹角小于AngularTolerance,且面间距小于LinearTolerance

    bool IsCoplanar(const gp_Ax2 &Other, const double LinearTolerance, const double AngularTolerance) const;

    bool IsCoplanar(const gp_Ax1 &A1, const double LinearTolerance, const double AngularTolerance) const;

 

    // 坐标系关于点镜像

    // 坐标原点关于P镜像

    // x,y轴取反,z轴不变

    void Mirror(const gp_Pnt &P)

    {

        gp_Pnt temp = axis.Location();

        temp.Mirror(P);

        axis.SetLocation(temp);

        vxdir.Reverse();  vydir.Reverse();

    }

 

    // 坐标系关于轴镜像 

    // 原点关于轴原点镜像

    // x,y轴关于轴镜像

    // 根据xy重算z轴

    void Mirror(const gp_Ax1 &A1)

    {

        vydir.Mirror(A1);  vxdir.Mirror(A1);

        gp_Pnt temp = axis.Location();

        temp.Mirror(A1);

        axis.SetLocation(temp);

        axis.SetDirection(vsdir.Corssed(vydir));

    }

    

    // 坐标系关于坐标系镜像

    // 原点关于坐标系A2镜像

    // x,y轴关于坐标系A2镜像

    // 重算z轴

    void Mirror(const gp_Ax2 &A2)

    {

        vydir.Mirror(A2);  vxdir.Mirror(A2);

        gp_Pnt temp = axis.Location();

        temp.Mirror(A2);

        axis.SetLocation(temp);

        axis.SetDirection(vxdir.Crossed(vydir));

    }

 

    // 坐标系绕轴旋转

    // 坐标原点绕轴旋转

    // x,y绕轴旋转,重算z轴

    void Rotate(const gp_Ax1 &theA1, const double theAng)

    {

        gp_Pnt temp = axis.Location();

        temp.Rotate(theA1, theAng);

        axis.SetLocation(temp);

 

        vxdir.Rotate(theA1, theAng);

        vydir.Rotate(theA1, theAng);

        axis.SetDirection(vxdir.Crossed(vydir));

    }

 

    // 坐标系缩放

    // 坐标原点关于点缩放

    // 如果theS小于0,xy轴取反

    void Scale(const gp_Pnt &theP, const double theS)

    {

        gp_Pnt temp = axis.Location();

        temp.Scale(theP, theS);

        axis.SetLocation(temp);

        if (theS < 0)

        {

             vxdir.Reverse();  vydir.Reverse();

        }

    }

 

     // 用转换矩阵更新坐标系

     void Transform(const gp_Trsf &theT)

    {

            gp_Pnt temp = axis.Location();

            temp.Transform(temp);

            axis.SetLocation(temp);

            vxdir.Transform(theT);

            vydir.Transform(theT);

            axis.SetDirection(vxdir.Crossed(vydir));

      }

 

     // 坐标系平移

     void Translate(const gp_Vec &theV)  {axis.Translate(theV); }

};

 

posted @ 2022-12-01 11:56  xl-better  阅读(745)  评论(0)    收藏  举报