找回密码
 立即注册

QQ登录

只需一步,快速开始

扫一扫,访问微社区

楼主: Love-Lisp

[研讨] 曲线选择集交点打断的源码

[复制链接]
 楼主| 发表于 2013-8-24 22:13:41 | 显示全部楼层
XDSoft 发表于 2013-8-24 22:02
看了下API的代码,里面多了次重复的选择集遍历到AcDbObjectIdArray数组,API代码为了考虑编程的方便和通 ...

深有同感!代码越通用,必然降低运行效率!对于非大量计算的代码,基本无所谓,无需考虑效率问题!对于需要大量计算的程序来说,还真不能为了考虑代码的简洁性,而损失了效率!



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

使用道具 举报

已领礼包: 145个

财富等级: 日进斗金

发表于 2013-8-24 22:21:10 | 显示全部楼层
Love-Lisp 发表于 2013-8-24 21:52
原先计算交点是nXn次计算,
for (int i=0,i < len,i++) //循环n次
{

另外,API考虑的参数多,还有一种自身打断,你的 i=0 第二次i=i+1, 就会落下自身对自身的交点的处理。就是你省下的那些次数。代码可以在综合考虑完善下算法。

点评

哦,XDRX_CURVE_INTERSECTBREAK函数对自己也进行了打断!但是发现XDRX_CURVE_INTERSECTBREAK 函数对于随便画的自交曲线,打断的结果毫无规律可循,在交点处的两条线只打断一条,多段线自身打断,有的每个节点间都打  详情 回复 发表于 2013-8-24 23:03
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

 楼主| 发表于 2013-8-24 23:03:02 | 显示全部楼层
XDSoft 发表于 2013-8-24 22:21
另外,API考虑的参数多,还有一种自身打断,你的 i=0 第二次i=i+1, 就会落下自身对自身的交点的处理。就 ...

哦,XDRX_CURVE_INTERSECTBREAK函数对自己也进行了打断!但是发现XDRX_CURVE_INTERSECTBREAK 函数对于随便画的自交曲线,打断的结果毫无规律可循,在交点处的两条线只打断一条,多段线自身打断,有的每个节点间都打断,但是有些节点间却不能打断!我觉得自身打断应该是在自交点处将曲线打断才对!

点评

自身打断处理的不是自交,API处理的是比如多段线,在每个顶点打断,但实体还是多段线。不改变实体类型(区别于EXPLODE) API函数已经优化了,下个版本提供xdrx_curve_intersectbreak测试, 打开新图出现对话框提  详情 回复 发表于 2013-8-25 00:30
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 145个

财富等级: 日进斗金

发表于 2013-8-25 00:30:54 | 显示全部楼层
Love-Lisp 发表于 2013-8-24 23:03
哦,XDRX_CURVE_INTERSECTBREAK函数对自己也进行了打断!但是发现XDRX_CURVE_INTERSECTBREAK 函数对于随 ...

自身打断处理的不是自交,API处理的是比如多段线,在每个顶点打断,但实体还是多段线。不改变实体类型(区别于EXPLODE)

API函数已经优化了,下个版本提供xdrx_curve_intersectbreak测试, 打开新图出现对话框提示的也解决了,谢谢你的测试和修改建议。
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 145个

财富等级: 日进斗金

发表于 2013-8-25 06:01:56 | 显示全部楼层
修改了代码,速度大大提高了。

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

使用道具 举报

已领礼包: 8612个

财富等级: 富甲天下

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

使用道具 举报

已领礼包: 593个

财富等级: 财运亨通

发表于 2013-8-26 18:31:24 | 显示全部楼层
仅Line构成的Net,没有调用 Command break 的spline,看来 Lisp 效率还可以接受{:soso_e100:}
命令: TT
选择对象: 指定对角点: 找到 1236 个
选择对象:
14.473
命令:
命令: U INTELLIZOOM '.ZOOM
命令: SSBRK
选择Line,ellipse,arc,circle,spline,lwpolyline,polyline.....
选择对象: 指定对角点: 找到 1236 个
选择对象:
共 1236 个实体排序中,请稍候.....
Ok, 共耗时35.526秒.
命令:
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

发表于 2013-11-27 23:00:12 | 显示全部楼层
本帖最后由 LoveArx 于 2016-11-27 13:00 编辑

[ 本帖最后由 LoveArx 于 2016-11-27 12:54 编辑 ]\n\n在楼主的代码基础上优化了一下,当1000*1000网格,即2002条图元相交,速度提升了差不多一半。代码如下:
  1. struct IntersectOnCurve
  2. {
  3.         AcGeDoubleArray IntersectParamat;
  4. };

  5. int doublecmp( const void *a , const void *b )
  6. {
  7. return *(double *)a > *(double *)b ? 1 : -1;
  8. }


  9. void WTUModifyEnt::IntersectBreakSS (ads_name ss,AcDbVoidPtrArray& curveSegments,ads_real rTol)
  10. {
  11.         Acad::ErrorStatus es;
  12.         ads_name e1;
  13.         AcGePoint3dArray nPoints;
  14.         AcGeTol tol;
  15.         tol.setEqualPoint(rTol);
  16.         tol.setEqualVector(rTol);
  17.         if (!(nPoints.isEmpty()))
  18.         {
  19.                 nPoints.setPhysicalLength(0);
  20.                 nPoints.setLogicalLength(0);
  21.         }
  22.         long len;
  23.         acedSSLength(ss,&len);
  24.         //实体个数小于两个,直接返回值
  25.         if (len < 2)
  26.         {
  27.                 if (len = 1)
  28.                 {
  29.                         AcDbEntity *pEnt;
  30.                         AcDbObjectId Id;
  31.                         acedSSName(ss,0,e1);
  32.                         acdbGetObjectId(Id,e1);
  33.                         es = acdbOpenObject(pEnt,Id,AcDb::kForRead);
  34.                         if (es != Acad::eOk)
  35.                         {
  36.                                 pEnt->close();

  37.                         }
  38.                         curveSegments.append(pEnt);
  39.                         pEnt->close();
  40.                 }
  41.                 return;
  42.         }
  43.         //将选择集实体转换到对象数组IdArray
  44.         AcDbObjectIdArray IdArray;
  45.         AcDbEntity *pEnt,*pEnt1;
  46.         AcDbObjectId Id,Id1;
  47.         AcDbCurve *pCurve,*pCurve1;
  48.         for (long i =0;i < len;i++)
  49.         {
  50.                 acedSSName(ss,i,e1);
  51.                 acdbGetObjectId(Id,e1);
  52.                 es = acdbOpenObject(pEnt,Id,AcDb::kForRead);
  53.                 if (es != Acad::eOk)
  54.                 {
  55.                         pEnt->close();

  56.                 }
  57.                 pCurve = AcDbCurve::cast(pEnt);
  58.                 if (pCurve == NULL)
  59.                 {
  60.                         pEnt->close();
  61.                         continue;
  62.                 }
  63.                 IdArray.append(Id);
  64.                 pEnt->close();
  65.         }
  66.         //曲线总个数
  67.         len = IdArray.length();

  68.         //创建曲线的IntersectOnCurve结构数组,每个元素保存对应曲线上的交点Param,以AcGeDoubleArray保存
  69.         IntersectOnCurve * intersectpt = new IntersectOnCurve[len];

  70.         //初始化intersectpt
  71.         for (long i = 0;i < len;i++)
  72.         {
  73.                 if (!(intersectpt.IntersectParamat.isEmpty()))
  74.                 {
  75.                         intersectpt.IntersectParamat.setPhysicalLength(0);
  76.                         intersectpt.IntersectParamat.setLogicalLength(0);
  77.                 }
  78.         }

  79.         for (long i = 0;i < len-1;i++)
  80.         {
  81.                 Id = IdArray.at(i);
  82.                 acdbOpenObject(pEnt,Id,AcDb::kForRead);
  83.                 pCurve = AcDbCurve::cast(pEnt);
  84.                 AcGePoint3d pstart0,pend0;
  85.                 pCurve->getStartPoint(pstart0);
  86.                 pCurve->getEndPoint(pend0);
  87.                 for (long j = i+1;j < len;j++)
  88.                 {
  89.                         Id1 = IdArray.at(j);
  90.                         acdbOpenObject(pEnt1,Id1,AcDb::kForRead);
  91.                         pCurve1 = AcDbCurve::cast(pEnt1);
  92.                         AcGePoint3dArray nPts;
  93.                         //计算交点
  94.                         pEnt->intersectWith(pEnt1,AcDb::kOnBothOperands,nPts);
  95.                         AcGePoint3d pstart1,pend1,pt;
  96.                         pCurve1->getStartPoint(pstart1);
  97.                         pCurve1->getEndPoint(pend1);      
  98.                         for (int m = 0;m < nPts.length();m++)
  99.                         {
  100.                                 pt = nPts[m];
  101.                                 if (!(pstart0.isEqualTo(pt,tol) || pend0.isEqualTo(pt,tol)))
  102.                                 {
  103.                                         //交点添加到第i条曲线上
  104.                                         double paramat;
  105.                                         pCurve->getParamAtPoint(pt,paramat);
  106.                                         intersectpt.IntersectParamat.append(paramat);
  107.                                 }        
  108.                                 if (!(pstart1.isEqualTo(pt,tol) || pend1.isEqualTo(pt,tol)))
  109.                                 {
  110.                                         //交点添加到第j条曲线上
  111.                                         //Pt3DArrays[j].append(pt);
  112.                                         double paramat;
  113.                                         pCurve1->getParamAtPoint(pt,paramat);
  114.                                         intersectpt[j].IntersectParamat.append(paramat);
  115.                                 }      
  116.                         }
  117.                         //判断pCurve1的端点是否在pCurve容差范围之内,添加到交点表第i条曲线上
  118.                         pCurve->getClosestPointTo(pstart1,pt);
  119.                         if (pstart1.isEqualTo(pt,tol) && !(pstart0.isEqualTo(pt,tol) || pend0.isEqualTo(pt,tol)))
  120.                         {
  121.                                 double paramat;
  122.                                 pCurve->getParamAtPoint(pt,paramat);
  123.                                 intersectpt.IntersectParamat.append(paramat);
  124.                         }
  125.                         pCurve->getClosestPointTo(pend1,pt);
  126.                         if (pend1.isEqualTo(pt,tol) && !(pstart0.isEqualTo(pt,tol) || pend0.isEqualTo(pt,tol)))
  127.                         {
  128.                                 double paramat;
  129.                                 pCurve->getParamAtPoint(pt,paramat);
  130.                                 intersectpt.IntersectParamat.append(paramat);
  131.                         }  
  132.                         //判断pCurve的端点是否在pCurve1容差范围之内,添加到交点表第j条曲线上
  133.                         pCurve1->getClosestPointTo(pstart0,pt);
  134.                         if (pstart0.isEqualTo(pt,tol) && !(pstart1.isEqualTo(pt,tol) || pend1.isEqualTo(pt,tol)))
  135.                         {
  136.                                 double paramat;
  137.                                 pCurve1->getParamAtPoint(pt,paramat);
  138.                                 intersectpt[j].IntersectParamat.append(paramat);
  139.                         }
  140.                         pCurve1->getClosestPointTo(pend0,pt);
  141.                         if (pend0.isEqualTo(pt,tol) && !(pstart1.isEqualTo(pt,tol) || pend1.isEqualTo(pt,tol)))
  142.                         {
  143.                                 double paramat;
  144.                                 pCurve1->getParamAtPoint(pt,paramat);
  145.                                 intersectpt[j].IntersectParamat.append(paramat);
  146.                         }  
  147.                         pEnt1->close();
  148.                 }
  149.                 pEnt->close();
  150.         }
  151.         for (long i = 0;i < len;i++)
  152.         {
  153.                 //取出第i条曲线pCurve
  154.                 Id = IdArray.at(i);
  155.                 acdbOpenObject(pEnt,Id,AcDb::kForRead);
  156.                 pCurve = AcDbCurve::cast(pEnt);

  157.                 //根据点intersectpt打断第i条曲线
  158.                 if (!(intersectpt.IntersectParamat.isEmpty()))
  159.                 {
  160.                         AcGeDoubleArray nPts;
  161.                         nPts.setPhysicalLength(0);
  162.                         nPts.setLogicalLength(0);
  163.                         long inptlen=intersectpt.IntersectParamat.length();
  164.                         double *intdouble=new double[inptlen];
  165.                         for (long j = 0;j < inptlen;j++)
  166.                         {
  167.                                 intdouble[j]=intersectpt.IntersectParamat.at(j);
  168.                         }
  169.                         qsort(intdouble,inptlen,sizeof(intdouble[0]),doublecmp);
  170.                         for (long i = 0;i < inptlen;i++)
  171.                         {
  172.                                 nPts.append(intdouble);
  173.                         }
  174.                         delete []intdouble;
  175.                         //len1打断曲线前curveSegments的长度
  176.                         long len1 = curveSegments.length();
  177.                         pCurve->upgradeOpen();
  178.                         //按参数表params打断曲线pCurve
  179.                         es = pCurve->getSplitCurves(nPts,curveSegments);
  180.                         //len2打断曲线后curveSegments的长度
  181.                         long len2 = curveSegments.length();

  182.                         if ((len2 - len1) > 1)/*生成了新的曲线*/
  183.                         {
  184.                                 //acutPrintf(_T("\n共生成直线 %d  条!"),(len2 - len1));
  185.                                 pCurve->erase();
  186.                                 pEnt->close();
  187.                                 for (int ii = len1; ii <len2; ii++)
  188.                                 {
  189.                                         AcDbEntity *pEntity = NULL;
  190.                                         pEntity = (AcDbEntity *)curveSegments[ii];
  191.                                         //将生成的曲线添加到数据库
  192.                                         WTUcreateEnt::PostToModelSpace(pEntity);
  193.                                 }

  194.                         }
  195.                         else /*没有生成新曲线*/
  196.                         {
  197.                                 pEnt->close();
  198.                                 AcDbEntity *pEnt1;
  199.                                 pEnt1  = (AcDbEntity *)curveSegments[(len2 - 1)];
  200.                                 delete(pEnt1);
  201.                                 curveSegments.setAt(len2 - 1,pCurve);
  202.                         }
  203.                 }
  204.                 else /*曲线没有交点,无需打断*/
  205.                 {      
  206.                         pEnt->close();
  207.                         curveSegments.append(pCurve);
  208.                 }

  209.         }
  210.         delete []intersectpt;
  211. }

点评

目前还是编译不通过,增加了[i]之后,编译正常,但使用时出来curveSegments.append(pEnt);此处的错误提示  发表于 2017-8-27 15:20
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 32个

财富等级: 招财进宝

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

使用道具 举报

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

使用道具 举报

发表于 2014-9-26 21:48:13 | 显示全部楼层
现在还看不到,过段时间才能看到,努力中
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

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

使用道具 举报

已领礼包: 7个

财富等级: 恭喜发财

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

使用道具 举报

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

使用道具 举报

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

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-9-28 10:20 , Processed in 0.364079 second(s), 61 queries , Gzip On.

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

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