找回密码
 立即注册

QQ登录

只需一步,快速开始

扫一扫,访问微社区

查看: 1854|回复: 15

[求助] 【已解决】按参数对AcGePoint3dArray进行排序,见置顶

[复制链接]

已领礼包: 112个

财富等级: 日进斗金

发表于 2016-10-2 22:20:45 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

×
本帖最后由 革天明 于 2016-10-6 09:37 编辑

如何对AcGePoint3dArray进行排序,最好有这样的参数,如xYz,表示先按X从小到大排列,再按Y从大到小排序,再按Z从小到大排序
目前搜索后发现对于坐标点的排序不多,不知道是不是ObjectARX自带有这样的排序函数?如果有的话请大家告知,谢谢!
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!

已领礼包: 112个

财富等级: 日进斗金

 楼主| 发表于 2016-10-4 14:56:12 | 显示全部楼层

谢谢指导,但我使用之后还是没有成功,下面将我的代码贴出来供您参考
        // - YTMsupport.RT command (do not rename)
        //按照x从小到大排序,当x相等时按照y从大到小排序
        static int compare (const AcGePoint3d &p1 , const AcGePoint3d &p2)
        {
                if(fabs((p1.x-p2.x)) < 0.00001)
                {
                        if (p1.y < p2.y)
                                return 1;
                        else
                                return -1;
                }
                else
                {
                        if (p1.x > p2.x)
                                return 1;
                        else
                                return -1;
                }
        }

        static void YTMsupportRT(void)
        {
                // Add your code for command YTMsupport.RT here
                ads_name sset;
                ads_point pt1,pt2;
                struct resbuf *rb;
                rb=acutBuildList(RTDXF0,_T("LINE,ARC,LWPOLYLINE"),RTNONE);
                acutPrintf(_T("\n请选择砂面的轮廓线:"));
                if(acedGetPoint(NULL,_T("\n请选择左上角点:"),pt1)!=RTNORM)
                {
                        return;
                }
                if(acedGetCorner(pt1,_T("\n请输入右下角点:"),pt2)!=RTNORM)
                {
                        return;
                }               
                if(acedSSGet(_T("W"),pt1,pt2,rb,sset)!=RTNORM)
                {
                        return;
                }
               
                long length=0;
                acedSSLength(sset,&length);
                acutPrintf(_T("\n实体数:%d"),length);
                AcGePoint3dArray ptarry;
                ptarry.setLogicalLength(0);
                for(int i=0;i<length;i++)
                {
                        ads_name ename;
                        Acad::ErrorStatus es;
                        acedSSName(sset,i,ename);
                        AcDbObjectId entId;
                        //获取图元ID
                        es=acdbGetObjectId(entId,ename);
                        if(es == Acad::eOk)
                        {
                                AcDbEntity *pEnt=NULL;
                                AcDbLine *pLine=NULL;
                                AcDbArc *pArc=NULL;
                                AcDb2dPolyline *p2dPline=NULL;
                                AcDb3dPolyline *p3dPline=NULL;
                                AcDbPolyline *pPline=NULL;
                                es=acdbOpenObject(pEnt,entId,AcDb::kForRead);
                                if(es == Acad::eOk)
                                {
                                        if(pEnt->isKindOf(AcDbLine::desc()))
                                        {
                                                pLine=AcDbLine::cast(pEnt);
                                                ptarry.append(pLine->startPoint());
                                                ptarry.append(pLine->endPoint());
                                        }
                                        if(pEnt->isKindOf(AcDbArc::desc()))
                                        {
                                                pArc=AcDbArc::cast(pEnt);
                                                //AcGePoint3d pt0(0,0,0);
                                                AcGePoint3d pcen=pArc->center();
                                                //CCreatEnt::YTMAddLine(pt0,pcen);
                                                AcGePoint3d pstar;
                                                pstar[X]=pcen[X]+cos(pArc->startAngle())*(pArc->radius());
                                                pstar[Y]=pcen[Y]+sin(pArc->startAngle())*(pArc->radius());
                                                pstar[Z]=0;
                                                AcGePoint3d pend;
                                                pend[X]=pcen[X]+cos(pArc->endAngle())*(pArc->radius());
                                                pend[Y]=pcen[Y]+sin(pArc->endAngle())*(pArc->radius());
                                                pend[Z]=0;
                                                //CCreatEnt::YTMAddLine(pstar,pend);
                                                ptarry.append(pstar);
                                                ptarry.append(pend);
                                        }
                                        if(pEnt->isKindOf(AcDb3dPolyline::desc()))
                                        {
                                                p3dPline=AcDb3dPolyline::cast(pEnt);
                                                AcDbObjectIterator* pVertsIter=p3dPline->vertexIterator();
                                                AcDb3dPolylineVertex* pVertex=NULL;
                                                AcDbObjectId vertexId;
                                                for(;!pVertsIter->done();pVertsIter->step())
                                                {
                                                        vertexId=pVertsIter->objectId();
                                                        p3dPline->openVertex(pVertex,vertexId,AcDb::kForRead);
                                                        ptarry.append(pVertex->position());
                                                }
                                                delete pVertsIter;

                                        }
                                        if(pEnt->isKindOf(AcDb2dPolyline::desc()))
                                        {
                                                p2dPline=AcDb2dPolyline::cast(pEnt);
                                                AcDbObjectIterator *pVertIter = p2dPline->vertexIterator();
                                                //对顶点进行遍历
                                                AcDb2dVertex *pVertex;
                                                AcGePoint3d location;
                                                AcDbObjectId vertexobjectId;
                                                for (int vertexNumber = 0; !pVertIter->done(); vertexNumber++, pVertIter->step())
                                                {
                                                        //打开矢量对象
                                                        vertexobjectId = pVertIter->objectId();
                                                        if(acdbOpenObject(pVertex, vertexobjectId,AcDb::kForRead)!=Acad::eOk)
                                                        {
                                                                return;
                                                        }

                                                        //获得矢量对象的坐标
                                                        location = pVertex->position();
                                                        pVertex->close();

                                                        //输出坐标
                                                        //acutPrintf(L"\nVertox %d location is : %0.3f, %0.3f, %0.3f", vertexNumber, location[X], location[Y], location[Z]);
                                                        ptarry.append(location);
                                                }
                                                delete pVertIter;
                                        }
                                        if(pEnt->isKindOf(AcDbPolyline::desc()))
                                        {
                                                pPline=AcDbPolyline::cast(pEnt);
                                                for(int i=0;i<pPline->numVerts();i++)
                                                {
                                                        AcGePoint3d pt;
                                                        pPline->getPointAt (i,pt);
                                                        ptarry.append(pt);
                                                }
                                        }
                                }
                                if(pEnt!=NULL)
                                {
                                        pEnt->close();
                                }
                                if(pLine!=NULL)
                                {
                                        pLine->close();
                                }
                                if(pArc!=NULL)
                                {
                                        pArc->close();
                                }
                                if(p2dPline!=NULL)
                                {
                                        p2dPline->close();
                                }
                                if(p3dPline!=NULL)
                                {
                                        p3dPline->close();
                                }
                        }                               
                }
                AcGeVector3d v1(0,5,0);
                for(int i=0;i<ptarry.length();i++)
                {
                        CString strtmp;
                        //strtmp.Format(_T("%.2f,%.2f,%.2f"),ptarry.at(i)[X],ptarry.at(i)[Y],ptarry.at(i)[Z]);
                        strtmp.Format(_T("%d"),i);
                        CCreatEnt::SetColor(CCreatEnt::YTMAddMText(ptarry.at(i)+v1,strtmp),3);
                }
               
                std::sort(ptarry.asArrayPtr(),ptarry.asArrayPtr()+ptarry.logicalLength(),compare);
                AcGeVector3d v2(0,-5,0);
                for(int i=0;i<ptarry.length();i++)
                {
                        CString strtmp;
                        //strtmp.Format(_T("%.2f,%.2f,%.2f"),ptarry.at(i)[X],ptarry.at(i)[Y],ptarry.at(i)[Z]);
                        strtmp.Format(_T("%d"),i);                       
                        CCreatEnt::SetColor(CCreatEnt::YTMAddMText(ptarry.at(i)+v2,strtmp),1);
                }
               
                AcGePoint3d ptright=ptarry.at(0);
                AcGePoint3d ptleft=ptarry.at(ptarry.length()-1);
               
                CCreatEnt::YTMAddMText(ptright,_T("左"));
                CCreatEnt::YTMAddMText(ptleft,_T("右"));
                int n = ptarry.logicalLength();
                AcGePoint3d * pts = new AcGePoint3d[n];
                for (int i = 0;i<n;i++)
                {
                        pts = ptarry;
                }
                qsort(pts,n,sizeof(AcGePoint3d),comp_x);


                acutPrintf(_T("\n排序后结果是:"));
                for (int i = 0;i<n;i++)
                {
                        acutPrintf(_T("\n第 %d的坐标是: %.1f , %.1f"),i,pts.x,pts.y);
                }
                delete [] pts;
                pts = NULL;


                acutRelRb(rb);
                acedSSFree(sset);
                acutPrintf(_T("\n轮体旋转完成!壹加技术."));
        }
        static int comp_x(const void *p1,const void *p2 )
        {
                if (((AcGePoint3d *)p1)->x <  ((AcGePoint3d *)p2)->x)
                        return -1;
                else
                        return (((AcGePoint3d  *)p1)->x == ((AcGePoint3d  *)p2)->x) ? 0 : 1;
        }


