zoukankan      html  css  js  c++  java
  • 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
  • 相关阅读:
    Bootstrapbutton组
    Hadoop
    图像手工画效果【QT+OpenCV】
    经常使用传感器协议1:CJ/T-188 水表协议解析1
    神经网络的初识
    用队列实现栈
    sas数据导入终极汇总-之中的一个
    SPOJ 题目705 New Distinct Substrings(后缀数组,求不同的子串个数)
    怎样选择正确的HTTP状态码
    最新最全的iOS手机支付总结
  • 原文地址:https://www.cnblogs.com/HelloQLQ/p/12752733.html
Copyright © 2011-2022 走看看