• 样条曲线转换为多段线


     

    样条曲线拟合

    //定义PI
    #ifndef PI
    #define PI 4*atan(1.0)//提高pi的精度
    #endif
    bool getSplineSamplePoints(AcDbSpline *&spline, AcGePoint3dArray &pnts)
    {
    assert(spline != NULL);
    AcGePoint3d orgPt;
    spline->getStartPoint(orgPt);
    pnts.append(orgPt);
    double dStartParam=0.0;
    spline->getStartParam(dStartParam);
    double dEntParam=0.0;
    spline->getEndParam(dEntParam);
    double dDist=0.0;
    spline->getDistAtParam(dEntParam,dDist);
    int nNum=(int)dDist/0.005;
    if(nNum<25)
    {
    nNum=25;
    }

    if(nNum>10000)

    {

    nNum=10000;

    }
    for(int i=0;i<nNum;i++)
    {
    double dTmpParam=0.0;
    spline->getParamAtDist(dDist*(i+1)/nNum,dTmpParam);
    spline->getPointAtParam(dTmpParam,orgPt);
    pnts.append(orgPt);
    }
    return pnts.logicalLength()>2;
    }
    AcGePoint2d convert3dPointTo2d(AcGePoint3d pt)
    {
    AcGePoint2d pm;
    pm.set(pt.x,pt.y);
    return pm;
    }
    //获取三个点构成的夹角
    double GetIntersectionDngle(AcGePoint2d pt1,AcGePoint2d pt2,AcGePoint2d pt3)
    {
    AcGeVector2d vt1=pt1-pt2;
    AcGeVector2d vt2=pt3-pt2;
    return vt1.angleTo(vt2);
    }
    //获取三个点构成的夹角
    double GetIntersectionDngle(AcGePoint3d pt1,AcGePoint3d pt2,AcGePoint3d pt3)
    {
    return GetIntersectionDngle(convert3dPointTo2d(pt1),convert3dPointTo2d(pt2),convert3dPointTo2d(pt3));
    }
    //删除构成直线的三个点中间的点
    //dMinAngle,构成的夹角最小值,默认为0.5度
    void RemovePointBetweenLine(AcGePoint3dArray &pnts,double dMinAngle=PI-0.5*PI/180.0)
    {
    AcGePoint3dArray rcPts;
    if(pnts.logicalLength()<=2)
    {
    return;
    }
    rcPts.append(pnts.at(0));
    rcPts.append(pnts.at(1));
    for(int i=2;i<pnts.logicalLength();i++)
    {
    AcGePoint3d pt1=rcPts.at(rcPts.logicalLength()-2);
    AcGePoint3d pt2=rcPts.at(rcPts.logicalLength()-1);
    AcGePoint3d pt3=pnts.at(i);
    double dAngle=GetIntersectionDngle(pt1,pt2,pt3);
    if(dAngle>=dMinAngle&&dAngle<=PI)
    {
    rcPts.setAt(rcPts.logicalLength()-1,pt3);
    }
    else
    {
    rcPts.append(pt3);
    }
    }
    pnts.setLogicalLength(0);
    pnts.append(rcPts);
    }
    // 功能:将选择集转换为实体ID数组
    // 参数: ssName,选择集
    // ObjIds,实体ID数组
    // 返回:
    void SSToIds(AcDbObjectIdArray& ObjIds,ads_name ssName)
    {
    AcDbObjectId ObjId;
    ads_name EntName;
    long nLength=0;
    acedSSLength(ssName,&nLength);

    for(int nLen=0; nLen<nLength; nLen++)
    {
    acedSSName(ssName,nLen,EntName);
    acdbGetObjectId(ObjId,EntName);
    ObjIds.append(ObjId);
    }
    }
    // 功能:添加实体到块表记录中
    // 参数: pEnt:待添加的实体指针
    // btrID,AcDbBlockTableRecord的ID
    // 返回: 实体的ObjectID,如果插入失败返回一个空的ObjectId
    AcDbObjectId AppendEntity(AcDbEntity* pEnt,const AcDbObjectId btrID)
    {
    AcDbObjectId resultId;
    resultId.setNull();

    AcDbBlockTableRecord* pBlkRec = NULL;//打开表
    Acad::ErrorStatus es = acdbOpenObject(pBlkRec, btrID, AcDb::kForWrite);
    if (es != Acad::eOk)
    {
    acutPrintf(_T(“ 打开模型空间失败!%s”),acadErrorStatusText(es));
    return resultId;
    }

    es = pBlkRec->appendAcDbEntity(resultId,pEnt);//添加实体
    if (es != Acad::eOk)
    {
    acutPrintf(_T(“ 添加对象到模型空间失败!%s”),acadErrorStatusText(es));
    pBlkRec->close();
    return resultId;
    }
    es=pBlkRec->close();

    return resultId;
    }
    Acad::ErrorStatus ToPLine(AcDbSpline *spline)
    {
    AcGePoint3dArray pnts;
    bool rc=getSplineSamplePoints(spline,pnts);
    if(!rc)
    return Acad::eInvalidInput;
    RemovePointBetweenLine(pnts);
    AcDbPolyline* pLine=new AcDbPolyline(pnts.logicalLength());
    for(int i=0;i<pnts.logicalLength();i++)
    {
    pLine->addVertexAt(i,convert3dPointTo2d(pnts.at(i)));
    }
    AppendEntity(pLine,spline->blockId());
    pLine->close();
    return Acad::eOk;
    }
    Acad::ErrorStatus ToPLine(AcDbObjectId id)
    {
    AcDbObjectPointer<AcDbSpline> spLine(id,AcDb::kForRead);
    if(spLine.openStatus()!=Acad::eOk)
    return spLine.openStatus();
    return ToPLine(spLine.object());

    }
    void ToPLine()
    {
    Acad::ErrorStatus es=eOk;
    resbuf* rb = acutBuildList(RTDXF0, _T(“SPLINE”), 0);
    ads_name ssName;
    acutPrintf(_T(“ 请选择样条曲线: ”));
    int rc=acedSSGet(NULL, NULL,NULL,rb,ssName);
    if(rc!=RTNORM)
    {
    acutRelRb(rb);
    return;
    }
    AcDbObjectIdArray ids;
    SSToIds(ids,ssName);
    acedSSFree(ssName);
    AcDbObjectId id;
    for(int i=0;i<ids.logicalLength();i++)
    {
    id=ids.at(i);
    ToPLine(id);
    }
    }

  • 相关阅读:
    pyqt pyside QLabel 显示图片
    圆周率pi π 与 角度的对应关系
    向量 dot cross product 点积叉积 几何意义
    Python 求点到直线的垂足
    Maya cmds pymel scriptJob() 和 undoInfo() 在回调中撤销(undo)
    Python 2 和 3 的区别记录
    Maya cmds filterExpand 列出 选择的 uvs vertices faces edges 等 component 类型
    maya shell 和 UV shell 的区别
    maya cmds pymel polyEvaluate 获取 bounding box
    挂载根目录注意事项
  • 原文地址:https://www.cnblogs.com/mjgw/p/12406133.html
Copyright © 2020-2023  润新知