通过标准网格点计算等值线

本资源提供了通过输入标准网格点数据计算等值线的接口,接口通过Qt实现,调整部分数据类型后也可转为C++代码。 接口使用也比较简单,将本资源的源码添加到工程中,然后调用GetContourlinesByGridPoints_new()函数即可得到等值线。该函数输入有2个,第一个是所有标准网格点的值,第二个参数是等值线的间隔。 本资源包括代码文件如下:

struct.h:结构体定义文件

ContourGenerator.h接口定义头文件

ContourGenerator.cpp接口实现代码文件

struct.h:结构体定义文件

#ifndef STRUCT_H
#define STRUCT_H

#include <QString>
#include <QList>
#include <QMap>

typedef float CONTOUR_AX;


class RectLine;
class ContourRect;
class RectLine;


//点
struct St3DPoint
{
public:
    CONTOUR_AX x;
    CONTOUR_AX y;
    float z;
    bool isBandage;
    bool isVertix;

    QList<ContourRect*> listBelong2Rect;       //所在的子网格
    QList<RectLine*> listBelong2Line;           //所在的线段
    St3DPoint(CONTOUR_AX a,CONTOUR_AX b,float c){x =a; y = b,z = c;isBandage = false; isVertix = false;}
    St3DPoint(){isBandage = false; isVertix = false;}
    St3DPoint(St3DPoint* p){x = p->x; y = p->y;z = p->z; isBandage = p->isBandage; isVertix = p->isVertix;}

    //添加所属网格
    void Add2Rect(ContourRect* rect)
    {
        if( !listBelong2Rect.contains(rect)) listBelong2Rect.push_back(rect);
    }
    //添加所属线段
    void Add2Line(RectLine* line)
    {
        if(!listBelong2Line.contains(line)) listBelong2Line.push_back(line);
    }

    void DeleteFromLIne(RectLine* line)
    {
        QList<RectLine*>::Iterator it = listBelong2Line.begin();
        for( int i = 0; i < listBelong2Line.size(); i++,it++)
        {
            if( listBelong2Line.at(i) == line)
            {
                listBelong2Line.erase(it);
                break;
            }
        }
    }

    int GetRectNumber(){return listBelong2Rect.size();}
    int GetLineNumber(){return listBelong2Line.size();}

    QString GetId(){return QString("%1").arg(x) + "," + QString("%1").arg(y);}


};

//边界
struct StBandange
{
    CONTOUR_AX xMin;
    CONTOUR_AX xMax;
    CONTOUR_AX yMin;
    CONTOUR_AX yMax;
    float zMin;
    float zMax;
};

//子网格中的曲线
class RectLine
{
public:
    RectLine(){isInUse = false;}
    QList<St3DPoint*> list;
    bool isInUse;

};

//子网格点信息
class RectPointsInfo
{
public:
    RectPointsInfo(){isAllLineGeted = false;}
    QList<St3DPoint*> list;
    bool isAllLineGeted;                                         //当前网格中的线段是否已经计算完成
};

//子网格
class ContourRect
{
public:
    ContourRect(){}
    ~ContourRect(){}

    St3DPoint downleft;
    St3DPoint downright;
    St3DPoint upleft;
    St3DPoint upright;
    QMap<int,RectPointsInfo* > mapPoints;  //当前网格中每个等值线值对应的点集
    //QMap<float,RectLine* > mapLines;                  //当前网格中的线段,做多里那个条


    int GetPointSize(int v)
    {
        QMap<int,RectPointsInfo* >::Iterator it = mapPoints.find(v);  //当前网格中每个等值线值对应的点集
        if( it == mapPoints.end())
            return 0;
        else
            return it.value()->list.size();
    }


};

//曲线类型
enum EPolygonType
{
    e_close=0,
    e_open,
    e_unfinished
};



//等值线
class ContourLine
{
public:
    ContourLine(){}
    ~ContourLine(){}
    QList<St3DPoint> listPoints;
    EPolygonType eType;
};

#endif // STRUCT_H

ContourGenerator.h接口定义头文件

#ifndef CONTOURGENERATOR_H
#define CONTOURGENERATOR_H

#include "struct.h"

/*
  *等值线特性:
  *      1.等值线是连续的
  *      2.等值线是闭合的,但在局部范围内,可以是非闭合的
  *思路:
  *      1.离散数据网格化
  *      2.计算每个小网格中的等值线点
  *      3.将每个小网格中的等值线点组合,形成线段
  *          3.1.网格中只有一个点,根据成对原则,改点与其他临近网格必能成对,所以在本矩形区域忽略该点,由其他网格进行计算
  *          3.2 网格中只有两个点,则这两个点直接相连,形成一条线段
  *          3.3 网格中有三个点
  *                计算每个点的所属网格中等值线点的个数
  *                顶点:最多属于4个小网格
  *                边界点:只属于1个小网格
  *                中间点:只属于2个小网格
  *                原则:每个等值点最多只能被两条直线使用,
  *          3.4 网格中有四个点
  *
  *      4.将所有小网格中的线段组合,形成等值线:等值线完整的条件:
  *          a. 等值线闭合,即第一个点与最后一个点是同一个点
  *          b. 等值线第一个点和最后一个点在边界上
  *
  *
  *说明:
  *        输入数据是标准网格数据(非标准网格数据,需要采用差值算法将离散点转换为标准网格点)
  */



class ContourGenerator
{
public:
    ContourGenerator();
    ~ContourGenerator();

    /**
     * @brief 根据规则网格生成等值线
     * @param[in] points规则网格数据
     * @param[in] space 等值线间隔值
     * @return 等值线集合
     */
    QMap<int,QList<ContourLine> > GetContourlinesByGridPoints_new(QList<St3DPoint> points,int space);