代码中红色部分来源于http://www.objectarx.net/forum.p ... page=1&tid=9516中高飞鸟的代码,他的排序是正确的。由于我的代码没有对直线相接处的端点进行去重复点,所以序号文字会有重叠的。我想求的是多个直线、圆弧、多段线的最左、最右点(当X坐标相同时,取Y值最小的点),您的排序最左、最右点分别是第二和倒数第二个点,且顺序好像不太对。
2016-10-04_144739.png
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 40个

财富等级: 招财进宝

发表于 2016-10-2 22:26:46 | 显示全部楼层
ARX自带的肯定没有,ARX是C++,C++丰富的资源都可以用,你可以找数组的快速排序的算法,有很多。
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 13个

财富等级: 恭喜发财

发表于 2016-10-2 23:17:43 | 显示全部楼层
下面代码把AcGePoint3dArray按X排序,快速排序算法,你可以参照下。

  1. void qsortxup(AcGePoint3dArray &pData,int left,int right)
  2. {
  3.   int i,j;
  4.   AcGePoint3d middle,iTemp;
  5.   i = left;
  6.   j = right;
  7.   middle = pData[(left+right)/2]; //求中间值
  8.   do{
  9.     while((pData.y<=middle.y) && (pData.x<middle.x) && (i<right))//从左扫描大于中值的数
  10.       i++;
  11.     while((pData[j].y>=middle.y) && (pData[j].x>middle.x) && (j>left))//从右扫描大于中值的数
  12.       j--;
  13.     if(i<=j)//找到了一对值
  14.     {
  15.       //交换
  16.       iTemp = pData;
  17.       pData = pData[j];
  18.       pData[j] = iTemp;
  19.       i++;
  20.       j--;
  21.     }
  22.   }while(i<=j);//如果两边扫描的下标交错,就停止(完成一次)

  23.   //当左边部分有值(left<j),递归左半边
  24.   if(left<j)
  25.     qsortxup(pData,left,j);
  26.   //当右边部分有值(right>i),递归右半边
  27.   if(right>i)
  28.     qsortxup(pData,i,right);
  29. }

