__declspec
A Plethora of C++
SuperMod
Needs a day job
Posts: 5837
AKA Daniel
WWW
Ignore
|
 |
« on: November 16, 2009, 02:41:00 am » |
|
static int ccw(const AcGePoint3d &p1,const AcGePoint3d &p2, const AcGePoint3d &p3) { double or = (p2.x - p1.x)*(p3.y - p1.y)-(p2.y - p1.y)*(p3.x - p1.x); if(or < 0.0) return -1; else if(or > 0.0) return 1; else return 0; }
static bool PointSortByX(const AcGePoint3d &a, const AcGePoint3d &b) { if(a.x == b.x) return a.y < b.y; return a.x < b.x; }
static void getPoints(PointVector &vec) { AcDbObjectIdArray ids; CResbufPtr pFilter (acutBuildList(RTDXF0,ACRX_T("POINT,LINE,LWPOLYLINE"),NULL)); CSelectionSet sset; sset.userSelect(pFilter); sset.asArray(ids); for(int i = 0 ; i < ids.length(); i++) { AcDbEntityPointer pEnt(ids[i],AcDb::kForRead); if(pEnt.openStatus() == eOk ) { if(pEnt->isA() == AcDbPoint::desc()) { AcDbPoint *pPoint = AcDbPoint::cast(pEnt); if(pPoint) { vec.push_back(pPoint->position()); } } else if(pEnt->isA() == AcDbLine::desc()) { AcDbLine *pLine = AcDbLine::cast(pEnt); if(pLine) { vec.push_back(pLine->startPoint()); vec.push_back(pLine->endPoint()); } } else if(pEnt->isA() == AcDbPolyline::desc()) { AcDbPolyline *pLine = AcDbPolyline::cast(pEnt); if(pLine) { for(int i = 0 ; i < pLine->numVerts() ; i++) { AcGePoint3d pt; pLine->getPointAt(i,pt); vec.push_back(pt); } } } } } }
static void sortPoints(PointVector &points, PointVector &ptsout) { PointVector upper; PointVector lower; AcGePoint3d left, right; PointVector::const_iterator iter; PointVector::const_reverse_iterator riter;
std::sort(points.begin(), points.end(), PointSortByX);
if(points.size() > 3) { left = points.front(); right = points.back();
for ( size_t i = 0 ; i < points.size() ; i++ ) { int dir = ccw( left, right, points[ i ] ); if ( dir < 0 ) upper.push_back( points[ i ] ); else lower.push_back( points[ i ] ); }
for ( iter = upper.begin() ; iter != upper.end() ; ++iter ) ptsout.push_back(AcGePoint3d((*iter).x, (*iter).y , (*iter).z));
for ( riter = lower.rbegin() ; riter != lower.rend() ; ++riter ) ptsout.push_back(AcGePoint3d((*riter).x, (*riter).y , (*riter).z)); } }
static void grahamScan(const PointVector &points , PointVector &ptsout) { PointDeque pntQue; PointDeque::const_iterator iter; pntQue.push_front(points[0]); pntQue.push_front(points[1]);
unsigned int i = 2;
while(i < points.size()) { if (pntQue.size() > 1) { if (ccw(pntQue[1],pntQue[0],points[i]) == 1) pntQue.push_front(points[i++]); else pntQue.pop_front(); } else pntQue.push_front(points[i++]); }
for(iter = pntQue.begin(); iter != pntQue.end(); ++iter) ptsout.push_back(AcGePoint3d((*iter).x, (*iter).y , (*iter).z)); }
// - ArxConvexHull._doit command (do not rename) static void ArxConvexHull_doit(void) { PointVector::const_iterator iter; PointVector basepoints,sortedPoints; getPoints(basepoints); sortPoints(basepoints,sortedPoints); basepoints.clear(); grahamScan(sortedPoints,basepoints); AcDbPolyline *pline = new AcDbPolyline(basepoints.size());
for(size_t i = 0 ; i < basepoints.size(); i++) pline->addVertexAt(i,AcGePoint2d(basepoints[i].x,basepoints[i].y));
pline->setClosed(Adesk::kTrue); AddEntityToDataBase(pline); }
static void AddEntityToDataBase(AcDbEntity *pEnt) { AcDbDatabase* pDb = acdbHostApplicationServices()->workingDatabase(); AcDbBlockTableRecordPointer pBTR(pDb->currentSpaceId(), AcDb::kForWrite); if (pEnt && Acad::eOk == pBTR.openStatus()) { pBTR->appendAcDbEntity(pEnt); pEnt->close(); } }
|
There are 2 attachment(s) in this post which you cannot view or downloadArxConvexHull.zip Capture.PNG
|
|
« Last Edit: November 16, 2009, 09:08:54 am by Daniel »
|
Logged
|
|
|
|
MickD
Water Moccasin
Posts: 2368
WWW
Ignore
|
 |
