|
|
#include "MLPline.h"
|
|
|
#include "MLPoint.h"
|
|
|
#include "MLFuncom.h"
|
|
|
#include <QPolygonF>
|
|
|
#include <QTextStream>
|
|
|
|
|
|
MLPline::MLPline(void)
|
|
|
{
|
|
|
memset(m_name, 0, 64);
|
|
|
m_dLength = 0;
|
|
|
m_dArea = 0;
|
|
|
}
|
|
|
|
|
|
MLPline::MLPline(const QPolygonF& polygonf)
|
|
|
:MLPline()
|
|
|
{
|
|
|
int num = polygonf.count();
|
|
|
if (num > 1)
|
|
|
{
|
|
|
m_nodeAry.resize(num);
|
|
|
for (int i=0;i<num;i++)
|
|
|
m_nodeAry[i] = MLPlNode(polygonf[i].x(), polygonf[i].y());
|
|
|
}
|
|
|
}
|
|
|
|
|
|
MLPline::MLPline(const QVector<MLPlNode>& nodeAry)
|
|
|
: MLPline()
|
|
|
{
|
|
|
if (nodeAry.count() >1)
|
|
|
{
|
|
|
m_nodeAry.resize(nodeAry.count());
|
|
|
memcpy(m_nodeAry.data(), nodeAry.data(), sizeof(MLPlNode) * nodeAry.count());
|
|
|
}
|
|
|
}
|
|
|
|
|
|
MLPline::~MLPline(void)
|
|
|
{
|
|
|
|
|
|
}
|
|
|
|
|
|
const char* MLPline::getName() const
|
|
|
{
|
|
|
return m_name;
|
|
|
}
|
|
|
|
|
|
void MLPline::setName(const char* name )
|
|
|
{
|
|
|
memcpy(m_name, name, strlen(name));
|
|
|
}
|
|
|
|
|
|
QVector<MLPlNode>& MLPline::getNodeAry()
|
|
|
{
|
|
|
return m_nodeAry;
|
|
|
}
|
|
|
|
|
|
void MLPline::setNodeAry(const QVector<MLPlNode>& nodeAry )
|
|
|
{
|
|
|
m_nodeAry = nodeAry;
|
|
|
}
|
|
|
|
|
|
void MLPline::setNodeAry(const QPolygonF& polygon)
|
|
|
{
|
|
|
m_nodeAry.clear();
|
|
|
m_nodeAry.resize(polygon.count());
|
|
|
for (int i=0;i<polygon.count();i++)
|
|
|
{
|
|
|
m_nodeAry[i] = MLPlNode(polygon[i].x(), polygon[i].y());
|
|
|
}
|
|
|
}
|
|
|
|
|
|
int MLPline::getCount() const
|
|
|
{
|
|
|
return m_nodeAry.count();
|
|
|
}
|
|
|
|
|
|
bool MLPline::isEmpty()
|
|
|
{
|
|
|
if (m_nodeAry.count() >1)
|
|
|
return false;
|
|
|
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
bool MLPline::isClose(double dis /*= 20.0*/)
|
|
|
{
|
|
|
if (getCount() <= 0)
|
|
|
return false;
|
|
|
|
|
|
if (getHeadTailDistance() > dis)
|
|
|
return false;
|
|
|
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
void MLPline::addHeadPt( const MLPlNode& node )
|
|
|
{
|
|
|
m_nodeAry.push_front(node);
|
|
|
}
|
|
|
|
|
|
void MLPline::addHeadPt( const MLPoint& point )
|
|
|
{
|
|
|
m_nodeAry.push_front(MLPlNode(point));
|
|
|
}
|
|
|
|
|
|
void MLPline::addHeadPt( double x, double y, double z/*=0*/ )
|
|
|
{
|
|
|
m_nodeAry.push_front(MLPlNode(x, y, z));
|
|
|
}
|
|
|
|
|
|
void MLPline::addHeadPt( const MLPline& pline )
|
|
|
{
|
|
|
for (int i=0;i<pline.getCount();i++)
|
|
|
{
|
|
|
m_nodeAry.push_front(pline[i]);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
void MLPline::addHeadPtRev( const MLPline& pline )
|
|
|
{
|
|
|
for (int i=pline.getCount()-1; i>=0; i--)
|
|
|
{
|
|
|
m_nodeAry.push_front(pline[i]);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
void MLPline::addHeadPtRev( const MLPointAry& pointAry )
|
|
|
{
|
|
|
for (int i=pointAry.count()-1; i>=0; i--)
|
|
|
{
|
|
|
m_nodeAry.push_front(pointAry[i]);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
void MLPline::addTailPt( const MLPlNode& node )
|
|
|
{
|
|
|
m_nodeAry.push_back(node);
|
|
|
}
|
|
|
|
|
|
void MLPline::addTailPt( const MLPoint& point )
|
|
|
{
|
|
|
m_nodeAry.push_back(MLPlNode(point));
|
|
|
}
|
|
|
|
|
|
void MLPline::addTailPt( double x,double y,double z/*=0*/ )
|
|
|
{
|
|
|
m_nodeAry.push_back(MLPlNode(x, y, z));
|
|
|
}
|
|
|
|
|
|
void MLPline::addTailPt( const MLPline& pline )
|
|
|
{
|
|
|
for (int i=0;i<pline.getCount();i++)
|
|
|
{
|
|
|
m_nodeAry.push_back(pline[i]);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
void MLPline::addTailPt(const QPoint& point )
|
|
|
{
|
|
|
m_nodeAry.push_back(MLPlNode(point));
|
|
|
}
|
|
|
|
|
|
void MLPline::addTailPt(const QPointF& point )
|
|
|
{
|
|
|
m_nodeAry.push_back(MLPlNode(point));
|
|
|
}
|
|
|
|
|
|
void MLPline::addTailPtRev( const MLPline& pline )
|
|
|
{
|
|
|
for (int i=pline.getCount()-1; i>=0; i--)
|
|
|
{
|
|
|
m_nodeAry.push_back(pline[i]);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
void MLPline::addTailPtRev( const MLPointAry& pointAry )
|
|
|
{
|
|
|
for (int i=pointAry.count()-1; i>=0; i--)
|
|
|
{
|
|
|
m_nodeAry.push_back(pointAry[i]);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
const MLPlNode& MLPline::getHeadPt() const
|
|
|
{
|
|
|
return m_nodeAry.front();
|
|
|
}
|
|
|
|
|
|
MLPlNode& MLPline::getHeadPt()
|
|
|
{
|
|
|
return m_nodeAry.front();
|
|
|
}
|
|
|
|
|
|
const MLPlNode& MLPline::getTailPt() const
|
|
|
{
|
|
|
return m_nodeAry.back();
|
|
|
}
|
|
|
|
|
|
MLPlNode& MLPline::getTailPt()
|
|
|
{
|
|
|
return m_nodeAry.back();
|
|
|
}
|
|
|
|
|
|
const MLPlNode& MLPline::getAtPt( int index ) const
|
|
|
{
|
|
|
return m_nodeAry.at(index);
|
|
|
}
|
|
|
|
|
|
void MLPline::setAtPt( int index, const MLPlNode& node )
|
|
|
{
|
|
|
m_nodeAry[index] = node;
|
|
|
}
|
|
|
|
|
|
void MLPline::insertAfter( int index, const MLPlNode& node )
|
|
|
{
|
|
|
int nCountPt = getCount();
|
|
|
if(index > nCountPt || index <0)
|
|
|
return ;
|
|
|
|
|
|
return m_nodeAry.insert(index+1, node);
|
|
|
}
|
|
|
|
|
|
void MLPline::insertBefore( int index, const MLPlNode& node )
|
|
|
{
|
|
|
int nCountPt = getCount();
|
|
|
if(index > nCountPt || index <0)
|
|
|
return ;
|
|
|
|
|
|
return m_nodeAry.insert(index, node);
|
|
|
}
|
|
|
|
|
|
void MLPline::removeHead()
|
|
|
{
|
|
|
m_nodeAry.pop_front();
|
|
|
}
|
|
|
|
|
|
void MLPline::removeTail()
|
|
|
{
|
|
|
m_nodeAry.pop_back();
|
|
|
}
|
|
|
|
|
|
void MLPline::removeAt( int index )
|
|
|
{
|
|
|
m_nodeAry.remove(index);
|
|
|
}
|
|
|
|
|
|
void MLPline::removeAll()
|
|
|
{
|
|
|
m_nodeAry.clear();
|
|
|
}
|
|
|
|
|
|
// <20>Ƴ<EFBFBD><C6B3><EFBFBD><EFBFBD><EFBFBD>
|
|
|
void MLPline::removeRt(const MLRect& dRect)
|
|
|
{
|
|
|
int count = getCount();
|
|
|
QVector<MLPlNode> nodeAry;
|
|
|
nodeAry.resize(count);
|
|
|
int j=0;
|
|
|
/*for (int i=0;i<count;i++)
|
|
|
{
|
|
|
if (dRect.contains(m_nodeAry[i].x, m_nodeAry[i].y))
|
|
|
continue;
|
|
|
|
|
|
nodeAry[j] = m_nodeAry[i];
|
|
|
j++;
|
|
|
}
|
|
|
|
|
|
if (j >1)
|
|
|
{
|
|
|
nodeAry.resize(j);
|
|
|
m_nodeAry.resize(j);
|
|
|
memcpy(m_nodeAry.data(), nodeAry.data(), sizeof(MLPlNode) * j);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
m_nodeAry.clear();
|
|
|
}*/
|
|
|
}
|
|
|
|
|
|
void MLPline::removeAtFrAngle(double angle)
|
|
|
{
|
|
|
int count = getCount();
|
|
|
|
|
|
if (count <= 0)
|
|
|
return;
|
|
|
|
|
|
QVector<MLPlNode> nodeAry;
|
|
|
nodeAry.resize(count);
|
|
|
int j = 0;
|
|
|
for (int i = 0; i < count; i++)
|
|
|
{
|
|
|
if (m_nodeAry[i].a <= angle)
|
|
|
continue;
|
|
|
|
|
|
nodeAry[j] = m_nodeAry[i];
|
|
|
j++;
|
|
|
}
|
|
|
|
|
|
if (j > 1)
|
|
|
{
|
|
|
nodeAry.resize(j);
|
|
|
m_nodeAry.resize(j);
|
|
|
memcpy(m_nodeAry.data(), nodeAry.data(), sizeof(MLPlNode) * j);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
m_nodeAry.clear();
|
|
|
}
|
|
|
}
|
|
|
|
|
|
void MLPline::removeAtFrAngle2(double angle)
|
|
|
{
|
|
|
double aa = angle * PI / 180;
|
|
|
removeAtFrAngle(aa);
|
|
|
}
|
|
|
|
|
|
|
|
|
void MLPline::resize( int count )
|
|
|
{
|
|
|
m_nodeAry.resize(count);
|
|
|
}
|
|
|
|
|
|
// <20><><EFBFBD>߽ڵ㷴<DAB5><E3B7B4>
|
|
|
void MLPline::reversePt()
|
|
|
{
|
|
|
for (int i = 0; i < getCount()/2; i++)
|
|
|
{
|
|
|
MLPlNode tmp = m_nodeAry[i];
|
|
|
m_nodeAry[i] = m_nodeAry[getCount() - 1 - i];
|
|
|
m_nodeAry[getCount() - 1 - i] = tmp;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
MLPlNode& MLPline::operator[]( int index )
|
|
|
{
|
|
|
return m_nodeAry[index];
|
|
|
}
|
|
|
|
|
|
const MLPlNode& MLPline::operator[]( int index ) const
|
|
|
{
|
|
|
return m_nodeAry[index];
|
|
|
}
|
|
|
|
|
|
const MLPlNode* MLPline::getData() const
|
|
|
{
|
|
|
return m_nodeAry.data();
|
|
|
}
|
|
|
|
|
|
MLPline* MLPline::clone()
|
|
|
{
|
|
|
MLPline* pPline = new MLPline;
|
|
|
pPline->setName(getName());
|
|
|
pPline->copyPt(getNodeAry());
|
|
|
|
|
|
return pPline;
|
|
|
}
|
|
|
|
|
|
void MLPline::copy(const MLPline& pline)
|
|
|
{
|
|
|
setName(pline.getName());
|
|
|
copyPt(pline);
|
|
|
calculateLength();
|
|
|
}
|
|
|
|
|
|
void MLPline::copyPt( const QVector<MLPlNode>& noteAry )
|
|
|
{
|
|
|
//m_nodeAry.clear();
|
|
|
// //m_nodeAry = nodeAry;
|
|
|
m_nodeAry.resize(noteAry.count());
|
|
|
memcpy(m_nodeAry.data(), noteAry.data(), sizeof(MLPlNode) * noteAry.count());
|
|
|
}
|
|
|
|
|
|
void MLPline::copyPt( const MLPline& pline )
|
|
|
{
|
|
|
m_nodeAry.clear();
|
|
|
memcpy(m_name, pline.getName(), 64);
|
|
|
m_nodeAry.resize(pline.getCount());
|
|
|
memcpy(m_nodeAry.data(), pline.getData(), sizeof(MLPlNode) * pline.getCount());
|
|
|
}
|
|
|
|
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͷ<EFBFBD><CDB7><EFBFBD>ӱպϵ<D5BA>
|
|
|
void MLPline::closeHeadPt()
|
|
|
{
|
|
|
double dis = GetDistance(m_nodeAry.front(), m_nodeAry.last());
|
|
|
if (dis > 2.0)
|
|
|
{
|
|
|
m_nodeAry.push_front(m_nodeAry.last());
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>β<EFBFBD><CEB2><EFBFBD>ӱպϵ<D5BA>
|
|
|
void MLPline::closeTailPt()
|
|
|
{
|
|
|
double dis = GetDistance(m_nodeAry.front(), m_nodeAry.last());
|
|
|
if (dis > 2.0)
|
|
|
{
|
|
|
m_nodeAry.push_back(m_nodeAry.front());
|
|
|
}
|
|
|
}
|
|
|
|
|
|
MLPointAry MLPline::getPointAry( int beginIndex ,int endIndex )
|
|
|
{
|
|
|
MLPointAry pointAry;
|
|
|
|
|
|
for (int i=beginIndex; i<=endIndex; i++)
|
|
|
{
|
|
|
pointAry.append(m_nodeAry[i]);
|
|
|
}
|
|
|
|
|
|
return pointAry;
|
|
|
}
|
|
|
|
|
|
MLPline MLPline::getPline( int beginIndex ,int endIndex )
|
|
|
{
|
|
|
MLPline pline;
|
|
|
|
|
|
for (int i=beginIndex; i<=endIndex; i++)
|
|
|
{
|
|
|
pline.addTailPt(m_nodeAry[i]);
|
|
|
}
|
|
|
|
|
|
return pline;
|
|
|
}
|
|
|
|
|
|
MLRect MLPline::calculateBox()
|
|
|
{
|
|
|
if (!m_box.isEmpty())
|
|
|
{
|
|
|
return m_box;
|
|
|
}
|
|
|
|
|
|
MLRect rect;
|
|
|
|
|
|
if (getCount() >0)
|
|
|
{
|
|
|
MLPlNode dPoint = m_nodeAry.front();
|
|
|
|
|
|
rect.left = dPoint.x;
|
|
|
rect.right = dPoint.x;
|
|
|
rect.top = dPoint.y;
|
|
|
rect.bottom=dPoint.y;
|
|
|
|
|
|
for (int i=1;i<m_nodeAry.size();i++)
|
|
|
{
|
|
|
dPoint = m_nodeAry[i];
|
|
|
if(rect.left > dPoint.x)
|
|
|
rect.left = dPoint.x;
|
|
|
if(rect.right < dPoint.x)
|
|
|
rect.right = dPoint.x;
|
|
|
|
|
|
if(rect.top < dPoint.y)
|
|
|
rect.top = dPoint.y;
|
|
|
if(rect.bottom > dPoint.y)
|
|
|
rect.bottom = dPoint.y;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
m_box = rect;
|
|
|
return rect;
|
|
|
}
|
|
|
void MLPline::resetBox()
|
|
|
{
|
|
|
m_box.setEmpty();
|
|
|
}
|
|
|
MLRect MLPline::getBox()
|
|
|
{
|
|
|
return m_box;
|
|
|
}
|
|
|
|
|
|
double MLPline::getLength( int index )
|
|
|
{
|
|
|
if (index ==0)
|
|
|
return 0.0;
|
|
|
|
|
|
if (m_nodeAry[index].l <=0)
|
|
|
{
|
|
|
calculateLength();
|
|
|
}
|
|
|
return m_nodeAry[index].l;
|
|
|
}
|
|
|
|
|
|
double MLPline::getLength()
|
|
|
{
|
|
|
if (m_dLength <=0)
|
|
|
{
|
|
|
calculateLength();
|
|
|
}
|
|
|
return m_dLength;
|
|
|
}
|
|
|
|
|
|
void MLPline::calculateLength()
|
|
|
{
|
|
|
if (getCount() <=0)
|
|
|
{
|
|
|
m_dLength = 0;
|
|
|
return ;
|
|
|
}
|
|
|
|
|
|
(*this)[0].l = 0.0;
|
|
|
for(int i=1;i<getCount();i++)
|
|
|
{
|
|
|
(*this)[i].l = (*this)[i-1].l + sqrt(pow((getAtPt(i).x - getAtPt(i-1).x),2) + pow((getAtPt(i).y - getAtPt(i-1).y),2));
|
|
|
}
|
|
|
if (getCount() > 0)
|
|
|
{
|
|
|
m_dLength = m_nodeAry[getCount()-1].l;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
void MLPline::calculateArea()
|
|
|
{
|
|
|
double area = 0.;
|
|
|
int i,j;
|
|
|
int n = m_nodeAry.count();
|
|
|
MLPlNode dPt1,dPt2;
|
|
|
|
|
|
double ai = 0.;
|
|
|
for(i=n-1,j=0; j<n; i=j,j++)
|
|
|
{
|
|
|
dPt1 = m_nodeAry[i];
|
|
|
dPt2 = m_nodeAry[j];
|
|
|
|
|
|
ai = dPt1.x * dPt2.y - dPt2.x * dPt1.y;
|
|
|
area += ai;
|
|
|
}
|
|
|
m_dArea = fabs(area / 2.0);
|
|
|
}
|
|
|
|
|
|
double MLPline::getArea()
|
|
|
{
|
|
|
if (m_dArea<=0)
|
|
|
{
|
|
|
calculateArea();
|
|
|
}
|
|
|
return m_dArea;
|
|
|
}
|
|
|
|
|
|
double angle(const MLPlNode& p0, const MLPlNode& p1)
|
|
|
{
|
|
|
double dx = p1.x - p0.x;
|
|
|
double dy = p1.y - p0.y;
|
|
|
return atan2(dy, dx);
|
|
|
}
|
|
|
|
|
|
static double diff(double ang1, double ang2)
|
|
|
{
|
|
|
double delAngle;
|
|
|
|
|
|
if (ang1 < ang2) {
|
|
|
delAngle = ang2 - ang1;
|
|
|
}
|
|
|
else {
|
|
|
delAngle = ang1 - ang2;
|
|
|
}
|
|
|
|
|
|
if (delAngle > PI) {
|
|
|
delAngle = (2 * PI) - delAngle;
|
|
|
}
|
|
|
|
|
|
return delAngle;
|
|
|
}
|
|
|
|
|
|
static double angleBetween(const MLPlNode& tip1, const MLPlNode& tail, const MLPlNode& tip2)
|
|
|
{
|
|
|
double a1 = angle(tail, tip1);
|
|
|
double a2 = angle(tail, tip2);
|
|
|
|
|
|
return diff(a1, a2);
|
|
|
}
|
|
|
|
|
|
void MLPline::calculateAngle()
|
|
|
{
|
|
|
int nCount = m_nodeAry.count();
|
|
|
if (nCount <= 0)
|
|
|
return;
|
|
|
|
|
|
m_nodeAry[0].a = 2*PI;
|
|
|
m_nodeAry[nCount-1].a = 2*PI;
|
|
|
|
|
|
MLPlNode dp1, dp2, dp3;
|
|
|
for (int i = 1; i < nCount - 1; i++)
|
|
|
{
|
|
|
dp1 = m_nodeAry[i - 1];
|
|
|
dp2 = m_nodeAry[i];
|
|
|
dp3 = m_nodeAry[i + 1];
|
|
|
|
|
|
m_nodeAry[i].a = angleBetween(dp1, dp2, dp3);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD>ߵ<EFBFBD><DFB5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
int MLPline::findIndex(const MLPoint& point, double delt/*=0.5*/)
|
|
|
{
|
|
|
int index = -1;
|
|
|
int nCount = m_nodeAry.count();
|
|
|
for (int i=0;i<nCount;i++)
|
|
|
{
|
|
|
MLPlNode dp1 = m_nodeAry[i];
|
|
|
if (fabs(point.x-dp1.x) < delt && fabs(point.y-dp1.y) < delt)
|
|
|
{
|
|
|
return i;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
return index;
|
|
|
}
|
|
|
|
|
|
// <20><><EFBFBD><EFBFBD>ȥ<EFBFBD><C8A5><EFBFBD><EFBFBD>
|
|
|
void MLPline::redundant(double error/*=1.0*/)
|
|
|
{
|
|
|
int count = getCount();
|
|
|
if (count <4)
|
|
|
return ;
|
|
|
|
|
|
double* x = new double[count];
|
|
|
double* y = new double[count];
|
|
|
int* mark = new int[count];
|
|
|
|
|
|
for (int i=0;i<count;i++)
|
|
|
{
|
|
|
x[i] = m_nodeAry[i].x;
|
|
|
y[i] = m_nodeAry[i].y;
|
|
|
mark[i] = i;
|
|
|
}
|
|
|
|
|
|
MLDPlineRedundant pineRedundant(x, y, count, mark);
|
|
|
pineRedundant.execute(error);
|
|
|
|
|
|
int mark_num = pineRedundant.getMarkNum();
|
|
|
|
|
|
m_nodeAry.resize(mark_num);
|
|
|
|
|
|
for(int i=0;i<mark_num;++i)
|
|
|
{
|
|
|
MLPlNode dPt;
|
|
|
dPt.x = x[mark[i]];
|
|
|
dPt.y = y[mark[i]];
|
|
|
m_nodeAry[i] = dPt;
|
|
|
}
|
|
|
calculateLength();
|
|
|
|
|
|
delete [] x;
|
|
|
delete [] y;
|
|
|
}
|
|
|
|
|
|
bool MLPline::contains( double x1, double y1 )
|
|
|
{
|
|
|
int i, j, c = 0;
|
|
|
MLPlNode dp1,dp2;
|
|
|
|
|
|
int npol = (int)m_nodeAry.count();
|
|
|
for (i = 0, j = npol-1; i < npol; j = i++)
|
|
|
{
|
|
|
dp1 = m_nodeAry[i];
|
|
|
dp2 = m_nodeAry[j];
|
|
|
|
|
|
if ((((dp1.y <=y1) && (y1 < dp2.y)) ||
|
|
|
((dp2.y <= y1) && (y1 < dp1.y))) &&
|
|
|
(x1 < (dp2.x - dp1.x) * (y1 - dp1.y) / (dp2.y - dp1.y) + dp1.x))
|
|
|
{
|
|
|
c = !c;
|
|
|
}
|
|
|
}
|
|
|
if (c != 0)
|
|
|
{
|
|
|
return true;
|
|
|
}
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
bool MLPline::contains( const MLPoint& point )
|
|
|
{
|
|
|
return contains(point.x, point.y);
|
|
|
}
|
|
|
|
|
|
bool MLPline::contains( const MLPlNode& node )
|
|
|
{
|
|
|
return contains(node.x, node.y);
|
|
|
}
|
|
|
|
|
|
bool MLPline::containsWhole(const MLPline& other)
|
|
|
{
|
|
|
bool con = false;
|
|
|
for (int i=0; i<other.getCount();i++)
|
|
|
{
|
|
|
if (!contains(other.getAtPt(i)))
|
|
|
{
|
|
|
return false;
|
|
|
}
|
|
|
}
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
bool MLPline::read(const QString& Path )
|
|
|
{
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
bool MLPline::read( QFile& fr )
|
|
|
{
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
void MLPline::read( QDataStream &in )
|
|
|
{
|
|
|
int nCount = 0;
|
|
|
int ver;
|
|
|
in >> ver;
|
|
|
|
|
|
in .readRawData(m_name, 64) ;
|
|
|
in >> nCount;
|
|
|
if (nCount < 2)
|
|
|
{
|
|
|
m_nodeAry.clear();
|
|
|
return ;
|
|
|
}
|
|
|
|
|
|
m_nodeAry.resize(nCount);
|
|
|
in.readRawData((char*)m_nodeAry.data(), sizeof(MLPlNode)*nCount);
|
|
|
}
|
|
|
|
|
|
void MLPline::write(const QString& Path )
|
|
|
{
|
|
|
QFile file(Path);
|
|
|
if (!file.open(QIODevice::WriteOnly | QIODevice::Text))
|
|
|
{
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
QTextStream stream(&file);
|
|
|
write(stream);
|
|
|
file.close();
|
|
|
}
|
|
|
|
|
|
void MLPline::write( QFile& fw )
|
|
|
{
|
|
|
QTextStream stream(&fw);
|
|
|
write(stream);
|
|
|
}
|
|
|
|
|
|
void MLPline::write( QDataStream &out )
|
|
|
{
|
|
|
int nCount = getCount();
|
|
|
|
|
|
out << 1;
|
|
|
out.writeRawData(m_name, 64);
|
|
|
out << nCount;
|
|
|
if(nCount <2)
|
|
|
return;
|
|
|
|
|
|
out.writeRawData((char*)m_nodeAry.data(), sizeof(MLPlNode)*nCount);
|
|
|
}
|
|
|
|
|
|
void MLPline::write(QTextStream& stream)
|
|
|
{
|
|
|
if (m_nodeAry.isEmpty())
|
|
|
return;
|
|
|
|
|
|
QString name(m_name);
|
|
|
name = name.simplified();
|
|
|
if (name.isEmpty())
|
|
|
stream << "pline\n";
|
|
|
else
|
|
|
stream << "pline." + name + "\n";
|
|
|
|
|
|
for (int i = 0; i < m_nodeAry.count(); i++)
|
|
|
{
|
|
|
QString str = QString("%1,%2\n").arg(m_nodeAry[i].x, 0, 'f', 3).arg(m_nodeAry[i].y, 0, 'f', 3);
|
|
|
stream << str;
|
|
|
}
|
|
|
stream << "\n";
|
|
|
}
|
|
|
|
|
|
void MLPline::toXyData( double*& pX, double*& pY, int& count )
|
|
|
{
|
|
|
count = getCount();
|
|
|
if (count <=0)
|
|
|
{
|
|
|
pX = nullptr;
|
|
|
pY = nullptr;
|
|
|
}
|
|
|
|
|
|
pX = new double[count];
|
|
|
pY = new double[count];
|
|
|
|
|
|
for (int i=0;i<count;i++)
|
|
|
{
|
|
|
pX[i] = getAtPt(i).x;
|
|
|
pY[i] = getAtPt(i).y;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// תΪQt <20><>ʽ
|
|
|
void MLPline::toQPolygonF(QPolygonF& polygon)
|
|
|
{
|
|
|
polygon.clear();
|
|
|
polygon.resize(m_nodeAry.count());
|
|
|
for (int i=0;i<polygon.size();i++)
|
|
|
{
|
|
|
polygon[i] = QPointF(m_nodeAry[i].x, m_nodeAry[i].y);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
QPolygonF MLPline::toQPolygonF()const
|
|
|
{
|
|
|
QPolygonF polygon;
|
|
|
polygon.resize(m_nodeAry.count());
|
|
|
for (int i = 0; i < polygon.size(); i++)
|
|
|
{
|
|
|
polygon[i] = QPointF(m_nodeAry[i].x, m_nodeAry[i].y);
|
|
|
}
|
|
|
return polygon;
|
|
|
}
|
|
|
|
|
|
void MLPline::sampling( MLPline &curve, double step )
|
|
|
{
|
|
|
double l0,lmax;
|
|
|
int i;
|
|
|
|
|
|
int nCount = getCount();
|
|
|
if(nCount<2) return ;
|
|
|
|
|
|
lmax=getTailPt().l;
|
|
|
l0 = getHeadPt().l;
|
|
|
if (Equ(lmax ,0.0, 5))
|
|
|
{
|
|
|
calculateLength();
|
|
|
lmax = getTailPt().l;
|
|
|
}
|
|
|
|
|
|
curve.setName(m_name);
|
|
|
|
|
|
if(!curve.m_nodeAry.isEmpty())
|
|
|
curve.m_nodeAry.clear();
|
|
|
|
|
|
MLPlNode point;
|
|
|
while(l0<=lmax)
|
|
|
{
|
|
|
i = bs(l0,(*this));
|
|
|
point.x = cz(l0,i,(*this),3,0);
|
|
|
point.y = cz(l0,i,(*this),3,1);
|
|
|
curve.addTailPt(point);
|
|
|
l0+=step;
|
|
|
}
|
|
|
curve.addTailPt(getTailPt());
|
|
|
}
|
|
|
|
|
|
double MLPline::getHeadTailDistance()const
|
|
|
{
|
|
|
double dis = 0.0;
|
|
|
int nCount = (int)m_nodeAry.count();
|
|
|
if(nCount <2) return dis;
|
|
|
|
|
|
dis = getDistance(getHeadPt(), getTailPt());
|
|
|
return dis;
|
|
|
}
|
|
|
|
|
|
double MLPline::getDistance( const MLPlNode& node1, const MLPlNode& node2 )const
|
|
|
{
|
|
|
if (Equ(node1.x, node2.x) && Equ(node1.y, node2.y))
|
|
|
return 0.0;
|
|
|
|
|
|
return sqrt(pow(node2.x - node1.x, 2) + pow(node2.y - node1.y, 2));
|
|
|
}
|
|
|
|
|
|
double MLPline::getDistance( int index1, int index2 )
|
|
|
{
|
|
|
double dis = 0.0;
|
|
|
|
|
|
if (index1 == index2)
|
|
|
return 0.0;
|
|
|
|
|
|
if (index1<0 || index1 > getCount())
|
|
|
return 0.0;
|
|
|
|
|
|
if (index2<0 || index2 > getCount())
|
|
|
return 0.0;
|
|
|
|
|
|
int length1 = getAtPt(index1).l;
|
|
|
int length2 = getAtPt(index2).l;
|
|
|
|
|
|
if (length1 < length2)
|
|
|
dis = length2 - length1;
|
|
|
if (length1 > length2)
|
|
|
dis = length1 - length2;
|
|
|
|
|
|
return dis;
|
|
|
}
|
|
|
|
|
|
double MLPline::getVerticalDistance( const MLPlNode& dPoint1, const MLPlNode& dPoint2 )
|
|
|
{
|
|
|
int index1 = -1;
|
|
|
int index2 = -1;
|
|
|
MLPlNode dptDest1, dptDest2;
|
|
|
double dis = 0;
|
|
|
|
|
|
//double dis11 = getNearest(dPoint1, index1, dptDest1);
|
|
|
//double dis22 = getNearest(dPoint2, index2, dptDest2);
|
|
|
|
|
|
if (index1 < index2)
|
|
|
{
|
|
|
double dis0 = getDistance(index1, index2);
|
|
|
double dis1 = getDistance(dptDest1, getAtPt(index1));
|
|
|
double dis2 = getDistance(dptDest2, getAtPt(index2));
|
|
|
|
|
|
dis = dis0 + dis1 - dis2 ;
|
|
|
}
|
|
|
else if (index1 > index2)
|
|
|
{
|
|
|
double dis0 = getDistance(index2, index1);
|
|
|
double dis1 = getDistance(dptDest1, getAtPt(index1));
|
|
|
double dis2 = getDistance(dptDest2, getAtPt(index2));
|
|
|
dis = dis0 - dis1 + dis2;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
dis = getDistance(dptDest1, dptDest2);
|
|
|
}
|
|
|
|
|
|
return dis;
|
|
|
}
|
|
|
|
|
|
double MLPline::getReverseDistance( const MLPlNode& dPoint1, const MLPlNode& dPoint2 )
|
|
|
{
|
|
|
double verDis = getVerticalDistance(dPoint1, dPoint2);
|
|
|
double reverseDis = getTailPt().l - verDis;
|
|
|
return reverseDis;
|
|
|
|
|
|
/*
|
|
|
int index1 = -1;
|
|
|
int index2 = -1;
|
|
|
MLPlNode dptDest1, dptDest2;
|
|
|
double dis = 0;
|
|
|
|
|
|
double dis1 = getNearest(dPoint1, index1, dptDest1);
|
|
|
double dis2 = getNearest(dPoint2, index2, dptDest2);
|
|
|
|
|
|
if (index1 > index2)
|
|
|
{
|
|
|
double dis1 = getDistance(dptDest2, getHeadPt());
|
|
|
double dis2 = getDistance(dptDest1, getTailPt());
|
|
|
dis = dis1 + dis2;
|
|
|
}
|
|
|
else if (index1 < index2)
|
|
|
{
|
|
|
double dis1 = getDistance(dptDest1, getHeadPt());
|
|
|
double dis2 = getDistance(dptDest2, getTailPt());
|
|
|
dis = dis1 + dis2;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
double dis0 = getDistance(dptDest1, dptDest2);
|
|
|
dis = getTailPt().l - dis0;
|
|
|
}
|
|
|
return dis;
|
|
|
*/
|
|
|
}
|
|
|
|
|
|
double MLPline::getNearest( const MLPlNode& node, int& index, MLPlNode& dptDest )
|
|
|
{
|
|
|
// <20><><EFBFBD>ص<EFBFBD>ǰ<EFBFBD><C7B0><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
double dis = 0.0;
|
|
|
int nCount = (int)m_nodeAry.count();
|
|
|
if(nCount <2) return dis;
|
|
|
|
|
|
// <20><><EFBFBD>뱣֤<EBB1A3>㼯<EFBFBD><E3BCAF><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
double dNearest=0.0, dd;
|
|
|
MLPlNode dptLast = getAtPt(0);
|
|
|
MLPlNode dptCur, dptNearest, dptRet;
|
|
|
index = -1;
|
|
|
|
|
|
for (int i = 1; i < nCount; i ++)
|
|
|
{
|
|
|
dptCur = getAtPt(i);
|
|
|
if (Equ(dptCur.x, dptLast.x) && Equ(dptCur.y, dptLast.y))
|
|
|
{
|
|
|
dptLast = dptCur;
|
|
|
continue;
|
|
|
}
|
|
|
|
|
|
dd = GetDistance(node, dptLast, dptCur, dptNearest);
|
|
|
if (index == -1 || dd < dNearest)
|
|
|
{
|
|
|
dNearest = dd;
|
|
|
dptRet = dptNearest;
|
|
|
index = i;
|
|
|
dptDest = dptNearest;
|
|
|
}
|
|
|
|
|
|
dptLast = dptCur;
|
|
|
}
|
|
|
|
|
|
dis = dNearest;
|
|
|
return dis;
|
|
|
}
|
|
|
|
|
|
void MLPline::toSinglePline( QList<MLPline *>& singleCurveList, double Angle )
|
|
|
{
|
|
|
int nCount = getCount();
|
|
|
MLPlNode dpt;
|
|
|
if(nCount <2) return ;
|
|
|
|
|
|
MLPline* pCurve = new MLPline();
|
|
|
pCurve->setName(m_name);
|
|
|
singleCurveList.push_back(pCurve);
|
|
|
|
|
|
for(int i=0;i<nCount;i++)
|
|
|
{
|
|
|
dpt = (*this)[i];
|
|
|
if(dpt.z > Angle)
|
|
|
{
|
|
|
pCurve->addTailPt(dpt);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
pCurve->addTailPt(dpt);
|
|
|
|
|
|
pCurve = new MLPline();
|
|
|
singleCurveList.push_back(pCurve);
|
|
|
pCurve->setName(m_name);
|
|
|
pCurve->addTailPt(dpt);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
void MLPline::createEllipse(const MLPoint& point, double radius)
|
|
|
{
|
|
|
m_nodeAry.clear();
|
|
|
|
|
|
int arc1 = 0;
|
|
|
int arc2 = 360;
|
|
|
double a0 = arc1;
|
|
|
int num = int((arc2-arc1)/10.0);
|
|
|
m_nodeAry.resize(num);
|
|
|
for (int i = 0; i < num; i++)
|
|
|
{
|
|
|
MLPoint dpt;
|
|
|
dpt.x = point.x + radius * cos(a0 / RHO);
|
|
|
dpt.y = point.y + radius * sin(a0 / RHO);
|
|
|
a0 += 10.0;
|
|
|
m_nodeAry[i] = dpt;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
MLPoint MLPline::calculateCentroid()
|
|
|
{
|
|
|
/* Compute polygon centroid location */
|
|
|
int i, last;
|
|
|
double A, d, xold, yold;
|
|
|
|
|
|
calculateArea();
|
|
|
A = m_dArea;
|
|
|
last = getCount();
|
|
|
|
|
|
double Cx=0.0 ,Cy = 0.0;
|
|
|
xold = m_nodeAry[last-1].x;
|
|
|
yold = m_nodeAry[last-1].y;
|
|
|
for (i = 0; i < last; i++)
|
|
|
{
|
|
|
d = (xold * m_nodeAry[i].y - m_nodeAry[i].x * yold);
|
|
|
Cx += (m_nodeAry[i].x + xold) * d;
|
|
|
Cy += (m_nodeAry[i].y + yold) * d;
|
|
|
xold = m_nodeAry[i].x;
|
|
|
yold = m_nodeAry[i].y;
|
|
|
}
|
|
|
|
|
|
Cx /= (6.0 * A);
|
|
|
Cy /= (6.0 * A);
|
|
|
|
|
|
return MLPoint(Cx, Cy);
|
|
|
//return ((A < 0.0) ? -1 : +1); /* -1 means CCW, +1 means CW */
|
|
|
}
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
MLDPlineRedundant::MLDPlineRedundant(void)
|
|
|
{
|
|
|
m_nMarkNum = 0;
|
|
|
m_pMark = 0;
|
|
|
m_dbMinDistance=0.0;
|
|
|
num =0;
|
|
|
x = nullptr;
|
|
|
y = nullptr;
|
|
|
z = nullptr;
|
|
|
l = nullptr;
|
|
|
}
|
|
|
|
|
|
MLDPlineRedundant::MLDPlineRedundant(double *oldx,double *oldy,double *oldz,double *oldl,int oldnum,int *mark)
|
|
|
{
|
|
|
num = oldnum;
|
|
|
x = oldx;
|
|
|
y = oldy;
|
|
|
z = oldz;
|
|
|
l = oldl;
|
|
|
m_pMark = mark;
|
|
|
|
|
|
m_nMarkNum = 0;
|
|
|
m_dbMinDistance=0.0;
|
|
|
}
|
|
|
|
|
|
MLDPlineRedundant::MLDPlineRedundant(double *oldx,double *oldy,int oldnum,int *mark)
|
|
|
{
|
|
|
num = oldnum;
|
|
|
x = oldx;
|
|
|
y = oldy;
|
|
|
z = nullptr;
|
|
|
l = nullptr;
|
|
|
|
|
|
m_pMark = mark;
|
|
|
|
|
|
m_nMarkNum = 0;
|
|
|
m_dbMinDistance=0.0;
|
|
|
}
|
|
|
|
|
|
MLDPlineRedundant::~MLDPlineRedundant(void)
|
|
|
{
|
|
|
|
|
|
}
|
|
|
|
|
|
int Compare(const void *e1,const void * e2)
|
|
|
{
|
|
|
int s1,s2;
|
|
|
s1=*(int *)e1;
|
|
|
s2=*(int *)e2;
|
|
|
if(s1>s2)return 1;
|
|
|
if(s1<s2)return -1;
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
//ִ<><D6B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ദ<EFBFBD><E0B4A6>
|
|
|
void MLDPlineRedundant::execute(double dbError)
|
|
|
{
|
|
|
m_dbMinDistance = dbError;
|
|
|
|
|
|
m_nMarkNum = 2;
|
|
|
|
|
|
m_pMark[0] = 0;
|
|
|
m_pMark[1] = num-1;
|
|
|
|
|
|
getNewPoint(0, num-1);
|
|
|
qsort(m_pMark, m_nMarkNum, sizeof(int), Compare);
|
|
|
}
|
|
|
|
|
|
double GetDisDPt(double x0,double y0,double k,double b)
|
|
|
{
|
|
|
if(fabs(k)>1e30)return x0-b;
|
|
|
return (y0-k*x0-b)/sqrt(1.0+k*k);
|
|
|
}
|
|
|
|
|
|
void MLDPlineRedundant::getNewPoint(int n1,int n2)
|
|
|
{
|
|
|
int ns,i;
|
|
|
double t1,t2,k,b;
|
|
|
if(n2-n1<2)return ;
|
|
|
|
|
|
t1 = -1e30;
|
|
|
k = x[n2] - x[n1];
|
|
|
|
|
|
if(fabs(k)<1e-30)
|
|
|
{
|
|
|
k = 1e40;
|
|
|
b = x[n1];
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
k = (y[n2] - y[n1])/k;
|
|
|
b = y[n1] - k * x[n1];
|
|
|
}
|
|
|
ns = n1 + 1;
|
|
|
|
|
|
for(i=n1+1; i<n2; ++i)
|
|
|
{
|
|
|
t2 = GetDisDPt(x[i],y[i],k,b);
|
|
|
t2 = fabs(t2);
|
|
|
if(t2>t1)
|
|
|
{
|
|
|
t1 = t2;
|
|
|
ns = i ;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
if(t1<m_dbMinDistance)
|
|
|
return ;
|
|
|
|
|
|
m_pMark[m_nMarkNum] = ns;
|
|
|
|
|
|
++m_nMarkNum;
|
|
|
|
|
|
getNewPoint(n1,ns);
|
|
|
getNewPoint(ns,n2);
|
|
|
}
|
|
|
|
|
|
int MLDPlineRedundant::getMarkNum()
|
|
|
{
|
|
|
return m_nMarkNum;
|
|
|
} |