找回密码
 立即注册

QQ登录

只需一步,快速开始

扫一扫,访问微社区

查看: 807|回复: 8

[求助]:如何求PL线的自交点,并在自交点处把曲线打断

[复制链接]
发表于 2005-7-31 12:33:33 | 显示全部楼层 |阅读模式

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

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

×
各位高手帮忙
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
发表于 2005-7-31 17:19:34 | 显示全部楼层
//如何求PL线的自交点,并在自交点处把曲线打断(#include <DBPL.H>)
int PLineInterSelf()
{
        //选择实体
        ads_name ssName;
        struct resbuf eb;
        char strbuf[20];
        eb.restype = 0;                //实体类型
        strcpy(strbuf, "LWPOLYLINE");
        eb.resval.rstring = strbuf;
        eb.rbnext = NULL;
       
        ads_printf("\n 选择一条多义线<退出>:");
        ads_ssget(NULL, NULL, NULL, &eb, ssName);
        long ssLen = 0;
        ads_sslength(ssName, &ssLen);
       
        if(ssLen != 1)
        {
                ads_ssfree(ssName);
                return 0;
        }

        //获得顶点个数
        ads_name en;
        AcDbPolyline *pPLine = NULL;
        AcDbObjectId enId;
        int nCount = 0;

        ads_ssname(ssName, 0, en);
        acdbGetObjectId(enId, en);
        if (Acad::eOk == acdbOpenObject(pPLine, enId, AcDb::kForRead))
        {
                nCount = pPLine->numVerts();        //多义线顶点个数
               
                pPLine->close();        //关闭实体
        }
        if (nCount < 3)                        //小于三个顶点的不处理
        {
                ads_ssfree(ssName);
                return 0;
        }
        ads_ssfree(ssName);                //释放选择集

        //得到各个顶点坐标
        int i;
        float *x = new float[nCount];
        float *y = new float[nCount];
        AcGePoint2d pt;
        if (Acad::eOk == acdbOpenObject(pPLine, enId, AcDb::kForRead))
        {
                for (i=0; i<nCount; i++)
                {
                        pPLine->getPointAt(i, pt);
                        x = (float)pt.x;
                        y = (float)pt.y;
                }
               
                pPLine->close();        //关闭实体
        }

        //求交点
        AcGePoint3d LinePoint1, LinePoint2, LinePoint3;
        AcDbLine *pLine1 = NULL;
        AcDbLine *pLine2 = NULL;
        AcDbObjectIdArray LineIds;
        AcGePoint3dArray interPoint;       
        int j;
        float fErr = 1.0E-2f;
        //得到顶点连成的直线
        for (i=0; i<nCount-2; i++)
        {
                LinePoint1[X] = x;
                LinePoint1[Y] = y;
                LinePoint1[Z] = 0;
                LinePoint2[X] = x[i+1];
                LinePoint2[Y] = y[i+1];
                LinePoint2[Z] = 0;
                pLine1 = new AcDbLine(LinePoint1, LinePoint2);

                for (j=i+1; j<nCount-1; j++)
                {
                        LinePoint1[X] = x[j];
                        LinePoint1[Y] = y[j];
                        LinePoint1[Z] = 0;
                        LinePoint2[X] = x[j+1];
                        LinePoint2[Y] = y[j+1];
                        LinePoint2[Z] = 0;
                        pLine2 = new AcDbLine(LinePoint1, LinePoint2);       
                       
                        interPoint.setLogicalLength(0);                //清空数组
                        pLine2->intersectWith(pLine1, AcDb::kOnBothOperands, interPoint);
                        delete[] pLine2;
                        pLine2 = NULL;

                        int nCountInter = interPoint.length();
                        if (nCountInter > 0)
                        {
                                //当交点是直线的顶点时,剔除
                                if (fabs(interPoint[0].x - x[j]) < fErr &&
                                        fabs(interPoint[0].y - y[j]) < fErr )
                                {
                                        continue;
                                }
                                else
                                {
                                        ads_printf("\n****** x= %0.2f", interPoint[0].x);
                                        ads_printf("\n****** y= %0.2f", interPoint[0].y);
                                }
                        }               
                }
                delete[] pLine1;
                pLine1 = NULL;

        }
        delete[] x;
        x = NULL;
        delete[] y;
        y = NULL;

        //求直线交点
        int nCountLine = LineIds.length();
        if (nCountLine < 2)
        {
                return 0;               
        }
       
        return 1;
}