« Reply #1 on: November 16, 2009, 03:45:16 pm » |
|
A fair bit of work there Daniel, nice job!
|
|
|
|
|
Logged
|
"There isn't any software! Only different internal states of hardware. It's all hardware! It's a shame programmers don't grok that better." - 1984 - unknown
|
|
|
|
frtfff
|
 |
« Reply #2 on: December 27, 2009, 10:56:22 am » |
|
 Nice,This is so nice to slove one of the matters for delaunay.Next work is to construct a constrain_line.That,I can finish it. 
|
|
|
|
|
Logged
|
|
|
|
|
frtfff
|
 |
« Reply #3 on: January 14, 2010, 06:22:11 am » |
|
Mr. Daniel: I can't get the internal hull,Why?
|
There are 1 attachment(s) in this post which you cannot view or download未命名.jpg
|
|
|
Logged
|
|
|
|
__declspec
A Plethora of C++
SuperMod
Needs a day job
Posts: 5837
AKA Daniel
WWW
Ignore
|
 |
« Reply #4 on: January 14, 2010, 06:49:41 am » |
|
Mr. Daniel: I can't get the internal hull,Why?
I don't know 
|
|
|
|
|
Logged
|
|
|
|
|
frtfff
|
 |
« Reply #5 on: January 14, 2010, 09:46:33 am » |
|
|
|
|
|
|
Logged
|
|
|
|
|
frtfff
|
 |
« Reply #6 on: January 15, 2010, 09:54:05 am » |
|
|
There are 1 attachment(s) in this post which you cannot view or downloadconvex hull.swf
|
|
|
Logged
|
|
|
|
|
frtfff
|
 |
« Reply #7 on: January 25, 2010, 10:53:26 pm » |
|
static int ccw(const AcGePoint3d &p1,const AcGePoint3d &p2, const AcGePoint3d &p3) { double or = (p2.x - p1.x)*(p3.y - p1.y)-(p2.y - p1.y)*(p3.x - p1.x); if(or < 0.0) return -1; else if(or > 0.0) return 1; else return 0; } //  ?
|
|
|
|
|
Logged
|
|
|
|
__declspec
A Plethora of C++
SuperMod
Needs a day job
Posts: 5837
AKA Daniel
WWW
Ignore
|
 |
« Reply #8 on: January 25, 2010, 11:14:37 pm » |
|
ccw = counter clock wise
|
|
|
|
|
Logged
|
|
|
|
|
frtfff
|
 |
« Reply #9 on: January 31, 2010, 03:42:12 am » |
|
There is one bug inside.
|
There are 1 attachment(s) in this post which you cannot view or downloadConvexHull.rar
|
|
|
Logged
|
|
|
|
|
frtfff
|
 |
« Reply #10 on: January 31, 2010, 04:15:51 am » |
|
static void grahamScan(const PointVector &points , PointVector &ptsout) { PointDeque pntQue; PointDeque::const_iterator iter; pntQue.push_front(points[0]); pntQue.push_front(points[1]);
unsigned int i = 2;
while(i < points.size()) { if (pntQue.size() > 1) { if (ccw(pntQue[1],pntQue[0],points) == 1) pntQue.push_front(points[i++]); else pntQue.pop_front(); } else pntQue.push_front(points[i++]); }
for(iter = pntQue.begin(); iter != pntQue.end(); ++iter) ptsout.push_back(AcGePoint3d((*iter).x, (*iter).y , (*iter).z)); }
|
|
|
|
|
Logged
|
|
|
|
|
frtfff
|
 |
« Reply #11 on: January 31, 2010, 04:16:50 am » |
|
//difficult to understand while(i < points.size()) { if (pntQue.size() > 1) { if (ccw(pntQue[1],pntQue[0],points) == 1) pntQue.push_front(points[i++]); else pntQue.pop_front(); } else pntQue.push_front(points[i++]); }
|
|
|
|
|
Logged
|
|
|
|
__declspec
A Plethora of C++
SuperMod
Needs a day job
Posts: 5837
AKA Daniel
WWW
Ignore
|
 |
« Reply #12 on: January 31, 2010, 04:48:54 am » |
|
//difficult to understand while(i < points.size()) { if (pntQue.size() > 1) { if (ccw(pntQue[1],pntQue[0],points) == 1) pntQue.push_front(points[i++]); else pntQue.pop_front(); } else pntQue.push_front(points[i++]); }
pretty slick huh!, it's using a std::deque to test if the next point is a left turn or right turn, if it's a right turn, pop it, else push it and test the next point
|
|
|
|
|
Logged
|
|
|
|
__declspec
A Plethora of C++
SuperMod
Needs a day job
Posts: 5837
AKA Daniel
WWW
Ignore
|
 |
« Reply #13 on: January 31, 2010, 04:51:09 am » |
|
|
|
|
|
|
Logged
|
|
|
|
|
frtfff
|
 |
« Reply #14 on: January 31, 2010, 08:34:34 am » |
|
Thanks
|
|
|
|
|
Logged
|
|
|
|
|