    /**
     * @brief 获取边界点
     * @return
     */
    StBandange GetBandage();



private:
    //网格的边界
    CONTOUR_AX m_xMin;
    CONTOUR_AX m_xMax;
    CONTOUR_AX m_yMin;
    CONTOUR_AX m_yMax;
    float m_zMin;
    float m_zMax;
    int m_row;
    int m_col;

    QMap<int,QList<ContourLine> > m_mapAllContourLines;                   //所有等值线
    QMap<QString,ContourRect*> m_mapAllRects;                                        //所有的子网格
    QMap<QString,St3DPoint*> m_mapAllContourPoints;                             //所有的等值线点
    QMap<int,QList<RectLine*> > m_mapAllRectLines;                             //所有子网格中的线段

private:
    void ReleaseMemory();                                                                                                                 //释放内存
    void GetBoundary(QList<St3DPoint> points);                                                                               //获取网格的边界
    void GetAllRects(QList<St3DPoint> points, QList<int> values);                                                 //获取所有矩形区域

    QString GetRectID(int i, int j);                                                                              //根据行号和列号获取矩形区域ID,后两个参数是最大行号和最大列号
    ContourRect* GetRectByID(QString id);                                                              //根据ID获取矩形区域
    QList<St3DPoint*> GetPointsInRect(ContourRect* rect,int value);                    //获取矩形区域内value的等值点
    St3DPoint* isEdgeContainsValue(St3DPoint start,St3DPoint end,int value);          //判断边上是否有value的点
    QString GetPointID(CONTOUR_AX x,CONTOUR_AX y);                              //根据坐标获取点的ID
    St3DPoint* GetPointByAx(CONTOUR_AX x,CONTOUR_AX y);                    //根据坐标获取点的指针


    void GetAllRectLines();                                                                                          //计算所有网格中的曲线(或者线段)
    void Deal3Points(ContourRect* rect,int value,RectPointsInfo* list);                     //处理子网格中包含3个等值点的情况
    void Deal4Points(ContourRect* rect,int value,RectPointsInfo* list);                     //处理子网格中包含4个等值点的情况
    bool isPointCanbeUsed(St3DPoint* p);                                                                  //判断点是否能够被使用


    void GetContourLinesByRectLine();                                                                                   //从网格线生成等值线
    void GetCompleteLine(RectLine* start, QList<RectLine*> &listLines, ContourLine &st);  //将所有能与本线段连接的线连起来

    CONTOUR_AX Distance(St3DPoint end1,St3DPoint start2);                                             //获取两点间的距离
    bool equals(St3DPoint t1,St3DPoint t2);                                                                               //判断两个点是否是同一个点
    void Add2Map(ContourLine line,int v,QMap<int,QList<ContourLine> > &map);        //插入队列

    //根据基点和间隔获取等值线  20191018新增
    QList<int> GetNewLineValues(int space) ;
};

#endif // CONTOURGENERATOR_H

ContourGenerator.cpp接口实现代码文件

#include "ContourGenerator.h"

#include <QDebug>
#include <math.h>



ContourGenerator::ContourGenerator()
{
    m_xMin = 100000;
    m_xMax = -100000;
    m_yMin = 100000;
    m_yMax = -100000;

    m_zMin = 100000.0;
    m_zMax = -10000.0;

    m_row = 0;
    m_col = 0;
}

ContourGenerator::~ContourGenerator()
{
}

//根据规则网格生成等值线
QMap<int, QList<ContourLine> > ContourGenerator::GetContourlinesByGridPoints_new(QList<St3DPoint> points,  int space)
{
    if( points.size() <= 0)
        qDebug() << "输入数据为空";
    //1.计算边界
    GetBoundary(points);
    //2.获取等值线
    QList<int> lineValues =GetNewLineValues(space);
    if(lineValues.size() <= 0)
        return m_mapAllContourLines;

    //3.初始化网格并计算每个小网格中的等值点
    GetAllRects(points,lineValues);

    //4.计算所有网格中的曲线(或者线段)
    GetAllRectLines();

    //5.根据网格线生成等值线
    GetContourLinesByRectLine();


    //释放内存
    ReleaseMemory();

    return m_mapAllContourLines;
}

//获取边界点
StBandange ContourGenerator::GetBandage()
{
    StBandange st;
    st.xMin = m_xMin;
    st.xMax = m_xMax;
    st.yMin = m_yMin;
    st.yMax = m_yMax;
    st.zMin = m_zMin;
    st.zMax = m_zMax;
    return st;
}

//释放内存
void ContourGenerator::ReleaseMemory()
{
    //所有的子网格
    QMap<QString,ContourRect*>::Iterator it = m_mapAllRects.begin();
    for(; it != m_mapAllRects.end(); it++)
    {
        ContourRect* p = it.value();
        delete p;
        p = 0;
    }
    m_mapAllRects.clear();

    //所有的等值线点
    QMap<QString,St3DPoint*>::Iterator itPoint = m_mapAllContourPoints.begin();
    for( ; itPoint != m_mapAllContourPoints.end(); itPoint++)
    {
        St3DPoint* p = itPoint.value();
        delete p; p = 0;
    }
    m_mapAllContourPoints.clear();

    //所有子网格中的线段:网格线段已经在GetCompleteLine函数中释放,因此,此处只需将map清空即可
    m_mapAllRectLines.clear();
}
//获取网格的边界
void ContourGenerator::GetBoundary(QList<St3DPoint> points)
{
    QList<CONTOUR_AX> listx;
    QList<CONTOUR_AX> listy;
    for(int i = 0; i < points.size(); i++)
    {
        if( !listx.contains(points.at(i).x))
            listx.push_back(points.at(i).x);

        if(!listy.contains(points.at(i).y))
            listy.push_back(points.at(i).y);



        if( points.at(i).x >= m_xMax)
            m_xMax = points.at(i).x;
        if(points.at(i).x <= m_xMin)
            m_xMin = points.at(i).x;
        if(points.at(i).y >= m_yMax)
            m_yMax = points.at(i).y;
        if(points.at(i).y <= m_yMin)
            m_yMin = points.at(i).y;

        if(points.at(i).z >= m_zMax)
            m_zMax = points.at(i).z;
        if( points.at(i).z <= m_zMin)
            m_zMin = points.at(i).z;


    }
    m_row = listy.size();
    m_col = listx.size();
    //qDebug() << "row = " << m_row << ", col=" << m_col;
    //qDebug() << m_xMin << "-" << m_xMax << "    " << m_yMin << "-" << m_yMax << "   " << m_zMin << "-" << m_zMax;
}




