找回密码
 立即注册

QQ登录

只需一步,快速开始

扫一扫,访问微社区

查看: 9777|回复: 7

[在线文档] 关于AcDbEntity::intersectWith()实体求交及将曲线实体AcDbCurve沿交点打断

[复制链接]
发表于 2015-7-12 17:52:47 | 显示全部楼层 |阅读模式

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

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

×
本帖最后由 panfanggui 于 2015-7-13 19:38 编辑

关于AcDbEntity::intersectWith()实体求交及将
曲线实体AcDbCurve沿交点打断

   Autocad实体求交均使用AcDbEntity::intersectWith()求交函数,该函数有两个版本,分别对应不同的情况。
一、           同一平面实体求交及曲线沿交点打断
位于同一平面的两实体求交,使用:
virtual Acad::ErrorStatus
intersectWith(
const AcDbEntity* pEnt,
AcDb::Intersect intType,
AcGePoint3dArray& points,
int thisGsMarker = 0,
int otherGsMarker = 0) const;

其中:
pEnt        为与使用该方法的“this”实体求交的实体   
intType              输入要求求交类型
points                输出求得的交点数组
thisGsMarker      Input GS marker of subentity of"this" entity that's involved in the intersection operation. Use the0 default if not applicable.
otherGsMarker  Input GS marker of subentity of the entitypointed to by pEnt that's involved in the intersection operation. Use the 0default if not applicable.
用途:
    找出pEnt实体和“this”实体边界框所有边的交点。
(It finds the intersections of the entitypointed to by pEnt and all the edges of the bounding box of this entity.)

1、当两实体均为曲线AcDbCurve实体派生类实体时,是曲线间的交点
2、当两实体中有块(AcDbBlockReference)、文字(AcDbText、AcDbMText)时,是曲线与他们边界框的交点,或边界框之间的交点
3、当曲线实体与填充图案(AcDbHatch)求交时,是曲线与组织图案的线段的交点,这点与曲线与块的交点不同
4、当填充图案与文字、块求交时,是组成图案的线段与文字、块的边界框的交点。

两个实体只要位于同一平面,均可以用该版本求交函数求得交点,这样求得曲线上的交点后,曲线均可以采用曲线AcDbCurve的方法:
virtual Acad::ErrorStatus
getSplitCurves(
const AcGePoint3dArray& points,
AcDbVoidPtrArray& curveSegments) const;进行打断。

但最好使用其另一版本:
virtual Acad::ErrorStatus
getSplitCurves(
const AcGeDoubleArray& params,
AcDbVoidPtrArray& curveSegments) const;

二、           不同平面二维实体求交
当二维多线段有高程、样条曲线有z坐标时,求他们与它不在同一平面其它实体的交点。由于他们不在同一平面上,需用求交的另一版本函数:
virtualAcad::ErrorStatus
intersectWith(
constAcDbEntity* pEnt,
AcDb::IntersectintType,
constAcGePlane& projPlane,
AcGePoint3dArray&points,
intthisGsMarker = 0,
intotherGsMarker = 0) const;
其中:
    projPlane     两个实体外观交点的投影平面
这个函数与上一个函数的区别:
这个函数把“this”实体和pEnt实体投影到projPlane平面上、找出交点,然后把交点投影回“this”实体上。这是与上一个函数的不同点,其它的相同。所有增加到points数组的点是在“this”实体上。投影按平行projPlane平面的法线矢量方向进行。
对于三维多线段,也能使用该函数求得交点,但交点不是在三维多线段上,因此不能按此求得的交点将三维多线段沿交点打断。
经测试下面两种使用方法均能得出交点,但要正确沿交点打断曲线,确定好“this”实体是很重要的。要打断的那条曲线就是“this”实体,也即需要使用被打断的曲线实体的求交函数来求交点。
1、将两实体投影到XY平面
    AcGePlaneplane;       //XY平面
AcGePoint3dArray intersectionPoints;
    pEnt1->intersectWith (pEnt2,AcDb::kOnBothOperands,plane,intersectionPoints);
此时,交点的z坐标就是曲线pEnt1的z坐标或标高。
2、将两实体投影到“this”实体所在平面或者投影到pEnt实体所在平面
    AcDb::Planarity flag;
    AcGePlane plane;
    AcGePoint3dArray intersectionPoints;
    Acad::ErrorStatus es;
    es=pEnt1->getPlane(plane,flag);   //获得实体pEnt1所在平面plane
// es=pEnt2->getPlane(plane,flag);   //获得实体pEnt2所在平面plane
pEnt1->intersectWith (pEnt2,AcDb::kOnBothOperands,plane,intersectionPoints);

交点的z坐标就是使用求交方法实体的z坐标或标高,也就是交点是在使用求交方法的曲线实体上的。

