TheSwamp
September 08, 2010, 07:45:59 pm *
Welcome, Guest. Please login or register.

Login with username, password and session length
News:
 
   Home   Help Login Register  
Pages: [1] 2  All |   Go Down
  Print  
Author Topic: convex hull  (Read 447 times)
0 Members and 1 Guest are viewing this topic.
__declspec
A Plethora of C++
SuperMod
Needs a day job

Posts: 5837


AKA Daniel


WWW

Ignore
« on: November 16, 2009, 02:41:00 am »

Code:
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 download
ArxConvexHull.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
Newt

Posts: 129




Ignore
« Reply #2 on: December 27, 2009, 10:56:22 am »

 huh
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. wink
Logged
frtfff
Newt

Posts: 129




Ignore
« 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  undecided
Logged

frtfff
Newt

Posts: 129




Ignore
« Reply #5 on: January 14, 2010, 09:46:33 am »

 
Logged
frtfff
Newt

Posts: 129




Ignore
« Reply #6 on: January 15, 2010, 09:54:05 am »

 

There are 1 attachment(s) in this post which you cannot view or download
convex hull.swf
Logged
frtfff
Newt

Posts: 129




Ignore
« 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;
  }
//
Huh?
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
Newt

Posts: 129




Ignore
« 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 download
ConvexHull.rar
Logged
frtfff
Newt

Posts: 129




Ignore
« 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
Newt

Posts: 129




Ignore
« 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 »

for more reading http://en.wikipedia.org/wiki/Graham_scan
Logged

frtfff
Newt

Posts: 129




Ignore
« Reply #14 on: January 31, 2010, 08:34:34 am »

Thanks
Logged
Pages: [1] 2  All |   Go Up
  Print  
 
Jump to:  

Powered by MySQL Powered by PHP Powered by SMF 1.1.11 | SMF © 2006-2009, Simple Machines LLC Valid XHTML 1.0! Valid CSS!