//获取所有矩形区域及等值点
void ContourGenerator::GetAllRects(QList<St3DPoint> points, QList<int> values)
{
    m_mapAllContourPoints.clear();         //所有等值点  -- 为方便计算

    //输入点是列输入
    for( int i = 0; i < m_col-1; i++)
    {
        for ( int j = 0; j < m_row-1; j++)
        {
            QString id = GetRectID(i,j);
            //生成小矩形区域
            ContourRect* prect = new ContourRect();
            prect->upleft =   points.at( i * m_row + j);
            prect->downleft =  points.at( i * m_row + j+1);
            prect->upright =  points.at((i+1)*m_row +j);
            prect->downright =   points.at((i+1)*m_row + j+1);
            m_mapAllRects.insert(id,prect);

            //计算区域内的等值线点
            for( int x = 0; x < values.size(); x++)
            {
                //1.获取所有等值点
                QList<St3DPoint*> listPoint = GetPointsInRect(prect, values.at(x));

                //2.保存

                RectPointsInfo* ps = new RectPointsInfo();
                ps->list = listPoint;


                //3.如果网格中仅仅包含两个点,则这来两个点直接形成一条直线,并设置该网格的状态为完成状态
                if(listPoint.size() == 1)
                {
                    ps->isAllLineGeted = true;

                }
                else if(listPoint.size() == 2)
                {
                    RectLine* line = new RectLine();
                    line->list.push_back(listPoint.at(0));
                    line->list.push_back(listPoint.at(1));

                    listPoint.at(0)->Add2Line(line);
                    listPoint.at(1)->Add2Line(line);
                    ps->isAllLineGeted = true;

                    QMap<int,QList<RectLine*> >::Iterator itss = m_mapAllRectLines.find(values.at(x));                                   //所有子网格中的线段
                    if( itss == m_mapAllRectLines.end())
                    {
                        QList<RectLine*> listLines ;
                        listLines.push_back(line);
                        m_mapAllRectLines.insert(values.at(x),listLines);
                    }else
                        itss.value().push_back(line);
                }else if( listPoint.size() == 4)
                {
                    //先组成两条线段
                    RectLine* line1 = new RectLine();
                    line1->list.push_back(listPoint.at(0));
                    line1->list.push_back(listPoint.at(1));

                    listPoint.at(0)->Add2Line(line1);
                    listPoint.at(1)->Add2Line(line1);



                    RectLine* line2 = new RectLine();
                    line2->list.push_back(listPoint.at(2));
                    line2->list.push_back(listPoint.at(3));

                    listPoint.at(2)->Add2Line(line2);
                    listPoint.at(3)->Add2Line(line2);

                    QMap<int,QList<RectLine*> >::Iterator itss = m_mapAllRectLines.find(values.at(x));                                   //所有子网格中的线段
                    if( itss == m_mapAllRectLines.end())
                    {
                        QList<RectLine*> listLines ;
                        listLines.push_back(line1);
                        listLines.push_back(line2);
                        m_mapAllRectLines.insert(values.at(x),listLines);
                    }else
                    {
                        itss.value().push_back(line1);
                        itss.value().push_back(line2);
                    }


                }
                prect->mapPoints.insert(values.at(x),ps);
            }

        } //for j end
    } // for i end

}

//根据行号和列号获取矩形区域ID
QString ContourGenerator::GetRectID(int i, int j)
{
    return QString::number(i) + "," + QString::number(j);
}

//根据ID获取矩形区域
ContourRect *ContourGenerator::GetRectByID(QString id)
{
    QMap<QString,ContourRect*>::Iterator it = m_mapAllRects.find(id);
    if( it == m_mapAllRects.end() )
    {
        return 0;
    }
    else
        return it.value();
}

//获取矩形区域内value的等值点
QList<St3DPoint*> ContourGenerator::GetPointsInRect(ContourRect *rect, int value)
{
    //从左侧边开始,逆时针方向排放
    QList<St3DPoint*> listout;
    //downleft -upleft
    St3DPoint* p2 = isEdgeContainsValue(rect->downleft,rect->upleft,value);
    if(p2 )
    {
        p2->Add2Rect(rect);
        listout.push_back(p2);
    }

    //downleft-downright
    St3DPoint* p1 = isEdgeContainsValue(rect->downleft,rect->downright,value);
    if( p1 && (!listout.contains(p1)) )
    {
        p1->Add2Rect(rect);
        listout.push_back(p1);
    }


    //downright-upright
    St3DPoint* p3 =isEdgeContainsValue(rect->downright,rect->upright,value);
    if(p3 && (!listout.contains(p3)) )
    {
        p3->Add2Rect(rect);
        listout.push_back(p3);
    }


    //upleft - upright
    St3DPoint* p4 = isEdgeContainsValue(rect->upleft,rect->upright,value);
    if(p4 && (!listout.contains(p4)))
    {
        p4->Add2Rect(rect);
        listout.push_back(p4);
    }

    return listout;
}

