Fork me on GitHub

objectarx 天正的墙转梁线

黄色的线是天正建筑2014画出来的墙炸开后的样子,炸开后全是AcDbLine。可以看到这个黄色的线在拐弯处,交叉处会出现多余的小线段,并且是不连续的,或者是超出了缺口,想要把它转变成梁就需要考虑这些因素。

我的思路是这样的,第一步 过滤小于等于墙厚度的直线,这样多余的直线就会消失,之后保存剩下的线段到一个vector集合中。

for (int i = 0; i < ids.length(); i++)
        {
            AcDbLine * l = NULL;

            if (acdbOpenObject(l, ids[i], AcDb::kForWrite) == Acad::eOk) {

                double len = 0;
                l->getDistAtPoint(l->endPoint(), len)
    //根据要求有三种数值的墙厚度
                if (len <queKou||len<queKou2||len<quekou3) {
                    l->erase();
                    l->close();
                    l = NULL;
                }
                else
                {
                    vecLines.push_back(l);
                }
            }
        }
View Code

第二步,把所有缺口封闭起来形成类似“#”这样的缺口,我采用的办法是,遍历直线集合,两两相交,如果有交点就延长至交点处,这里有个限制,那就是从线的端点到延长到交点的长度不超过1.5*quekou值并且交点确实是在延长线上而不是在直线的两个端点之间。

for (int ww = 0; ww < (int)vecLines.size(); ww++)
        {
            AcDbLine * l1 = vecLines[ww];
            for (int j = ww + 1; j < (int)vecLines.size(); j++)
            {
                AcDbLine *l2 = vecLines[j];

                l1->intersectWith(l2, AcDb::kOnBothOperands, temp1, 0, 0);

                if (1 == temp1.length()) {

                    temp1.removeAll();

                }
                else {
                    l1->intersectWith(l2, AcDb::kExtendBoth, temp2, 0, 0);
                
                    if (temp2.length() > 0) {
                        ExtendLine(l1, temp2[0]);
                        ExtendLine(l2, temp2[0]);
                        temp2.removeAll();
                    }
                }
            }
        }
View Code
static void ExtendLine(AcDbLine * l1, const  AcGePoint3d & pt) {
        AcGePoint3d pt11 = l1->startPoint();
        AcGePoint3d pt12 = l1->endPoint();
        double disO = pt11.distanceTo(pt12);

        double dis1 = pt11.distanceTo(pt);
        double dis2 = pt12.distanceTo(pt);

        double max = (dis2 > dis1 ? dis2 : dis1);

        if (max > disO + 1.5*(queKou + queKou2 + quekou3) / 3 || max < disO) {

            return;
        }
        else {

            if (max==dis2) {

                l1->setStartPoint(pt);

            }
            else {
                l1->setEndPoint(pt);
            }

        }
    }
View Code

第三步削减类似“#”的口子,让它们变成类似互通的路口,我采取的方法是遍历两两相交,判断交点是否在线的两个端点之间,如果是,则进行消减,改变端点。

//削减
        for (int ww = 0; ww < (int)vecLines.size(); ww++)
        {
            AcDbLine * l1 = vecLines[ww];

            for (int j = ww + 1; j < (int)vecLines.size(); j++)
            {
                AcDbLine *l2 = vecLines[j];
                //l1->intersectWith(l2, AcDb::kExtendBoth, temp2, 0, 0);
                l1->intersectWith(l2, AcDb::kOnBothOperands, temp1, 0, 0);
                
                if (1 == temp1.length()) {
                    
                    CutLine(l1, temp1[0]);            
                    CutLine(l2, temp1[0]);
                    temp1.removeAll();
                }
            }
        }
View Code
static void CutLine(AcDbLine * l1, const  AcGePoint3d & pt) {
        AcGePoint3d pt11 = l1->startPoint();
        AcGePoint3d pt12 = l1->endPoint();
        double disO = pt11.distanceTo(pt12);

        double dis1 = pt11.distanceTo(pt);
        double dis2 = pt12.distanceTo(pt);

        if (disO > dis1&&disO > dis2) {

            if (dis1 <= (queKou + queKou2 + quekou3)/3&&dis2 <= (queKou + queKou2 + quekou3) / 3) {

                return;
            
            }
            else {

                if (dis1 < dis2) {
                    l1->setStartPoint(pt);
                }
                else {
                    l1->setEndPoint(pt);
                }
            }
        }
    }
View Code

第四步,在第三步的时候会把边界的路口的线也给删了,所以就要补充边界缺口。这时剩下的缺口有个特点,那就是缺口对应的两条线是不会有交点的,利用这个特点就能解决问题。我是在交点处画一个圆,与圆相交的线构成集合,然后把这个集合中部任何线相交的直线找出来,进行延长相交,补充缺口。

