本资源提供了通过输入标准网格点数据计算等值线的接口,接口通过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;
}