//判断边上是否有value的点
St3DPoint* ContourGenerator::isEdgeContainsValue(St3DPoint start, St3DPoint end, int value)
{
    St3DPoint* pnew =  new St3DPoint();
    bool b = false;
    if( value ==start.z  )
    {
        pnew->x = start.x;
        pnew->y = start.y;
        pnew->z = start.z;
        pnew->isVertix = true;
        if(pnew->x == m_xMax || pnew->x == m_xMin ||pnew->y == m_yMax || pnew->y == m_yMin)
            pnew->isBandage = true;
        b = true;
    }
    if( value ==end.z  )
    {
        pnew->x = end.x;
        pnew->y = end.y;
        pnew->z = end.z;
        pnew->isVertix = true;
        if(pnew->x == m_xMax || pnew->x == m_xMin ||pnew->y == m_yMax || pnew->y == m_yMin)
            pnew->isBandage = true;
        b = true;
    }
    if( value > start.z && value < end.z)
    {
        pnew->x = start.x + (value - start.z)/(end.z - start.z) * (end.x - start.x);
        pnew->y = start.y + (value - start.z)/(end.z - start.z) * (end.y - start.y);
        pnew->z = value;
        if(pnew->x == m_xMax || pnew->x == m_xMin ||pnew->y == m_yMax || pnew->y == m_yMin)
            pnew->isBandage = true;
        b = true;
    }

    if(value <start.z && value > end.z)
    {
        pnew->x = end.x + (value - end.z)/(start.z - end.z) * (start.x - end.x);
        pnew->y = end.y + (value - end.z)/(start.z - end.z) * (start.y - end.y);
        pnew->z = value;
        if(pnew->x == m_xMax || pnew->x == m_xMin ||pnew->y == m_yMax || pnew->y == m_yMin)
            pnew->isBandage = true;
        b = true;
    }


    if(b)
    {
        St3DPoint* pold = GetPointByAx(pnew->x,pnew->y);
        if( pold)
        {
            delete pnew; pnew = 0; return pold;
        }else
        {
            QString id = GetPointID(pnew->x,pnew->y);
            m_mapAllContourPoints.insert(id,pnew);
            return pnew;
        }
    }else
    {
        delete pnew; pnew = 0;
        return 0;
    }
}

//根据坐标获取点的ID
QString ContourGenerator::GetPointID(CONTOUR_AX x, CONTOUR_AX y)
{
    return QString("%1").arg(x) + "," + QString("%1").arg(y);
}
//根据坐标获取点的指针
St3DPoint *ContourGenerator::GetPointByAx(CONTOUR_AX x, CONTOUR_AX y)
{
    QString id = GetPointID(x,y);
    QMap<QString,St3DPoint*>::Iterator it = m_mapAllContourPoints.find(id);                               //所有的等值线点
    if( it == m_mapAllContourPoints.end())
        return 0;
    else
        return it.value();
}

//4.计算所有网格中的曲线(或者线段)
void ContourGenerator::GetAllRectLines()
{
    QMap<QString,ContourRect*>::Iterator itAll = m_mapAllRects.begin();                                         //所有的子网格
    for( ; itAll != m_mapAllRects.end(); itAll++)
    {
        ContourRect* rect = itAll.value();
        QMap<int,RectPointsInfo* >::Iterator itValue = rect->mapPoints.begin();
        for( ; itValue != rect->mapPoints.end(); itValue++)
        {
            RectPointsInfo* pp = itValue.value();
            if( pp->isAllLineGeted ) continue;
            else
            {
                //将该网格中的点练成线段
                if( pp->list.size() == 1)
                    continue;
                else if( pp->list.size() == 3)
                {
                    Deal3Points(rect,itValue.key(),pp);
                }else if( pp->list.size() == 4)
                {
                    Deal4Points(rect,itValue.key(),pp);
                }
            }
        }
    }
}


//处理子网格中包含3个等值点的情况:rect为当前计算网格:在获取等值点时,已经进行过重复点的判断,因此,这里的点不会出现重复点
void ContourGenerator::Deal3Points(ContourRect* rect,int value,RectPointsInfo *pp)
{
    St3DPoint* p0 = pp->list.at(0);
    St3DPoint* p1 = pp->list.at(1);
    St3DPoint* p2 = pp->list.at(2);


    bool b0 = isPointCanbeUsed(p0);
    bool b1 = isPointCanbeUsed(p1);
    bool b2 = isPointCanbeUsed(p2);


    //三个点都可用
    if(b0 && b1 && b2)
    {
        //这三个点都没有被使用,则这三个点直接组成一个闭合曲线
        ContourLine line;
        line.eType = e_close;
        line.listPoints.push_back(St3DPoint(p0));
        line.listPoints.push_back(St3DPoint(p1));
        line.listPoints.push_back(St3DPoint(p2));
        pp->isAllLineGeted = true;

        Add2Map(line,value,m_mapAllContourLines);

    }else if( (!b0) && b1 && b2 ) //p0 不可用 p1-p2可用
    {
        RectLine* line = new RectLine();
        line->list.push_back(p1);
        line->list.push_back(p2);

        p1->Add2Line(line);
        p2->Add2Line(line);
        QMap<int,QList<RectLine*> >::Iterator it = m_mapAllRectLines.find(value);                                   //所有子网格中的线段
        if( it == m_mapAllRectLines.end())
        {
            QList<RectLine*> listInsert;
            listInsert.push_back(line);
            m_mapAllRectLines.insert(value,listInsert);
        }else
            it.value().push_back(line);
        pp->isAllLineGeted = true;
    }else if( b0 && (!b1) && b2) //p1不可用  p0-p2可用
    {
        RectLine* line = new RectLine();
        line->list.push_back(p0);
        line->list.push_back(p2);

        p0->Add2Line(line);
        p2->Add2Line(line);
        QMap<int,QList<RectLine*> >::Iterator it = m_mapAllRectLines.find(value);                                   //所有子网格中的线段
        if( it == m_mapAllRectLines.end())
        {
            QList<RectLine*> listInsert;
            listInsert.push_back(line);
            m_mapAllRectLines.insert(value,listInsert);
        }else
            it.value().push_back(line);
        pp->isAllLineGeted = true;
    }else if(b0 && b1 && (!b2)) //p2 不可用 p0-p1可用
    {
        RectLine* line = new RectLine();
        line->list.push_back(p0);
        line->list.push_back(p1);

        p0->Add2Line(line);
        p1->Add2Line(line);
        QMap<int,QList<RectLine*> >::Iterator it = m_mapAllRectLines.find(value);                                   //所有子网格中的线段
        if( it == m_mapAllRectLines.end())
        {
            QList<RectLine*> listInsert;
            listInsert.push_back(line);
            m_mapAllRectLines.insert(value,listInsert);
        }else
            it.value().push_back(line);
        pp->isAllLineGeted = true;
    }else //有两个以上不可用,则直接忽略该网格
    {
        pp->isAllLineGeted = true;
    }


}