论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 6569个

财富等级: 富甲天下

发表于 2016-10-3 00:10:25 | 显示全部楼层
谢谢提供,试用一下,祝国庆快乐
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 264个

财富等级: 日进斗金

发表于 2016-10-3 04:06:42 来自手机 | 显示全部楼层
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 112个

财富等级: 日进斗金

 楼主| 发表于 2016-10-3 15:05:10 | 显示全部楼层

您好!对于一个AcGePoint3dArray ptarry数组,如何按X从小到大进行排序,当X相等时,按Y从小到大排序?能帮助写一个这样的一个完整吗?
如AcGePoint3d为
(1.0,2.0,0.0)
(5.0,0.0,0.0)
(3.0,1.0,0.0)
(7.0,2.0,0.0)
(5.0,-2.0,0.0)
(3.0,2.0,0.0)
按X升序Y升序后的排序结果为:
(1.0,2.0,0.0)
(3.0,1.0,0.0)
(3.0,2.0,0.0)
(5.0,-2.0,0.0)
(5.0,0.0,0.0)
(7.0,2.0,0.0)
请问如何实现?

sort我搜索后发现对于compare的编写是个问题,经常参数类型不对
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 40个

财富等级: 招财进宝

发表于 2016-10-3 15:17:38 | 显示全部楼层

