You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1198 lines
20 KiB
C++

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

#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;
}