//处理子网格中包含4个等值点的情况
void ContourGenerator::Deal4Points(ContourRect* rect,int value,RectPointsInfo *pp)
{
    St3DPoint* p0 = pp->list.at(0);
    St3DPoint* p1 = pp->list.at(1);
    St3DPoint* p2 = pp->list.at(2);
    St3DPoint* p3 = pp->list.at(3);


    //连接的线段为:0-1/2-3

    bool b0 = isPointCanbeUsed(p0);
    bool b1 = isPointCanbeUsed(p1);
    bool b2 = isPointCanbeUsed(p2);
    bool b3 = isPointCanbeUsed(p3);

    if(b0 && b1 && b2 && b3)   //四个点都可用
    {
        //因为在创建网格区域的时候,已经两两连接,因此,再次只需要将这四个点形成一个闭环即可
        //1.将形成的网格线段从集合zhong删除
        RectLine* line1 = p0->listBelong2Line.at(0);
        RectLine* line2 = p2->listBelong2Line.at(0);

        QMap<int,QList<RectLine*> >::Iterator it = m_mapAllRectLines.find(value);                             //所有子网格中的线段
        if( it != m_mapAllRectLines.end())
        {
            QList<RectLine*> lineList = it.value();
            QList<RectLine*>::Iterator itdel = lineList.begin();
            for( int i = 0; i < lineList.size(); i++,itdel++)
            {
                if( lineList.at(i) == line1 || lineList.at(i) == line2 )
                {
                    lineList.erase(itdel);
                    i = 0;
                    itdel = lineList.begin();
                }
            }
        }


        p0->DeleteFromLIne(line1);
        p1->DeleteFromLIne(line1);
        p2->DeleteFromLIne(line2);
        p3->DeleteFromLIne(line2);
        delete line1; line1 = 0;
        delete line2;line2 = 0;
        //形成闭合曲线
        ContourLine line ;
        line.eType = e_close;
        line.listPoints.push_back(St3DPoint(p0));
        line.listPoints.push_back(St3DPoint(p1));
        line.listPoints.push_back(St3DPoint(p2));
        line.listPoints.push_back(St3DPoint(p3));

        Add2Map(line,value,m_mapAllContourLines);
    }else if( (!b0) && b1 && b2 && b3) //p0不可用,其他可用,
    {
        //删除两条线段
        RectLine* line1 = p0->listBelong2Line.at(0);
        RectLine* line2 = p2->listBelong2Line.at(0);

        QMap<int,QList<RectLine*> >::Iterator it = m_mapAllRectLines.find(value);                             //所有子网格中的线段
        if( it != m_mapAllRectLines.end())
        {
            QList<RectLine*> lineList = it.value();
            QList<RectLine*>::Iterator itdel = lineList.begin();
            for( int i = 0; i < lineList.size(); i++,itdel++)
            {
                if( lineList.at(i) == line1 || lineList.at(i) == line2 )
                {
                    lineList.erase(itdel);
                    i = 0;
                    itdel = lineList.begin();
                }
            }
        }
        p0->DeleteFromLIne(line1);
        p1->DeleteFromLIne(line1);
        p2->DeleteFromLIne(line2);
        p3->DeleteFromLIne(line2);
        delete line1; line1 = 0;
        delete line2;line2 = 0;
        //形成一条新的线段
        RectLine* pnew = new RectLine();
        pnew->list.push_back(p0);
        pnew->list.push_back(p1);
        pnew->list.push_back(p2);
        pnew->list.push_back(p3);

        p0->Add2Line(pnew);
        p1->Add2Line(pnew);
        p2->Add2Line(pnew);
        p3->Add2Line(pnew);

        //charu
        it = m_mapAllRectLines.find(value);                             //所有子网格中的线段
        if( it == m_mapAllRectLines.end())
        {
            QList<RectLine*> listinsert;
            listinsert.push_back(pnew);
            m_mapAllRectLines.insert(value,listinsert);
        }else
        {
            it.value().push_back(pnew);
        }


    }else if(  b0 && (!b1) && b2 && b3  ) //p1 不可用,其他可用
    {
        //------------
        //删除两条线段
        RectLine* line1 = p0->listBelong2Line.at(0);
        RectLine* line2 = p2->listBelong2Line.at(0);

        QMap<int,QList<RectLine*> >::Iterator it = m_mapAllRectLines.find(value);                             //所有子网格中的线段
        if( it != m_mapAllRectLines.end())
        {
            QList<RectLine*> lineList = it.value();
            QList<RectLine*>::Iterator itdel = lineList.begin();
            for( int i = 0; i < lineList.size(); i++,itdel++)
            {
                if( lineList.at(i) == line1 || lineList.at(i) == line2 )
                {
                    lineList.erase(itdel);
                    i = 0;
                    itdel = lineList.begin();
                }
            }
        }
        p0->DeleteFromLIne(line1);
        p1->DeleteFromLIne(line1);
        p2->DeleteFromLIne(line2);
        p3->DeleteFromLIne(line2);
        delete line1; line1 = 0;
        delete line2;line2 = 0;
        //形成一条新的线段
        RectLine* pnew = new RectLine();
        pnew->list.push_back(p1);
        pnew->list.push_back(p0);
        pnew->list.push_back(p2);
        pnew->list.push_back(p3);

        p0->Add2Line(pnew);
        p1->Add2Line(pnew);
        p2->Add2Line(pnew);
        p3->Add2Line(pnew);

        //charu
        it = m_mapAllRectLines.find(value);                             //所有子网格中的线段
        if( it == m_mapAllRectLines.end())
        {
            QList<RectLine*> listinsert;
            listinsert.push_back(pnew);
            m_mapAllRectLines.insert(value,listinsert);
        }else
        {
            it.value().push_back(pnew);
        }
        //---------------
    }else if( b0 && b1 && (!b2) && b3) //p2
    {
        //------------
        //删除两条线段
        RectLine* line1 = p0->listBelong2Line.at(0);
        RectLine* line2 = p2->listBelong2Line.at(0);

        QMap<int,QList<RectLine*> >::Iterator it = m_mapAllRectLines.find(value);                             //所有子网格中的线段
        if( it != m_mapAllRectLines.end())
        {
            QList<RectLine*> lineList = it.value();
            QList<RectLine*>::Iterator itdel = lineList.begin();
            for( int i = 0; i < lineList.size(); i++,itdel++)
            {
                if( lineList.at(i) == line1 || lineList.at(i) == line2 )
                {
                    lineList.erase(itdel);
                    i = 0;
                    itdel = lineList.begin();
                }
            }
        }
        p0->DeleteFromLIne(line1);
        p1->DeleteFromLIne(line1);
        p2->DeleteFromLIne(line2);
        p3->DeleteFromLIne(line2);
        delete line1; line1 = 0;
        delete line2;line2 = 0;
        //形成一条新的线段
        RectLine* pnew = new RectLine();
        pnew->list.push_back(p2);
        pnew->list.push_back(p3);
        pnew->list.push_back(p0);
        pnew->list.push_back(p1);

        p0->Add2Line(pnew);
        p1->Add2Line(pnew);
        p2->Add2Line(pnew);
        p3->Add2Line(pnew);

        //charu
        it = m_mapAllRectLines.find(value);                             //所有子网格中的线段
        if( it == m_mapAllRectLines.end())
        {
            QList<RectLine*> listinsert;
            listinsert.push_back(pnew);
            m_mapAllRectLines.insert(value,listinsert);
        }else
        {
            it.value().push_back(pnew);
        }
        //---------------
    }else if( b0 && b1 && b2 && (!b3)) //p3
    {
        //------------
        //删除两条线段
        RectLine* line1 = p0->listBelong2Line.at(0);
        RectLine* line2 = p2->listBelong2Line.at(0);

        QMap<int,QList<RectLine*> >::Iterator it = m_mapAllRectLines.find(value);                             //所有子网格中的线段
        if( it != m_mapAllRectLines.end())
        {
            QList<RectLine*> lineList = it.value();
            QList<RectLine*>::Iterator itdel = lineList.begin();
            for( int i = 0; i < lineList.size(); i++,itdel++)
            {
                if( lineList.at(i) == line1 || lineList.at(i) == line2 )
                {
                    lineList.erase(itdel);
                    i = 0;
                    itdel = lineList.begin();
                }
            }
        }
        p0->DeleteFromLIne(line1);
        p1->DeleteFromLIne(line1);
        p2->DeleteFromLIne(line2);
        p3->DeleteFromLIne(line2);
        delete line1; line1 = 0;
        delete line2;line2 = 0;
        //形成一条新的线段
        RectLine* pnew = new RectLine();
        pnew->list.push_back(p3);
        pnew->list.push_back(p2);
        pnew->list.push_back(p0);
        pnew->list.push_back(p1);

        p0->Add2Line(pnew);
        p1->Add2Line(pnew);
        p2->Add2Line(pnew);
        p3->Add2Line(pnew);

        //charu
        it = m_mapAllRectLines.find(value);                             //所有子网格中的线段
        if( it == m_mapAllRectLines.end())
        {
            QList<RectLine*> listinsert;
            listinsert.push_back(pnew);
            m_mapAllRectLines.insert(value,listinsert);
        }else
        {
            it.value().push_back(pnew);
        }
        //---------------
    }
    if( ( b0 && b1 && (!b2) && (!b3)) || (  (!b0) && (!b1) && b2 && b3    )      ) //原本已经相连的直线
    {
        //do nothing
    }else if(   b0 && (!b1) && b2 && (!b3)           )
    {
        //---------------
        //删除两条线段
        RectLine* line1 = p0->listBelong2Line.at(0);
        RectLine* line2 = p2->listBelong2Line.at(0);

        QMap<int,QList<RectLine*> >::Iterator it = m_mapAllRectLines.find(value);                             //所有子网格中的线段
        if( it != m_mapAllRectLines.end())
        {
            QList<RectLine*> lineList = it.value();
            QList<RectLine*>::Iterator itdel = lineList.begin();
            for( int i = 0; i < lineList.size(); i++,itdel++)
            {
                if( lineList.at(i) == line1 || lineList.at(i) == line2 )
                {
                    lineList.erase(itdel);
                    i = 0;
                    itdel = lineList.begin();
                }
            }
        }
        p0->DeleteFromLIne(line1);
        p1->DeleteFromLIne(line1);
        p2->DeleteFromLIne(line2);
        p3->DeleteFromLIne(line2);
        delete line1; line1 = 0;
        delete line2;line2 = 0;
        //形成一条新的线段
        RectLine* pnew = new RectLine();
        pnew->list.push_back(p1);
        pnew->list.push_back(p0);
        pnew->list.push_back(p2);
        pnew->list.push_back(p3);

        p0->Add2Line(pnew);
        p1->Add2Line(pnew);
        p2->Add2Line(pnew);
        p3->Add2Line(pnew);

        //charu
        it = m_mapAllRectLines.find(value);                             //所有子网格中的线段
        if( it == m_mapAllRectLines.end())
        {
            QList<RectLine*> listinsert;
            listinsert.push_back(pnew);
            m_mapAllRectLines.insert(value,listinsert);
        }else
        {
            it.value().push_back(pnew);
        }
        //-----------------
    }else if(    b0 && (!b1) && (!b2) && b3    )
    {
        //----
        //删除两条线段
        RectLine* line1 = p0->listBelong2Line.at(0);
        RectLine* line2 = p2->listBelong2Line.at(0);

        QMap<int,QList<RectLine*> >::Iterator it = m_mapAllRectLines.find(value);                             //所有子网格中的线段
        if( it != m_mapAllRectLines.end())
        {
            QList<RectLine*> lineList = it.value();
            QList<RectLine*>::Iterator itdel = lineList.begin();
            for( int i = 0; i < lineList.size(); i++,itdel++)
            {
                if( lineList.at(i) == line1 || lineList.at(i) == line2 )
                {
                    lineList.erase(itdel);
                    i = 0;
                    itdel = lineList.begin();
                }
            }
        }
        p0->DeleteFromLIne(line1);
        p1->DeleteFromLIne(line1);
        p2->DeleteFromLIne(line2);
        p3->DeleteFromLIne(line2);
        delete line1; line1 = 0;
        delete line2;line2 = 0;
        //形成一条新的线段
        RectLine* pnew = new RectLine();
        pnew->list.push_back(p1);
        pnew->list.push_back(p0);
        pnew->list.push_back(p3);
        pnew->list.push_back(p2);

        p0->Add2Line(pnew);
        p1->Add2Line(pnew);
        p2->Add2Line(pnew);
        p3->Add2Line(pnew);

        //charu
        it = m_mapAllRectLines.find(value);                             //所有子网格中的线段
        if( it == m_mapAllRectLines.end())
        {
            QList<RectLine*> listinsert;
            listinsert.push_back(pnew);
            m_mapAllRectLines.insert(value,listinsert);
        }else
        {
            it.value().push_back(pnew);
        }
        //------
    }else if(   (!b0) && b1 && b2 && (!b3)    )
    {
        //-----------
        //删除两条线段
        RectLine* line1 = p0->listBelong2Line.at(0);
        RectLine* line2 = p2->listBelong2Line.at(0);

        QMap<int,QList<RectLine*> >::Iterator it = m_mapAllRectLines.find(value);                             //所有子网格中的线段
        if( it != m_mapAllRectLines.end())
        {
            QList<RectLine*> lineList = it.value();
            QList<RectLine*>::Iterator itdel = lineList.begin();
            for( int i = 0; i < lineList.size(); i++,itdel++)
            {
                if( lineList.at(i) == line1 || lineList.at(i) == line2 )
                {
                    lineList.erase(itdel);
                    i = 0;
                    itdel = lineList.begin();
                }
            }
        }
        p0->DeleteFromLIne(line1);
        p1->DeleteFromLIne(line1);
        p2->DeleteFromLIne(line2);
        p3->DeleteFromLIne(line2);
        delete line1; line1 = 0;
        delete line2;line2 = 0;
        //形成一条新的线段
        RectLine* pnew = new RectLine();
        pnew->list.push_back(p0);
        pnew->list.push_back(p1);
        pnew->list.push_back(p2);
        pnew->list.push_back(p3);

        p0->Add2Line(pnew);
        p1->Add2Line(pnew);
        p2->Add2Line(pnew);
        p3->Add2Line(pnew);

        //charu
        it = m_mapAllRectLines.find(value);                             //所有子网格中的线段
        if( it == m_mapAllRectLines.end())
        {
            QList<RectLine*> listinsert;
            listinsert.push_back(pnew);
            m_mapAllRectLines.insert(value,listinsert);
        }else
        {
            it.value().push_back(pnew);
        }
        //-------------
    }else if(    (!b0) && b1 && (!b2) && b3    )
    {
        //-----
        //删除两条线段
        RectLine* line1 = p0->listBelong2Line.at(0);
        RectLine* line2 = p2->listBelong2Line.at(0);

        QMap<int,QList<RectLine*> >::Iterator it = m_mapAllRectLines.find(value);                             //所有子网格中的线段
        if( it != m_mapAllRectLines.end())
        {
            QList<RectLine*> lineList = it.value();
            QList<RectLine*>::Iterator itdel = lineList.begin();
            for( int i = 0; i < lineList.size(); i++,itdel++)
            {
                if( lineList.at(i) == line1 || lineList.at(i) == line2 )
                {
                    lineList.erase(itdel);
                    i = 0;
                    itdel = lineList.begin();
                }
            }
        }
        p0->DeleteFromLIne(line1);
        p1->DeleteFromLIne(line1);
        p2->DeleteFromLIne(line2);
        p3->DeleteFromLIne(line2);
        delete line1; line1 = 0;
        delete line2;line2 = 0;
        //形成一条新的线段
        RectLine* pnew = new RectLine();
        pnew->list.push_back(p0);
        pnew->list.push_back(p1);
        pnew->list.push_back(p3);
        pnew->list.push_back(p2);

        p0->Add2Line(pnew);
        p1->Add2Line(pnew);
        p2->Add2Line(pnew);
        p3->Add2Line(pnew);

        //charu
        it = m_mapAllRectLines.find(value);                             //所有子网格中的线段
        if( it == m_mapAllRectLines.end())
        {
            QList<RectLine*> listinsert;
            listinsert.push_back(pnew);
            m_mapAllRectLines.insert(value,listinsert);
        }else
        {
            it.value().push_back(pnew);
        }

    }else //三/四个点不可用
    {
        // do nothing
    }

    pp->isAllLineGeted = true;






}