LOVEARX不是给你贴了代码了吗?
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 859个

财富等级: 财运亨通

发表于 2016-10-3 17:48:57 | 显示全部楼层

试试

  1. int compare (const AcGePoint3d &p1 , const AcGePoint3d &p2)
  2. {
  3.         if(fabs((p1.x-p2.x)) < 0.00001)
  4.         {
  5.                 if (p1.y < p2.y)
  6.                         return 1;
  7.                 else
  8.                         return -1;
  9.         }
  10.         else
  11.         {
  12.                 if (p1.x > p2.x)
  13.                         return 1;
  14.                 else
  15.                         return -1;
  16.         }
  17. }
复制代码


std::sort(pts.asArrayPtr(),pts.asArrayPtr()+pts.logicalLength(),compare);
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 264个

财富等级: 日进斗金

发表于 2016-10-4 17:22:06 来自手机 | 显示全部楼层
你这个程序是完成什么功能?
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 112个

财富等级: 日进斗金

 楼主| 发表于 2016-10-4 19:44:20 | 显示全部楼层

我想求的是多个直线、圆弧、多段线的最左、最右点(当X坐标相同时,取Y值最小的点),也就是左下、右下点
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 13个

财富等级: 恭喜发财

发表于 2016-10-4 19:52:38 | 显示全部楼层

你这么说就容易了,不就是求多个实体的包围盒嘛,使用

AcDbExtents mExts;
AcDbEntity::getGeomExtents 得到点,

然后:

mExts.set(minPnt,maxPnt);


都添加进去后,

最后: mExts.get(minPnt,maxPnt) ;就得到了所有这些点的包围盒的点了。

论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 859个

财富等级: 财运亨通

发表于 2016-10-4 20:14:53 | 显示全部楼层
另外 LINE ARC LWPOLYLINE 上节点用 getStretchPoints  更简单吧
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 112个

财富等级: 日进斗金

 楼主| 发表于 2016-10-5 10:41:49 | 显示全部楼层

倒是另外一个思路,我试试,谢谢了!
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 112个

财富等级: 日进斗金

 楼主| 发表于 2016-10-5 10:42:57 | 显示全部楼层

我试试,主要还是没经验
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|申请友链|Archiver|手机版|小黑屋|辽公网安备|晓东CAD家园 ( 辽ICP备15016793号 )

GMT+8, 2024-11-26 07:41 , Processed in 0.450451 second(s), 60 queries , Gzip On.

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表