• ObjectARX 使用std::sort坐标点排序带图元排序例子


    有不少人是从autolisp转向ObjectARX开发,习惯了一些lisp的数据结构.虽然objectARX编程和lisp编程是不同编程语言,但是编程思想是可以相互借鉴的.

    就拿这个点表排序来说,在lisp中常用的方式就是构建一个(点 图元名)的表集合,使用vl-sort来排序.

    而在ObjectARX中,同样我们也可以实现这样的操作..排序的时候按点坐标排序,点附带了对象ID,便于排序后处理实体对象..

    我们这里使用一个struct来构造 点 和对象ID的结构体;

    代码

    	//定义结构体 pt,ObjId
    	struct ListPtEntId
    	{
    		AcGePoint3d pt;
    		AcDbObjectId objId;
    	};
    

      

    然后可以使用 AcArray动态数组模板来实现这个结构体的集合.

    为了简化代码,我们可以给这个数组模板typedef一个别名

    代码

    	//定义命名AcArray
    	typedef AcArray<ListPtEntId> ListPtEntIdArray;	
    

      

    代码会使用std::sort来实现排序的算法.需要先添加头文件的包含,确保sort正常使用.

    个人建议这里不使用std命名空间.使用std::sort避免命名冲突.

    同时我们可以声明一个double类型的静态全局变量来实现点值比较的容差(公差);

    代码

    //加入std算法头文件
    #include <algorithm>
    //定义点值比较的容差(公差)
    static double g_dTolerance=1.0e-8;  

    添加比较算法

    	//比较函数,先从左向右,再从上到下
    	static bool mySortByX(const ListPtEntId &s1,const ListPtEntId &s2)
    	{
    		//如果点的y值相等,x从小到大,否则y从大到小
    		if (fabs(s1.pt.y - s2.pt.y) < g_dTolerance)
    			return (s1.pt.x<s2.pt.x);
    		else
    			return (s1.pt.y> s2.pt.y);
    	}
    

      

    准备工作完成,开始测试

    代码

    static void testMySort()
    	{
    		ads_name ss;
    		//堆上创建过滤圆链表
    		resbuf *rbList=acutBuildList(RTDXF0,_T("CIRCLE"),RTNONE);		
    		acutPrintf(_T("
    请选择圆: "));
    		if (RTNORM != acedSSGet(NULL,NULL,NULL,rbList,ss))
    		{
    			//提前return退出,要释放链表.
    			acutRelRb(rbList);
    			acutPrintf(_T("
    未选择到有效对象!"));
    			return;
    		}
    		//释放链表
    		acutRelRb(rbList);
    		//高版本acedSSLength要求用Adesk::Int32
    		Adesk::Int32 nSSLength=0;
    		acedSSLength(ss,&nSSLength);
    		ads_name ent;
    		AcDbObjectId objId;
    		//创建ListPtEntId数组
    		ListPtEntIdArray listEnts;
    		for (Adesk::Int32 i=0;i<nSSLength;i++)
    		{
    			acedSSName(ss,i,ent);//此处无需错误处理.
    			acdbGetObjectId(objId,ent);//此处无需错误处理.
    			//使用ARX智能指针打开对象,在循环内的变量(作用域)的进入下一次循环会清空
    			AcDbObjectPointer<AcDbCircle> pCircle(objId,AcDb::kForRead);
    			if (Acad::eOk != pCircle.openStatus())
    			{
    				//跳过此次循环,进入下一次循环.
    				continue;
    			}
    			//创建ListPtEntId对象并赋值
    			ListPtEntId listEnt;
    			listEnt.pt=pCircle->center();
    			listEnt.objId=objId;
    			//添加到ListPtEntId数组
    			listEnts.append(listEnt);
    			if (0 == i)
    			{
    				//设置公差(容差)值
    				g_dTolerance=pCircle->radius();
    			}
    		}
    		//及时释放选择集
    		acedSSFree(ss);
    		//设置公差(容差)值
    		//g_dTolerance=100.0;
    		//执行std::sort排序
    		std::sort(listEnts.asArrayPtr(),listEnts.asArrayPtr()+listEnts.logicalLength(),mySortByX);
    		//验证排序后的结果
    		for (Adesk::Int32 i=0;i<listEnts.length();i++)
    		{
    			//同样使用ARX指针,尽管上个循环打开过,但是出了循环就会自动关闭,所以这里打开不会失败.
    			AcDbObjectPointer<AcDbCircle> pCircle(listEnts.at(i).objId,AcDb::kForWrite);
    			if (Acad::eOk != pCircle.openStatus())
    			{
    				continue;
    			}
    			//使用智能指针创建单行文本
    			AcDbObjectPointer<AcDbText> pText;
    			if (Acad::eOk!= pText.create())
    			{
    				continue;
    			}
    			//设置文字属性,按pt点居中显示,字高为半径的0.5倍
    			pText->setPosition(listEnts.at(i).pt);
    			pText->setHeight(pCircle->radius()*0.5);
    			pText->setHorizontalMode(AcDb::kTextMid);
    			pText->setVerticalMode(AcDb::kTextVertMid);
    			pText->setAlignmentPoint(listEnts.at(i).pt);
    			CString str;
    			str.Format(_T("%02d"),i+1);
    			pText->setTextString(str);
    			//添加到当前工作空间
    			PostToCurrentSpace(pText);
    			//前256个对象直接修改颜色,此处仅做演示.
    			if (i<256)
    			{
    				pCircle->setColorIndex(i+1);
    			}
    		}
    	}
    

      添加实体到当前空间函数

    	static Acad::ErrorStatus PostToCurrentSpace(AcDbEntity *pEnt)
    	{
    		AcDbDatabase *pDb=acdbHostApplicationServices()->workingDatabase();		
    		AcDbBlockTableRecordPointer pBlkRcd(pDb->currentSpaceId(),AcDb::kForWrite);
    		if (Acad::eOk != pBlkRcd.openStatus())
    		{
    			return pBlkRcd.openStatus();
    		}
    		return pBlkRcd->appendAcDbEntity(pEnt);		
    	}
    

      

    最终效果如图,

  • 相关阅读:
    性能测试的概念
    位运算和逻辑与运算
    09年~16年上午题题型分布
    复习建议
    软件评测师下午题笔记
    php 数据库 操作
    mysqli_query($conn, "set names utf8"); //**设置字符集*** 不设置插入数据库就是乱码
    iview admin template 基础模板架子
    iview-admin里面的 axios 给包装了一层数据 libs/axios.js 数据做了一层拦截
    mysql 如果没有密码 就不能远程连接
  • 原文地址:https://www.cnblogs.com/edata/p/12619219.html
Copyright © 2020-2023  润新知