//判断点是否能够被使用
bool ContourGenerator::isPointCanbeUsed(St3DPoint *p)
{
    if( (p->isBandage && p->GetLineNumber() < 1) || ( (!p->isBandage) && p->GetLineNumber() < 2) )
        return true;
    else
        return false;
}

//从网格线生成等值线
void ContourGenerator::GetContourLinesByRectLine()
{
    QMap<int,QList<RectLine*> >::Iterator itRectLine = m_mapAllRectLines.begin();                             //所有子网格中的线段
    for( ; itRectLine != m_mapAllRectLines.end(); itRectLine++)
    {
        QList<RectLine*> listLines = itRectLine.value();
        while( true)
        {
            if(listLines.size() == 0) break;
            RectLine* start = listLines.first();
            listLines.pop_front();
            if( start->list.size() <= 1) continue;
            //从剩余线段中查找能与本线段连接的线段
            ContourLine st;
            GetCompleteLine(start,listLines,st);

            //将得到的等值线插入队列
            Add2Map(st,itRectLine.key(),m_mapAllContourLines);

        }
    }
}

//将所有能与本线段连接的线连起来
void ContourGenerator::GetCompleteLine(RectLine *start, QList<RectLine *> &listLines, ContourLine &st)
{
    QList<RectLine *>::Iterator it = listLines.begin();
    for(int i=0 ; i < listLines.size(); )
    {
        St3DPoint* head1 = start->list.first();
        St3DPoint* tail1 = start->list.back();
        St3DPoint* head2 = listLines.at(i)->list.first();
        St3DPoint* tail2 = listLines.at(i)->list.back();
        if(   tail1 == head2  )  //tail -head
        {
            //tail -head
            RectLine* pnew = new RectLine();
            //start 正序插入
            for( int t = 0; t < start->list.size(); t++)
                pnew->list.push_back( start->list.at(t));
            //listLIne.at(i)正序插入
            for(int t = 0; t < listLines.at(i)->list.size(); t++)
                pnew->list.push_back(  listLines.at(i)->list.at(t));

            delete start; start = 0;
            delete listLines.at(i);
            listLines.erase(it);
            i = 0;
            it = listLines.begin();
            start = pnew;

        }else if(  tail1 == tail2 ) //tail - tail
        {
            //tail -tail
            RectLine* pnew = new RectLine();
            //start 正序插入
            for( int t = 0; t < start->list.size(); t++)
                pnew->list.push_back( start->list.at(t));
            //listLIne.at(i)逆序插入
            for(int t = listLines.at(i)->list.size() - 1; t >= 0; t--)
                pnew->list.push_back(  listLines.at(i)->list.at(t));

            delete start; start = 0;
            delete listLines.at(i);
            listLines.erase(it);
            i = 0;
            it = listLines.begin();
            start = pnew;
        }else if(  head1 == head2  ) //head -head
        {
            //head - head
            RectLine* pnew = new RectLine();
            //start 逆序插入
            for( int t =  start->list.size() -1; t >= 0; t--)
                pnew->list.push_back( start->list.at(t));
            //listLIne.at(i)正序插入
            for(int t = 0; t < listLines.at(i)->list.size(); t++ )
                pnew->list.push_back(  listLines.at(i)->list.at(t));

            delete start; start = 0;
            delete listLines.at(i);
            listLines.erase(it);
            i = 0;
            it = listLines.begin();
            start = pnew;
        }else if(  head1 == tail2   ) // head -tail
        {
            //head - tail
            RectLine* pnew = new RectLine();
            //listLIne.at(i)正序插入
            for(int t = 0; t < listLines.at(i)->list.size(); t++ )
                pnew->list.push_back(  listLines.at(i)->list.at(t));

            //start 正序插入
            for( int t = 0;  t <  start->list.size(); t++ )
                pnew->list.push_back( start->list.at(t));


            delete start; start = 0;
            delete listLines.at(i);
            listLines.erase(it);
            i = 0;
            it = listLines.begin();
            start = pnew;
        } else
        {
            i++;it++;
        }
    } //for end


    //将RectLine转换为ContourLine
    for( int x = 0; x < start->list.size(); x++)
    {
        st.listPoints.push_back( St3DPoint(  start->list.at(x))    );
    }


    if(  start->list.first() == start->list.back()   )
        st.eType = e_close;
    else if( start->list.first()->isBandage && start->list.back()->isBandage)
        st.eType = e_open;
    else
        st.eType = e_unfinished;

    delete start; start = 0;

}

