#include "StdAfx.h" #include "PipeTools.h" #include "getol.h" #include "DuctPipeLink.h" #include "GlobalFunction.h" #include "TGripData.h" // 获取pt1、pt2中,离ptBase点较近的点 XPoint GetNearPt(XPoint ptBase, XPoint pt1, XPoint pt2) { double dDist1 = ptBase.Distance(pt1), dDist2 = ptBase.Distance(pt2); XPoint ptRet = dDist1>(dDist2+PS_SNAP)?pt2:pt1; return ptRet; } // 获取pt1、pt2中,离ptBase点较远的点 XPoint GetFarPt(XPoint ptBase, XPoint pt1, XPoint pt2) { double dDist1 = ptBase.Distance(pt1), dDist2 = ptBase.Distance(pt2); XPoint ptRet = dDist1>(dDist2-PS_SNAP)?pt1:pt2; return ptRet; } // 判断两直线是否平行 BOOL IsParallelLine(const XLine &l1, const XLine &l2) { AcGeVector3d vt1 = XVector3D(l1.EndPoint() - l1.StartPoint()).AsAcGeVector3d(), vt2 = XVector3D(l2.EndPoint() - l2.StartPoint()).AsAcGeVector3d(); // cet 2017.12.5 modify 未考虑精度影响 // // sg注:当两向量相反时,其实vt1.isParallelTo(vt2)也返回Adesk::kTrue,建议修改 // if (vt1.isParallelTo(vt2) == Adesk::kTrue) // 平行 // return TRUE; // else if (vt1.isCodirectionalTo(vt2) == Adesk::kTrue) // 相反 // return TRUE; AcGeTol tol; tol.setEqualVector(0.001); if (vt1.isParallelTo(vt2, tol)) { return TRUE; } return FALSE; } // 判断两向量是否平行 // 若不平行,返回0;若平行且方向一致,返回1;方向相反,返回-1, int IsParallel(const XVector3D vt1, const XVector3D vt2) { int nRet(0); AcGeVector3d vec1 = vt1.AsAcGeVector3d(), vec2 = vt2.AsAcGeVector3d(); AcGeTol myTol; myTol.setEqualVector(1.0E-5); if (vec1.isParallelTo(vec2, myTol) == Adesk::kTrue) { if (vec1.isCodirectionalTo(vec2, myTol) == Adesk::kFalse) // 相反 nRet = -1; else // 平行 nRet = 1; } return nRet; } // 获取直线srcLine关于直线mirrorLine镜像后的直线 XLine GetMirrorLine(const XLine &srcLine, const XLine &mirrorLine) { XCurveSegment seg; // 镜子 seg = mirrorLine; XPoint ptMid1, ptMid2; seg.ProjectToMe(srcLine.StartPoint(), ptMid1); seg.ProjectToMe(srcLine.EndPoint(), ptMid2); XPoint ptStart, ptEnd; ptMid1.Mirror(srcLine.StartPoint(), ptStart); ptMid2.Mirror(srcLine.EndPoint(), ptEnd); XLine retLine(ptStart, ptEnd, srcLine.GetLineFlag()); return retLine; } // 判断两个seg是否共线或共圆 BOOL Is2SegOnSeg(const XCurveSegment &seg1, const XCurveSegment &seg2) { int nIsLine1 = seg1.Is(CURVE_LINE), nIsLine2 = seg2.Is(CURVE_LINE); if (nIsLine1 != nIsLine2) return FALSE; BOOL bRet(FALSE); XPoint pt1, pt2; double dNum1(0), dNum2(0); if (nIsLine1 == 1) { // LINE pt1 = seg1.StartPoint(); pt2 = seg1.EndPoint(); dNum1 = fabs(pt1.Distance(&seg2)); dNum2 = fabs(pt2.Distance(&seg2)); if (fabs(pt1.Distance(&seg2))<2.0 && fabs(pt2.Distance(&seg2))<2.0) bRet = TRUE; } else if (nIsLine1 == 0) { // ARC XArc arc1 = seg1.GetArc(), arc2 = seg2.GetArc(); pt1 = arc1.GetCenterPt(); pt2 = arc2.GetCenterPt(); dNum1 = arc1.GetRadius(); dNum2 = arc2.GetRadius(); if (pt1.Distance(pt2)intersectWith(line2, nType, points) == Acad::eOk) { int nLen = points.length(); if (nLen >= 1) ptRet = points[0]; if (line1 != NULL) { delete line1; line1 = NULL; } if (line2 != NULL) { delete line2; line2 = NULL; } } } return ptRet; } /*============================================================================* * 函 数 名: GetAnotherPipe * 功能描述: 找出另外管线的标号 * 备 注: 1、至少给出一根管线的标号 2、未知管线,必须给一个<0的初值 3、总数少于四个的情况,后面几个只要给出>0的初值即可 ==============================================================================*/ void GetAnotherPipe(const int &nNum1, int &nNum2, int &nNum3, int &nNum4) { for (int i=0; i<4; i++) { if (i == nNum1) continue; if (nNum2 < 0) { nNum2 = i; continue; } else if (i == nNum2) continue; if (nNum3 < 0) { nNum3 = i; continue; } else if (i == nNum3) continue; if (nNum4 < 0) { nNum4 = i; continue; } else if (i == nNum4) continue; } } // 过弧外一点向弧引切线,获取切点 // 当切点不止一个时,返回一个离ptRef点较近的 XPoint GetTangentPt1(const XArc &arc, XPoint pt, XPoint ptRef) { XPoint ptCen = arc.GetCenterPt(); double dRadius = arc.GetRadius(), dDist = pt.Distance(ptCen); if (dDist <= (dRadius+_distSnap)) return XPoint(); double dRadiusNew = sqrt(dDist*dDist-dRadius*dRadius); XCircle circle1(ptCen, dRadius), circle2(pt, dRadiusNew); XPoint ptInt1, ptInt2; circle2.Intersection(&circle1, ptInt1, ptInt2); if (ptInt1 == XPoint()) // 无交点 return XPoint(); int nRet1 = ptInt1&arc, nRet2 = ptInt2&arc; if (nRet1!=1 && nRet1!=2 && nRet1!=3) { if (nRet2!=1 && nRet2!=2 && nRet2!=3) return XPoint(); // 交点不在弧上 else return ptInt2; } else { if (nRet2!=1 && nRet2!=2 && nRet2!=3) return ptInt1; else { // 两个交点都在弧上 XPoint ptRet = ::GetNearPt(ptRef, ptInt1, ptInt2); return ptRet; } } } // 过圆外一点向圆引切线,获取一个离ptRef点较近的切点 XPoint GetTangentPt2(const XCircle &circle, XPoint pt, XPoint ptRef) { XPoint ptCen = circle.GetCenterPt(); double dRadius = circle.GetRadius(), dDist = pt.Distance(ptCen); if (dDist <= (dRadius+_distSnap)) return XPoint(); double dRadiusNew = sqrt(dDist*dDist-dRadius*dRadius); XCircle circleTmp(pt, dRadiusNew); XPoint ptInt1, ptInt2; if (!circleTmp.Intersection(&circle, ptInt1, ptInt2)) // 无交点 return XPoint(); XPoint ptRet = ::GetNearPt(ptRef, ptInt1, ptInt2); return ptRet; } /*============================================================================* * 函 数 名: AT_cal_fillet * 功能描述: 计算点ptReal1、ptReal2的位置 * 备 注: XLine(ptLoc、pt1)、XLine(ptLoc、pt2)为角的两条边,ptLoc为顶点, XLine(ptLoc、ptCen)为角平分线,ptTmp1、ptTmp2分别为角两边上的点,其中: 当bIsSin = TRUE时,ptTmp1、ptTmp2到ptCen的距离为dDist; 当bIsSin = FALSE时,ptTmp1、ptTmp2到ptInt的距离为dDist ==============================================================================*/ void AT_cal_fillet(const XPoint pt1, const XPoint ptLoc, const XPoint pt2, const double dDist, XPoint &ptReal1, XPoint &ptCen, XPoint &ptReal2, const BOOL bIsSin) { double dDir1 = ads_angle(ptLoc, pt1), dDir2 = ads_angle(ptLoc, pt2), dDir(0), // 中线 dAngle(0), // 角平分线 dTmp(0); XPoint ptMid, ptTmp1, ptTmp2; // 临时点 ads_polar(ptLoc, dDir1, dDist, ptTmp1); ads_polar(ptLoc, dDir2, dDist, ptTmp2); Spoint(ptMid, (ptTmp1[X]+ptTmp2[X])/2.0, (ptTmp1[Y]+ptTmp2[Y])/2.0, 0.0); // 中点 dDir = ads_angle(ptLoc, ptMid); // 中线 dAngle = fabs(dDir1 - dDir2); if (dAngle > (PI+1.0E-6)) dAngle = 2*PI - dAngle; dAngle = dAngle/2; // 角平分线 if (bIsSin) dTmp = dDist/fabs(sin(dAngle)); // dDist为圆半径 else dTmp = dDist/fabs(cos(dAngle)); // dDist为到顶点的距离 ads_polar(ptLoc, dDir, dTmp, ptCen); // 圆心点 // 管线端点的新位置,从该点开始绘制弯头 if (bIsSin) dTmp = dDist/fabs(tan(dAngle)); else dTmp = dDist; ads_polar(ptLoc, dDir1, dTmp, ptReal1); ads_polar(ptLoc, dDir2, dTmp, ptReal2); } // 获取以ptCen为圆心,过ptStart、ptEnd点的优弧 // 当bSwitch = TRUE,表示返回的是arc2;当bSwitch = FALSE,返回arc1 XArc GetRightArc(XPoint ptStart, XPoint ptCen, XPoint ptEnd, BOOL &bSwitch) { double dAng1 = CT_std_angle(ads_angle(ptCen, ptStart) - ads_angle(ptCen, ptEnd)), dAng2 = CT_std_angle(ads_angle(ptCen, ptEnd) - ads_angle(ptCen, ptStart)); XArc arc1(ptEnd, ptStart, dAng1), arc2(ptStart, ptEnd, dAng2); if (arc1.GetLength() > (arc2.GetLength()+1.0E-6)) // 选择优弧 { bSwitch = TRUE; return arc2; } bSwitch = FALSE; return arc1; } // 将以ptStart、ptEnd为起止点的线段XLine,分割成nNum份,获取分割点 void GetSplitPts(XPoint ptStart, XPoint ptEnd, int nNum, XPointList &pts) { XVector3D vt = ptEnd - ptStart; double dDist = ptStart.Distance(ptEnd); dDist /= nNum; pts.Reset(); for (int i=1; i &lstFaces, int nSplitNum, int nShowSideNum, BOOL bGetCircle1, BOOL bGetCircle2, BOOL bShow1, BOOL bShow2) { int nSideNum = nSplitNum/nShowSideNum; if (nSideNum == 0) // 显示的边>切割的边 { return FALSE; } XPointList ptLst1, ptLst2; ::GetSplitCirclePts(ptCen1, dRadius1, vtNormal1, nSplitNum, ptLst1); ::GetSplitCirclePts(ptCen2, dRadius2, vtNormal2, nSplitNum, ptLst2); int nLen1 = ptLst1.Length(), nLen2 = ptLst2.Length(); if (nLen1!=nLen2 || nLen1==0 || nLen1!=nSplitNum+1) { return FALSE; } int i(0); for (i=0; i4)) { nTmp = 0; } break; case TDbDuctNode::kTapered: regProp.GetValue(_T("TaperedMod"), nTmp); regProp.GetValue(_T("TaperedAngle"), dParam1); regProp.GetValue(_T("TaperedLen"), dParam2); if ((nTmp<0) || (nTmp>2)) { nTmp = 1; } break; case TDbDuctNode::kYiZiElbow: regProp.GetValue(_T("YZElbowMod"), nTmp); regProp.GetValue(_T("YZElbowAngle"), dParam1); regProp.GetValue(_T("YZElbowRate"), dParam2); if ((nTmp<0) || (nTmp>2)) { nTmp = 0; } break; case TDbDuctNode::k3Corner: regProp.GetValue(_T("3TType"), nTmp); regProp.GetValue(_T("3TRate"), dParam1); regProp.GetValue(_T("3TAngle"), dParam2); if ((nTmp<0) || (nTmp>12)) { nTmp = 2; } break; case TDbDuctNode::kTaoDong: regProp.GetValue(_T("3TType"), nTmp); regProp.GetValue(_T("3TRate"), dParam1); break; case TDbDuctNode::k4Corner: regProp.GetValue(_T("4TType"), nTmp); regProp.GetValue(_T("4TRate"), dParam1); regProp.GetValue(_T("4TAngle"), dParam2); if ((nTmp<0) || (nTmp>7)) { nTmp = 0; } break; } nMod = nTmp; int nLink(0); regProp.GetValue(_T("DuctLinkMod"), nLink); return nLink; } extern TWT_GRIPCMDDATA g_gripCmdData; bool GetGripCmdData( AcGePoint3d &ptGirp, AcDbObjectId &id ) { if (g_gripCmdData.id.isNull()) { return false; } ptGirp = g_gripCmdData.ptGrip; id = g_gripCmdData.id; g_gripCmdData.id.setNull(); g_gripCmdData.ptGrip = AcGePoint3d::kOrigin; return true; }