//補充
        temp1.removeAll();
        temp2.removeAll();
        AcGePoint3dArray ptArrAll;
        ptArrAll.append(AcGePoint3d::kOrigin);
        ptArrAll.removeAll();

        for (int i = 0; i < (int)vecLines.size(); i++)
        {
            AcDbLine * l1 = vecLines[i];

            ptArrAll.append(l1->startPoint());
            ptArrAll.append(l1->endPoint());


        }

        //acutPrintf(L"prePt=%d", ptArrAll.length());
        double r = (queKou + queKou2 + quekou3) / 3*2;
        for (int i=0;i<ptArrAll.length();i++)
        {
            AcGePoint3d ptCenter=ptArrAll[i];

            AcDbCircle *cir = new AcDbCircle(ptCenter, AcGeVector3d::kZAxis, r);

            for (int j = i+1; j < ptArrAll.length(); j++) {

                AcGePoint3d pt2 = ptArrAll[j];

                double dis = pt2.distanceTo(ptCenter);

                if (dis <= r) {

                    ptArrAll.removeAt(j);

                }

            }
            delete cir;
            cir = NULL;
        }
        //acutPrintf(L"afterPt=%d", ptArrAll.length());

        for (int i = 0; i < ptArrAll.length(); i++)
        {
            AcGePoint3d ptCenter = ptArrAll[i];

            AcDbCircle *cir = new AcDbCircle(ptCenter, AcGeVector3d::kZAxis, r);
            vector<AcDbLine*>vecLL;
            for (int ww = 0; ww < (int)vecLines.size(); ww++)
            {

                AcDbLine * l1 = vecLines[ww];

                l1->intersectWith(cir, AcDb::kOnBothOperands, temp1, 0, 0);

                if (temp1.length() > 0) {

                    vecLL.push_back(l1);
                    temp1.removeAll();

                }

            }

            delete cir;
            cir = NULL;

            AcGeIntArray intArr;

            for (int m = 0; m < (int)vecLL.size(); m++)
            {
                AcDbLine * lT1 = vecLL[m];

                for (int s = 0; s < (int)vecLL.size(); s++)
                {
                    AcDbLine * lT2 = vecLL[s];

                    lT1->intersectWith(lT2, AcDb::kOnBothOperands, temp2, 0, 0);

                    if (temp2.length() > 0) {

                        intArr.append(m);
                        intArr.append(s);

                        temp2.removeAll();


                    }

                }

            }

            for (int m = 0; m < (int)vecLL.size(); m++)
            {
                if (intArr.contains(m))
                {
                    continue;
                }

                AcDbLine * lT1 = vecLL[m];

                for (int s = 0; s < (int)vecLL.size() ; s++)
                {
                    if (intArr.contains(s)) {

                        continue;
                    }

                    AcDbLine * lT2 = vecLL[s];


                    lT1->intersectWith(lT2, AcDb::kExtendBoth, temp2, 0, 0);
                    //ptNJdAll.append(temp2[0]);
                    if (temp2.length() > 0) {
                        AcGePoint3d pt11 = lT1->startPoint();
                        AcGePoint3d pt12 = lT1->endPoint();
                        double disO = pt11.distanceTo(pt12);

                        double dis1 = pt11.distanceTo(temp2[0]);
                        double dis2 = pt12.distanceTo(temp2[0]);

                        double max1 = (dis2 > dis1 ? dis2 : dis1);

                        AcGePoint3d pt21 = lT2->startPoint();
                        AcGePoint3d pt22 = lT2->endPoint();
                        double disO2 = pt21.distanceTo(pt22);

                        double dis21 = pt21.distanceTo(temp2[0]);
                        double dis22 = pt22.distanceTo(temp2[0]);

                        double max21 = (dis22 > dis21 ? dis22 : dis21);

                        if (max1 < disO + 0.5*(queKou + queKou2 + quekou3))
                        {
                            if (max1 == dis2) {

                                lT1->setStartPoint(temp2[0]);
                            }
                            else {
                                lT1->setEndPoint(temp2[0]);
                            }
                        }
                        if (max21 < disO2 + 0.5*(queKou + queKou2 + quekou3)) {
                            if (max21 == dis22) {

                                lT2->setStartPoint(temp2[0]);
                            }
                            else {
                                lT2->setEndPoint(temp2[0]);
                            }
                        }

                        temp2.removeAll();
                    }

                }
            }
            intArr.removeAll();

            vecLL.clear();
        }
View Code

最后在关闭实体

for (int i = 0; i < (int)vecLines.size(); i++)
        {

            vecLines[i]->setColorIndex(1);

            vecLines[i]->close();

        }
View Code

 

posted @ 2020-04-22 16:04  HelloLLLLL  阅读(691)  评论(0编辑  收藏  举报