三、           三维多段线与其它实体的求交
为了正确求得三维多线段上的交点及沿其交点打断三维多线段,应采用下列方法:
1、获取pCur2曲线(“this”实体,需打断的三维多线段)在pCur1曲线所在平面的正射投影曲线projCrv
2、取得projCrv曲线上与pCur1曲线的交点
3、取得projCrv曲线上交点对应的参数化曲线的参数
4、依据投影曲线projCrv与原曲线pCur2参数相同,将投影面上的交点投影返回到原曲线pCur2上,取得pCur2曲线与pCur1曲线在pCur2曲线上的交点。
程序代码段:
    AcDb::Planarity flag;
    AcGePlane plane;
    AcDbCurve * projCrv,*pCur1,*pCur2;
    AcGePoint3dArray pnts, intersectionPoints;
    Acad::ErrorStatus es;
    es=pEnt1->getPlane(plane,flag);   //获得曲线pCur1所在平面plane
    if(es!=Acad::eOk)
    {
       acutPrintf  (_T("\ngetPlanefailed : es = %s"),acadErrorStatusText(es));
       return(RTERROR);
    }
       es=pCur2->getOrthoProjectedCurve(plane,projCrv);
       if (es!=Acad::eOk)
       {
           acutPrintf  (_T("\ngetOrthoProjectedCurve : es =%s"),acadErrorStatusText(es));
           return (RTERROR);
       }
       es=projCrv->intersectWith(pCur1,AcDb::kOnBothOperands,pnts);
       if(es!=Acad::eOk)
       {
           acutPrintf  (_T("\nintersectWith : es =%s"),acadErrorStatusText(es));
           return (RTERROR);
       }
       int len=pnts.length();
       double * param=new double[len];
       AcGePoint3d pt;
       for (int i=0;i<len;i++)
       {
           projCrv->getClosestPointTo(pnts,pt);
           projCrv->getParamAtPoint(pt,param);
       }
       for (int i=0;i<len;i++)
       {
           pCur2->getPointAtParam(param,pt);
           intersectionPoints.append(pt);
       }
四、两条z坐标均为非定值的样条曲线相交打断
   以下三种情况采用上述方法均不能求得交点,也就不能沿交点打断曲线。
    1、两条z坐标均为非定值的三维多线段相交打断
2、z坐标非定值的样条曲线与z坐标非定值的三维多线段相交打断
3、两条z坐标均为非定值的样条曲线相交打断

解决问题设想:
1、先求两条曲线在同一平面正射投影曲线projCrv
2、求两条正射投影曲线projCrv的交点
3、再将交点投影回到原曲线上得交点。
    经测试,在autocad2006下,能达到目的,但在cad2012下有时不能达到目的
    该部分代码可从上面的代码演变可得。
五、存在问题
目前根据求交、打断编制的任意多边形裁图程序的裁图效果还比较满意。但存在以下问题:
1、有时会出现极个别曲线不能裁断的情况,有的进行二次操作后可以剪断。这个别曲线有的用cad命名也无法剪断。不知何故?
2、当自相交曲线的交点正好位于剪切边界上时,只能打断曲线其中一边
3、该程序在打断前求交选择实体对象及打断后平移、旋转实体变换均是采用获取选择集的方式,因此要裁剪部分图形选择后必须位于屏幕可见区域内,否则就会出现**没有裁剪的情况,不知用何方法解决??
4、对于打断样条拟合的二维多线段在2006会出错,打断前需进行预处理,而在2012下没有问题,打断前不需预处理。

附上程序:cad2006版
任意多边形裁剪命令:brkcur
实体求交测试命令:curjd
两条曲线交点打断测试命令:ddcur

brkcur.zip

64.88 KB, 下载次数: 159, 下载积分: D豆 -1 , 活跃度 1

brkcur2012.zip

67.13 KB, 下载次数: 152, 下载积分: D豆 -1 , 活跃度 1

评分

参与人数 1D豆 +10 收起 理由
XDSoft + 10 很给力!经验;技术要点;资料分享奖!

查看全部评分

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

已领礼包: 264个

财富等级: 日进斗金

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

使用道具 举报

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

使用道具 举报

已领礼包: 1个

财富等级: 恭喜发财

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

使用道具 举报

发表于 2018-11-9 11:17:33 | 显示全部楼层
好厉害,正好碰到用二维的闭合多段线打断三维多段线的问题,给的思路很好
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

发表于 2020-5-21 15:45:28 | 显示全部楼层
好经典的思路!感谢楼主分享,但是有个问题大佬们有没有遇到过:在一些地理图纸中(图元坐标特大),用Insertsectwith函数求的交点,传递给打断函数进行打断时,会返回给定点不在曲线上的错误,大概率与误差有关,但是具体怎么处理误差,希望遇到过的大佬给点思路。
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 10个

财富等级: 恭喜发财

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

使用道具 举报

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

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-4-26 18:25 , Processed in 0.300322 second(s), 47 queries , Gzip On.

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

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