//获取两点间的距离
CONTOUR_AX ContourGenerator::Distance(St3DPoint s1, St3DPoint s2)
{
    return sqrt( (s1.x - s2.x)*(s1.x - s2.x) + (s1.y - s2.y)*(s1.y - s2.y)  );
}

//判断两个点是否是同一个点
bool ContourGenerator::equals(St3DPoint t1, St3DPoint t2)
{
    if( t1.x == t2.x && t1.y == t2.y)
        return true;
    else
        return false;
}

//插入队列
void ContourGenerator::Add2Map(ContourLine line, int value, QMap<int, QList<ContourLine> > &mapout)
{
    QMap<int,QList<ContourLine> >::Iterator itInsert = mapout.find(value);
    if( itInsert == mapout.end())
    {
        QList<ContourLine> listInsert;
        listInsert.push_back(line);
        mapout.insert(value,listInsert);
    }else
        itInsert.value().push_back(line);
}
//根据基点和间隔获取等值线  20191018新增
QList<int> ContourGenerator::GetNewLineValues(int space)
{
    QList<int> listout;
    int d = m_zMin /space;
    int start = d * space;
    if(start < m_zMin)
        start += space;

    while(start <= m_zMax)
    {
        listout.push_back(start);
        start += space;
    }
    return listout;
}








  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值