#include "MLPline.h" #include "MLPoint.h" #include "MLFuncom.h" #include #include 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& 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& MLPline::getNodeAry() { return m_nodeAry; } void MLPline::setNodeAry(const QVector& nodeAry ) { m_nodeAry = nodeAry; } void MLPline::setNodeAry(const QPolygonF& polygon) { m_nodeAry.clear(); m_nodeAry.resize(polygon.count()); for (int i=0;i1) 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=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=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(); } // 移出结点 void MLPline::removeRt(const MLRect& dRect) { int count = getCount(); QVector nodeAry; nodeAry.resize(count); int j=0; /*for (int i=0;i1) { 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 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); } // 曲线节点反向 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& 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()); } // 向曲线头增加闭合点 void MLPline::closeHeadPt() { double dis = GetDistance(m_nodeAry.front(), m_nodeAry.last()); if (dis > 2.0) { m_nodeAry.push_front(m_nodeAry.last()); } } // 向曲线尾增加闭合点 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 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 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 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); } } // 查找线点相近点索此 int MLPline::findIndex(const MLPoint& point, double delt/*=0.5*/) { int index = -1; int nCount = m_nodeAry.count(); for (int i=0;i> 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 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 ) { // 返回当前点后索引 double dis = 0.0; int nCount = (int)m_nodeAry.count(); if(nCount <2) return dis; // 必须保证点集中至少有两个点 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& 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 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(s11e30)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; it1) { t1 = t2; ns = i ; } } if(t1