//编程思路:
1、选择实体
2、得到实体的各个顶点坐标
3、把各个相邻的顶点看作直线,依次求交点
4、把与顶点重合的交点剔除

//只做了求PL线的自交点,“并在自交点处把曲线打断”这句话我没理解。
//本人水平有限,调试了好半天。
//上面的代码,上传之后就把有些地方给自动改错了(不知道斑竹知道这个情况嘛,期望修改一下),所以我又加了个附件。txt格式的。
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

发表于 2005-8-1 11:25:51 | 显示全部楼层
对PL使用getSplitCurves函数把原来的线分段生成新线,删除原来的线,留下需要的,ARXDBG例子中有这个功能.
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

发表于 2005-8-1 14:50:12 | 显示全部楼层
这个程序是不是有点问题,
如果PL线上有弧线怎么办呢,
难道也取首尾点,构造一个直线求交点吗?????
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

发表于 2005-8-1 20:22:09 | 显示全部楼层
最初由 valuxlin 发布
[B]这个程序是不是有点问题,
如果PL线上有弧线怎么办呢,
难道也取首尾点,构造一个直线求交点吗????? [/B]


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

使用道具 举报

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

使用道具 举报

 楼主| 发表于 2005-8-2 17:43:27 | 显示全部楼层
谢谢了大家这么热情

我现在发现其实用getSplitCurves函数完全可以搞定。
我以前用了一个笨办法也实现了,大家可以看看.


BOOL CWsjs::GetPlAllInterPt(AcDbObjectId id,OUT std::set<double>& setParam)
{
        setParam.clear();
        AcDbObjectPointer<AcDbCurve> spCur(id,AcDb::kForRead);
        if(spCur.openStatus() != Acad::eOk)
        {
                RXASSERT(0);
                return FALSE;
        }
       
        if(AcDbLine::cast(spCur.object()) != NULL
                || AcDbArc::cast(spCur.object() ) != NULL  
                )
        {
                //对圆弧和直线不需要处理.
                return TRUE;
        }

        AcGePoint3dArray aryInstersPt;
        if(spCur->intersectWith(spCur.object(),AcDb::kOnBothOperands,AcGePlane::kXYPlane,aryInstersPt) != Acad::eOk)
        {
                return FALSE;
        }

        std::set<stuSearchData,less_data> setSearchData;
        if(!AryPtToSearchData(aryInstersPt,setSearchData,spCur.object()) )
                return FALSE;
       
        //离散曲线
        double dDis = 0.0;
        double dParam = 0.0;
        spCur->getStartParam(dParam);
        spCur->getDistAtParam(dParam,dDis);

        double dEndParam = 0.0;
        double dEndDis   = 0.0;
        spCur->getEndParam(dEndParam);
        spCur->getDistAtParam(dEndParam,dEndDis);

        double dStep = less_data::s_searchTol;
        for(;dDis < dEndDis + dStep;dDis += dStep)
        {
                double dT = dDis;
                if(dT > dEndDis)
                        dT = dEndDis;
               
                AcGePoint3d tmpPt;
                spCur->getPointAtDist(dT,tmpPt);

                std::set<stuSearchData,less_data>::iterator iter = setSearchData.find(tmpPt);
                if(iter != setSearchData.end() )
                {
                        double dTDis = dT;
                        spCur->getDistAtParam(iter->dParam,dTDis);
                       
                        GXBUG_DOUBLE(fabs(dTDis - dT));
                        if(fabs(dTDis - dT) > less_data::s_searchTol * 3.0)
                        {
                                std::set<double>::reverse_iterator revTmpIter = setParam.rbegin();
                                BOOL isNewPos = TRUE;
                                if(revTmpIter != setParam.rend() )
                                {
                                        if(fabs(*revTmpIter - dT) < less_data::s_searchTol * 3.0)
                                                isNewPos = FALSE;
                                }
                                if(isNewPos)
                                        setParam.insert(dT);
                        }
                        else
                        {
                                setParam.insert(dTDis);
                        }
                }
        }
        //把距离参数转抽换成Param;

        std::set<double>::iterator iter = setParam.begin();
        for(;iter != setParam.end();++iter)
        {
                double dParam = *iter;
                spCur->getParamAtDist(*iter,dParam);
                *iter = dParam;
        }

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

使用道具 举报

发表于 2005-8-3 16:52:52 | 显示全部楼层
今天发现一个问题,
使用getSplitCurves函数跟点的顺序有关
不同的顺序,结果会不一样!
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

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

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-9-22 20:31 , Processed in 0.295488 second(s), 46 queries , Gzip On.

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

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