zoukankan      html  css  js  c++  java
  • objectarx 按比例分割面积

    测试结果:这个是按0.1,0.1,0.1,0.3,0.4的比例划分的。

    插件描述:这个插件主要是选择一个多段线poly,设置poly的close属性为true,在poly任意一侧画一条长线line(line画的时候不能与poly相交),找到line的垂直向量p'yXl,这个pyXl是要往与poly能相交的方向。在找到这个line与poly相切的时候。然后取每次平移的步进值bujin,因为这个poly的总面积有大有小,所以我是取总面积totaArea/2000在开方,如果这个bujin<=1,则直接取1,这样对于面积很大的poly也不需要平移很多次。然后就是利用acedTraceBoundary函数来获取平移后的
    切线与poly形成的封闭多段线pl,求这个pl的面积是否大与按比例分割后的面积。

    需要注意的地方:在使用acedTraceBoundary的时候,必须确认poly和平移的切线都是close掉的,不然无法求出pl。如果没有acedTraceBoundary函数,可以这样:

    //ads_point pt = { seedPoint.x,seedPoint.y,seedPoint.z };
        //acedCommandS(RTSTR, L"-boundary", RTPOINT, pt, RTSTR, L"", RTNONE);
        //acdbEntLast(pent);
        ////acedRedraw(pent, 3);
        //AcDbObjectId eId;
    
        //acdbGetObjectId(eId, pent);
    
        //AcDbPolyline * pEnt = NULL;
    
        //ErrorStatus es = acdbOpenObject(pEnt, eId, AcDb::OpenMode::kForWrite);

    来获得封闭的多段线,然后在求面积。

    下面给出详细代码:
    求pyXl:

    AcGeVector3d CAreaFenGe::GetDirection()
    {
        //l2pt和l1pt是在poly侧边画的线的端点
        AcGeVector3d lineDirc = l2Pt - l1Pt;
        AcGeVector3d lineDirc2 = l2Pt - l1Pt;
    
        AcGePoint3d centerPt((l2Pt.x + l1Pt.x) / 2, (l2Pt.y + l1Pt.y) / 2, 0);
        AcGePoint3d ptCloset;
    
        poly->getClosestPointTo(centerPt, ptCloset, false);
    
        AcDbLine *line1 = AcDbLine::cast(line->clone());
        AcDbLine *line2 = AcDbLine::cast(line->clone());
        double len = ptCloset.distanceTo(centerPt);
    
        AcGeVector3d pyXl1 = lineDirc.rotateBy(-1 * CMathUtil::PI() / 2, AcGeVector3d::kZAxis);
        AcGeVector3d pyXl2 = lineDirc2.rotateBy(CMathUtil::PI() / 2, AcGeVector3d::kZAxis);
    
        line1->transformBy(AcGeMatrix3d::translation(pyXl1.normal()*len*1.5));
        line2->transformBy(AcGeMatrix3d::translation(pyXl2.normal()*len*1.5));
        AcGePoint3dArray p3dArr1, p3dArr2;
    
        poly->intersectWith(line1, AcDb::Intersect::kExtendArg, p3dArr1, 0, 0);
        poly->intersectWith(line2, AcDb::Intersect::kExtendArg, p3dArr2, 0, 0);
    
        if (p3dArr1.length() > 0) {        
            pyXl = pyXl1;    
        }
        else if(p3dArr2.length()>0){        
            pyXl = pyXl2;
        }
        else {
            pyXl = AcGeVector3d(3, -1, 0);//这个可以注释掉
        }
        delete line1;
        line1 = NULL;
        delete line2;
        line2 = NULL;
    
        return pyXl;
    }
    View Code

    获得切线:

    //得到切线
    AcGePoint3d CAreaFenGe::GetQieDian(AcDbLine * &line1)
    {
    
        line1 = new AcDbLine(l1Pt, l2Pt);
    
        AcGePoint3dArray ptArr;
    
        while (ptArr.length() < 1) {
    
            poly->intersectWith(line1, AcDb::Intersect::kOnBothOperands, ptArr, 0, 0);
    
            line1->transformBy(AcGeMatrix3d::translation(pyXl.normal() * 1));
    
        }
        poly->close();
    
        if (ptArr.length() > 0)
            return ptArr[0];
        else
            return AcGePoint3d::kOrigin;
    
    }
    View Code

    得到面积:

    bool  CAreaFenGe::GetPyPolyline(AcGePoint3d seedPoint, double & a)
    {
    
        AcDbVoidPtrArray ptrArr;
        ErrorStatus es = acedTraceBoundary(seedPoint, false, ptrArr);
    
        if (es != Acad::eOk) {
            acutPrintf(L"
    boundary=%d", es);
            return false;
        }
    
        AcDbPolyline * pl = NULL;
        pl = (AcDbPolyline*)ptrArr[0];
    
        pl->setColorIndex(1);
    
        pl->getArea(a);
    
        pl->erase();
        pl->close();
        pl = NULL;
        return true;
    
    }

    主要步骤:

    void CAreaFenGe::Command()
    {
    
        ErrorStatus es;
        AcDbLine * lQieXian = NULL;
        AcGePoint3d ptQieDian = GetQieDian(lQieXian);
    
        acutPrintf(L"
    ptQieDian=[%.2f,%.2f,%.2f]", ptQieDian.x, ptQieDian.y, ptQieDian.z);
    
        ptQieDian=ptQieDian.transformBy(AcGeMatrix3d::translation(pyXl.normal() * 5));
        acutPrintf(L"
    ptQieDian2=[%.2f,%.2f,%.2f]", ptQieDian.x, ptQieDian.y, ptQieDian.z);
    
        if (ptQieDian.x == 0 && ptQieDian.y == 0) {
            return;
        }
        double bujin = sqrt(totalArea * 1 / 2000);
    
        if (bujin <= 1) {
            bujin = 1;
        }
    
        AcDbObjectId qxId;
        lQieXian->transformBy(AcGeMatrix3d::translation(pyXl.normal() * bujin*3));
    
    
        es = acdbOpenObject(poly, plId, AcDb::kForRead);
    
        AcGePoint3dArray ptJdArr;
    
        poly->intersectWith(lQieXian, AcDb::Intersect::kOnBothOperands, ptJdArr, 0, 0);
    
    
        if (ptJdArr.length() >= 2) {
    
            ptQieDian=AcGePoint3d((ptJdArr[0].x+ ptJdArr[1].x)/2, (ptJdArr[0].y + ptJdArr[1].y) / 2,0);
    
            ptQieDian= ptQieDian.transformBy(AcGeMatrix3d::translation(pyXl.normal() * -bujin*1.5));
    
        }
        poly->close();
    
    
        qxId = CDwgDataBaseUtil::PostToModelSpace(lQieXian);
    
        lQieXian->close();
    
        lQieXian = NULL;
    
        //AcDbPolyline * ptPy = new AcDbPolyline();
    
        //ptPy->setColorIndex(5);
    
        //AcDbObjectId ptId;
    
        AcGePoint3dArray ptJdArr2;
    
    
        for (int i = 0; i < (int)vecArea.size(); i++)
        {
    
    
            AcGePoint3d ptCopyQd = ptQieDian;
    
            double a = 0.0;
            
            while (a < vecArea[i]) {
    
                bool flag = GetPyPolyline(ptQieDian, a);
    
                if (!flag) {
                    return;
                }
                es = acdbOpenObject(lQieXian, qxId, AcDb::kForWrite);
                lQieXian->transformBy(AcGeMatrix3d::translation(pyXl.normal() * bujin));
    
                ptJdArr2.removeAll();
    
                es = acdbOpenObject(poly, plId, AcDb::kForRead);
                poly->intersectWith(lQieXian, AcDb::Intersect::kExtendArg, ptJdArr2, 0, 0);
    
                poly->close();
    
                if (ptJdArr2.length() < 1) {
    
                    lQieXian->close();
                    break;
                    
                }
    
    
                lQieXian->close();
    
            }
    
            acdbOpenObject(lQieXian, qxId, AcDb::kForWrite);
    
            es = acdbOpenObject(poly, plId, AcDb::kForRead);
    
             ptJdArr.removeAll();
    
            poly->intersectWith(lQieXian, AcDb::Intersect::kExtendArg, ptJdArr, 0, 0);
    
            AcGePoint3d preCenter;
            if (ptJdArr.length() >= 2) {
    
                AcDbLine* lFg = new AcDbLine(ptJdArr[0], ptJdArr[1]);
    
                preCenter = AcGePoint3d((ptJdArr[0].x + ptJdArr[1].x) / 2, (ptJdArr[0].y + ptJdArr[1].y) / 2, 0);
                lFg->setColorIndex(2);
    
                CDwgDataBaseUtil::PostToModelSpace(lFg);
    
                lFg->close();
    
            }
            else {
    
                poly->close();
                lQieXian->erase();
                lQieXian->close();
                lQieXian = NULL;
                //ptId = CDwgDataBaseUtil::PostToModelSpace(ptPy);
                return;
    
            }
        
            poly->close();
    
            AcDbPolyline *pCopyQx = (AcDbPolyline*)lQieXian->clone();
    
            pCopyQx->transformBy(AcGeMatrix3d::translation(pyXl.normal() *bujin));
    
            if (i != (int)vecArea.size() - 1) {
    
    
                es = acdbOpenObject(poly, plId, AcDb::kForRead);
    
                ptJdArr.removeAll();
    
                poly->intersectWith(pCopyQx, AcDb::Intersect::kExtendArg, ptJdArr, 0, 0);
    
                if (ptJdArr.length() >= 2) {
                    ptQieDian = AcGePoint3d((ptJdArr[0].x + ptJdArr[1].x) / 2, (ptJdArr[0].y + ptJdArr[1].y) / 2, 0);
    
                    ptQieDian = AcGePoint3d((preCenter.x + ptQieDian.x) / 2, (preCenter.y + ptQieDian.y) / 2, 0);
    
                }
                qxId = CDwgDataBaseUtil::PostToModelSpace(pCopyQx);
    
                pCopyQx->close();
                poly->close();
                pCopyQx = NULL;
            }
            lQieXian->erase();
            lQieXian->close();
            lQieXian = NULL;
    
            //当运行到最后一个面积时,就不复制了
            if (i == (int)vecArea.size() - 1) {
    
                delete pCopyQx;
                pCopyQx = NULL;
    
                break;
            }
        }
    
        /*if (ptId.isNull()) {
            ptId = CDwgDataBaseUtil::PostToModelSpace(ptPy);
            ptPy->close();
        }*/
    }

    构造函数:

    CAreaFenGe::CAreaFenGe(ACHAR *fenGeStr, AcDbPolyline *&p, AcDbLine *&l)
    {
        
        vector<CString> vec;
    
        CStringUtil::Split(W2T(fenGeStr), L",", vec, false);
    
        for (int i = 0; i < (int)vec.size(); i++)
        {
            vecFenGe.push_back(_wtof(vec.at(i)));
        }
        this->poly = p;
        this->line = l;
    
        l1Pt = l->startPoint();
        l2Pt = l->endPoint();
    
        if (poly->isClosed() == false) {
            poly->setClosed(true);
        }
    
        poly->getArea(totalArea);
    
        for (int i = 0; i < (int)vecFenGe.size(); i++)
        {
            vecArea.push_back(totalArea*vecFenGe.at(i));
            acutPrintf(L"%.2f", vecArea[i]);
        }
        GetDirection();
        plId = poly->objectId();
    }
    View Code
  • 相关阅读:
    CreateDatabase is not supported by the provider
    SQLServer 查看耗时较多的SQL语句(转)
    Unity下调试ToLua(基于IDEA和VSCode)
    《Javascript高级程序设计》读书笔记——函数与闭包
    《Javascript高级程序设计》读书笔记——继承与原型链
    《Javascript高级程序设计》读书笔记——构造函数与原型
    客户端地图内寻路总结与优化
    《程序员的自我修养》读书笔记 第二章 编译和链接
    客户端GUI结构学习总结
    关于浏览器的页面渲染
  • 原文地址:https://www.cnblogs.com/HelloQLQ/p/12228308.html
Copyright © 2011-2022 走看看