chpmould 发表于 2011-6-1 19:10:38

排除重复点

如何显现从AcGePoint3dArray ptArr中排除重复点...请会的指导一下...

bluelightcsy 发表于 2011-6-1 19:56:31

AcGePoint3d::isEqualTo 这个可以指定一个Tol,容许误差范围,希望可以帮到你

chpmould 发表于 2011-6-2 00:23:28

bluelightcsy 发表于 2011-6-1 19:56 static/image/common/back.gif
AcGePoint3d::isEqualTo 这个可以指定一个Tol,容许误差范围,希望可以帮到你

谢谢,我查看帮助具体用法先试试...

chpmould 发表于 2011-6-18 09:23:19

试了多次,但是没有成功,请高手们在百忙之中抽出一点时间,帮写出排查重复点的局部示范代码

highflybird 发表于 2011-6-18 14:54:13

回复 chpmould 的帖子

先创建一个类,譬如CPoint3d

#pragma once
#include "c:\objectarx 2012\inc\gepnt3d.h"    //--->根据你的目录来定
class CPoint3d : public AcGePoint3d
{
private:
double fuzz;
public:
CPoint3d(void):fuzz(0.0){}
~CPoint3d(void){}
void SetFuzz(double tol)
{
fuzz = tol;
}
void copy(c**t AcGePoint3d & pt)
{
this->x=pt.x;
this->y=pt.y;
this->z=pt.z;
}
bool isEqualTo(double x1,double x2) c**t
{
      double delta = x1 - x2;
return (delta <= fuzz && delta >= (-fuzz));
}
bool operator < ( c**t CPoint3d& pt) c**t
{
if (isEqualTo(this->x,pt.x))
   if (isEqualTo(this->y,pt.y))
    return (this->z < pt.z);
   else
    return (this->y < pt.y);
return (this->x < pt.x);
}
};

highflybird 发表于 2011-6-18 15:03:45

本帖最后由 highflybird 于 2011-6-18 21:20 编辑

回复 chpmould 的帖子

然后在程序中这样用:
#include <set>
#include <algorithm>
using namespace std;

以下为测试:
在你的函数中这样添加:


//过滤选择CAD的点(PointArray)对象
resbuf filter;
filter.restype=0;
filter.resval.rstring=_T("POINT");
filter.rbnext = NULL;
ads_name sel;
int ret=acedSSGet(NULL,NULL,NULL,&filter,sel);
if( ret!=RTNORM)
{
   acedSSFree(sel);
   return;
}
long len;
ads_name ent;
AcDbObjectId ObjId;
AcDbPoint *pEnt;
acedSSLength(sel,&len);
AcGePoint3dArray ptset;
for (long i = 0;i<len;i++)
{
   acedSSName(sel,i,ent);
   acdbGetObjectId(ObjId,ent);
   if (acdbOpenObject(pEnt,ObjId,AcDb::kForRead)!=Acad::eOk)
    continue;
   ptset.append(pEnt->position());
   pEnt->close();
}
acedSSFree(sel);

len = ptset.length();

//这样得到了AcGePoint3dArray,然后运用set,排除重复点:
set<CPoint3d> pts;
CPoint3d tempPt;
tempPt.SetFuzz(1e-4);
for (int i = 0; i < ptset.length();i++)
{
   tempPt.copy(ptset[ i ]);
   pts.insert(tempPt);
}
//利用set迭代器,构建新的AcGePoint3dArray:
size_t newlen = pts.size();
acutPrintf(_T("New size is %d"),newlen);
ptset.removeAll();
ptset.setLogicalLength(newlen);
AcGePoint3d Pt3d;
set<CPoint3d>::iterator pItr;
int i = 0;
for (pItr = pts.begin();pItr!=pts.end();pItr++)
{
   acutPrintf(_T("\nPoint [%d] is : %f,%f,%f"),i,(*pItr).x,(*pItr).y,(*pItr).z);
   Pt3d.x=(*pItr).x;
   Pt3d.y=(*pItr).y;
   Pt3d.z=(*pItr).z;
   ptset[ i ] = Pt3d;
   i++;
}

chpmould 发表于 2011-6-18 16:16:05

本帖最后由 chpmould 于 2011-6-18 16:17 编辑

highflybird 发表于 2011-6-18 15:03 http://space.mjtd.com/static/image/common/back.gif
回复 chpmould 的帖子

然后在程序中这样用:


谢你的热心帮助,目前还没有看懂,先下来慢慢消化...能否不用定义一个类啊

highflybir 发表于 2011-6-18 19:08:01

本帖最后由 highflybir 于 2011-6-18 19:14 编辑

回复 chpmould 的帖子

不学走,先要跑,是行不通的方法。
C++,类要必须掌握。
我只能说,如果这个题目不用类的方法,代码更多,更 复杂,局限性更大。
简单几句定义了类后,核心代码只有几句:

//这样得到了AcGePoint3dArray,然后运用set,排除重复点:
set<CPoint3d> pts;
CPoint3d tempPt;
tempPt.SetFuzz(1e-4);
for (int i = 0; i < ptset.length();i++)
{
   tempPt.copy(ptset[ i ]);
   pts.insert(tempPt);
}

highflybird 发表于 2011-6-18 21:07:08

本帖最后由 highflybird 于 2011-6-19 15:15 编辑

回复 chpmould 的帖子

如果在点数不是很多情况下,可以这样:这样不需要排序,所以直接列举就可以了:

AcGeTol tol;
tol.setEqualPoint(1e-4);
AcGePoint3dArrayNewPtSet = ptset;            //-->ptset原来 AcGePoint3dArray,NewPtSet,就是以后要删除重复点的点集
long newLen = NewPtSet.length();
for (int i = 0;i < newLen;i++)
{
   for (int j = i+1;j < newLen;j++)
   {
    if (NewPtSet[ j ].isEqualTo(NewPtSet[ i ],tol))
    {
   NewPtSet.removeAt(j);
   j--;
   newLen--;
    }
   }
}

chpmould 发表于 2011-6-19 09:31:57

highflybir 发表于 2011-6-18 19:08 static/image/common/back.gif
回复 chpmould 的帖子

不学走,先要跑,是行不通的方法。


谢谢指正,后续慢慢纠正...
页: [1]
查看完整版本: 排除重复点