zoukankan      html  css  js  c++  java
  • ObjectArx圆角功能代码

    用了几次cad的圆角功能,想试着自己写一个。
    目前已经基本可用,但只能直线变圆角,圆弧变圆角需要另一套算法,就不写了。

    //直线变圆角
    bool PhdUtility::LineFillet(const AcDbObjectId& idLine1, const AcDbObjectId& idLine2, double dRadius, AcDbObjectId& idArc)
    {
    #pragma region 得到圆心
    //得到角平分线向量
    AcGeVector2d midVec;
    PhdGeometry::GetMidVectorOfLines(idLine1, idLine2, midVec);
    double dVecAngle = midVec.angle();
    double dAngle = 0;
    PhdGeometry::GetAngleOfLines(idLine1, idLine2, dAngle);
    double dDist = dRadius / std::sin(dAngle/2);
    AcGePoint3d ptInter;
    PhdGeometry::GetIntersectPoint(idLine1, idLine2, ptInter);
    AcGePoint3d ptCenter = PhdGeometry::PolarPoint(ptInter, dVecAngle, dDist);
    #pragma endregion

    #pragma region 得到垂足
    AcGePoint3d ptNew1 = PhdGeometry::GetClossedPoint(idLine1, ptCenter);
    AcGePoint3d ptNew2 = PhdGeometry::GetClossedPoint(idLine2, ptCenter);
    #pragma endregion

    #pragma region 设置直线点
    AcDbObjectPointer<AcDbLine> pLine1(idLine1,AcDb::kForWrite);
    if (Acad::eOk != pLine1.openStatus())
    return false;
    AcDbObjectPointer<AcDbLine> pLine2(idLine2, AcDb::kForWrite);
    if (Acad::eOk != pLine2.openStatus())
    return false;
    if (ptInter.distanceTo(pLine1->startPoint()) < ptInter.distanceTo(pLine1->endPoint()))
    {
    pLine1->setStartPoint(ptNew1);
    }
    else
    {
    pLine1->setEndPoint(ptNew1);
    }
    if (ptInter.distanceTo(pLine2->startPoint()) < ptInter.distanceTo(pLine2->endPoint()))
    {
    pLine2->setStartPoint(ptNew2);
    }
    else
    {
    pLine2->setEndPoint(ptNew2);
    }
    #pragma endregion

    #pragma region 绘制圆弧
    AcDbArc* pArc = NULL;
    PhdEntity::CreateArc3(ptCenter, ptNew1, ptNew2,pArc);
    ArxDbgUtils::addToCurrentSpaceAndClose(pArc);
    idArc = pArc->objectId();
    #pragma endregion

    return true;
    }

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    内部函数


    // Summary: 得到两条直线的角平分线向量
    bool PhdGeometry::GetMidVectorOfLines(const AcDbObjectId& idLine1, const AcDbObjectId& idLine2, AcGeVector2d& midVector)
    {
    AcDbObjectPointer<AcDbLine> pLine1(idLine1,AcDb::kForRead);
    if (Acad::eOk != pLine1.openStatus())
    return false;
    AcDbObjectPointer<AcDbLine> pLine2(idLine2, AcDb::kForRead);
    if (Acad::eOk != pLine2.openStatus())
    return false;
    AcGePoint3d ptInter;
    PhdGeometry::GetIntersectPoint(pLine1, pLine2, ptInter);
    AcGePoint3d ptEnd1, ptEnd2;
    if (!ptInter.isEqualTo(pLine1->startPoint()))
    {
    ptEnd1 = pLine1->startPoint();
    }
    else
    {
    ptEnd1 = pLine1->endPoint();
    }
    if (!ptInter.isEqualTo(pLine2->startPoint()))
    {
    ptEnd2 = pLine2->startPoint();
    }
    else
    {
    ptEnd2 = pLine2->endPoint();
    }
    AcGeVector2d vec1 = ptEnd1.convert2d(AcGePlane::kXYPlane) - ptInter.convert2d(AcGePlane::kXYPlane);
    AcGeVector2d vec2 = ptEnd2.convert2d(AcGePlane::kXYPlane) - ptInter.convert2d(AcGePlane::kXYPlane);
    midVector = vec1.normal() + vec2.normal();
    return true;
    }

    // Summary: 得到两条直线的夹角
    bool PhdGeometry::GetAngleOfLines(const AcDbObjectId& idLine1, const AcDbObjectId& idLine2, double& dAngle)
    {
    AcDbObjectPointer<AcDbLine> pLine1(idLine1,AcDb::kForRead);
    if (Acad::eOk != pLine1.openStatus())
    return false;
    AcDbObjectPointer<AcDbLine> pLine2(idLine2, AcDb::kForRead);
    if (Acad::eOk != pLine2.openStatus())
    return false;
    AcGePoint3d ptInter;
    PhdGeometry::GetIntersectPoint(pLine1, pLine2, ptInter);
    AcGePoint3d ptEnd1, ptEnd2;
    if (!ptInter.isEqualTo(pLine1->startPoint()))
    {
    ptEnd1 = pLine1->startPoint();
    }
    else
    {
    ptEnd1 = pLine1->endPoint();
    }
    if (!ptInter.isEqualTo(pLine2->startPoint()))
    {
    ptEnd2 = pLine2->startPoint();
    }
    else
    {
    ptEnd2 = pLine2->endPoint();
    }
    AcGeVector2d vec1 = ptEnd1.convert2d(AcGePlane::kXYPlane) - ptInter.convert2d(AcGePlane::kXYPlane);
    AcGeVector2d vec2 = ptEnd2.convert2d(AcGePlane::kXYPlane) - ptInter.convert2d(AcGePlane::kXYPlane);
    dAngle = vec1.angleTo(vec2);
    return true;
    }

    // Summary: 得到交点坐标
    bool PhdGeometry::GetIntersectPoint(const AcDbObjectId& idLine1, const AcDbObjectId& idLine2, AcGePoint3d& ptIntersect)
    {
    AcDbObjectPointer<AcDbLine> pLine1(idLine1,AcDb::kForRead);
    if (Acad::eOk != pLine1.openStatus())
    return false;
    AcDbObjectPointer<AcDbLine> pLine2(idLine2, AcDb::kForRead);
    if (Acad::eOk != pLine2.openStatus())
    return false;
    AcGeLine2d geLine1(pLine1->startPoint().convert2d(AcGePlane::kXYPlane), pLine1->endPoint().convert2d(AcGePlane::kXYPlane));
    AcGeLine2d geLine2(pLine2->startPoint().convert2d(AcGePlane::kXYPlane), pLine2->endPoint().convert2d(AcGePlane::kXYPlane));
    AcGePoint2d pt2d;
    bool bRet = geLine1.intersectWith(geLine2, pt2d);
    if (!bRet)
    return false;
    ptIntersect = AcGePoint3d(pt2d.x, pt2d.y, 0);
    return true;
    }

    // Summary: 极坐标求点
    AcGePoint3d PhdGeometry::PolarPoint(const AcGePoint3d& pt, double angle, double distance)
    {
    ads_point ptForm, ptTo;
    ptForm[X] = pt.x;
    ptForm[Y] = pt.y;
    ptForm[Z] = pt.z;

    acutPolar(ptForm, angle, distance, ptTo);
    return asPnt3d(ptTo);
    }

    // Summary: 得到直线上距离该点最近的点
    AcGePoint3d PhdGeometry::GetClossedPoint(const AcDbObjectId& idCurve, const AcGePoint3d& pt)
    {
    AcDbObjectPointer<AcDbCurve> pCurve(idCurve,AcDb::kForRead);
    if (Acad::eOk != pCurve.openStatus())
    return AcGePoint3d::kOrigin;
    AcGePoint3d ptOnCurve;
    pCurve->getClosestPointTo(pt, ptOnCurve);
    return ptOnCurve;
    }

    // Summary: 圆心和起始点和终止点绘制圆弧(不知道谁是起始点和终止点)
    bool PhdEntity::CreateArc3(const AcGePoint3d& ptCenter, const AcGePoint3d& pt1, const AcGePoint3d& pt2, AcDbArc*& pArc)
    {
    // 计算半径;
    double radius = ptCenter.distanceTo(pt1);
    // 计算起始和终止角度;
    AcGeVector2d vecStart(pt1.x - ptCenter.x, pt1.y - ptCenter.y);
    AcGeVector2d vecEnd(pt2.x - ptCenter.x, pt2.y - ptCenter.y);
    double startAngle = vecStart.angle();
    double endAngle = vecEnd.angle();
    double dBulge = PhdGeometry::GetArcBulge(startAngle, endAngle);
    if (0 > dBulge)
    {
    vecStart = AcGeVector2d(pt2.x - ptCenter.x, pt2.y - ptCenter.y);
    vecEnd = AcGeVector2d(pt1.x - ptCenter.x, pt1.y - ptCenter.y);
    startAngle = vecStart.angle();
    endAngle = vecEnd.angle();
    dBulge = PhdGeometry::GetArcBulge(startAngle, endAngle);
    if (0 > dBulge)
    return false;
    }
    pArc = new AcDbArc(ptCenter, radius, startAngle, endAngle);

    return true;
    }

    //得到圆弧凸度
    double PhdUtility::GetArcBulge(double dAngleStart, double dAngleEnd)
    {
    double dAlfa = dAngleEnd - dAngleStart;

    if (dAlfa < 0.0)//如果终点角度小于起点角度;
    {
    dAlfa = 2 * (atan(1.0) * 4) + dAlfa;
    }
    double dBulge = 0.0;
    dBulge = tan((dAlfa) / 4.0);

    return dBulge;
    }
    ————————————————
    版权声明:本文为CSDN博主「A彡安静氵」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
    原文链接:https://blog.csdn.net/phd17621680432/article/details/91848419

  • 相关阅读:
    ffmpeg mp4 视频输出为 aac 的命令
    git操作远程分支
    Linux (openSUSE 15.3 ) server ssh 可以使用,sftp无法使用
    小小思考题
    Linux 命令介绍
    2021 年 如何使用VMware 安装 ubuntu 7.04 虚拟机, 配置 apt 源
    Linux 下 命令行 使用浏览器
    oracle.cmd
    Sqlcmd
    vue eslint 配置使用
  • 原文地址:https://www.cnblogs.com/mjgw/p/12348077.html
Copyright © 2011-2022 走看看