//-----------------------------------------------------------------------------+ // Copyright (C), 1998-2007, Beijing Tangent Software Co. Ltd. // = FileName : 内部全局函数实现文件 // = Version : ver2.0 // = Author : tg // = CreateDate : 2002-09-09 // = Description: 全局函数的声明 // = Maintainers: // //-----------------------------------------------------------------------------+ #include "StdAfx.h" #include "TchSubPrivateGlobalFunc.h" #include "TGPoint2D.h" #include "TPGeGLine2D.h" #include "TPGeGLineRay2D.h" #include "TPGeGLineSeg2D.h" #include "TPGeCircle2D.h" #include "TPGeArc2D.h" #include "TGMLine2D.h" #include "TGPLine2D.h" #include "TGMCurve2D.h" #include "TGPolygon2D.h" #include "TGPolygonEx2D.h" #include "TGRegionEx2D.h" #include "TGPoint3D.h" #include "TPGeGLine3D.h" #include "TPGeGLineRay3D.h" #include "TPGeGLineSeg3D.h" #include "TGPCurve3D.h" #include "TGMLine3D.h" #include "TGMCurve3D.h" #include "TGPlane3D.h" #include "TPGeGraph.h" double TchSubPrivate::GetAngle(const TPGeDscEdge &e0,const TPGeDscEdge &e1) { TPGeDscPoint *pPt,*pPt0,*pPt1; if (e0.pPt0 == e1.pPt0) { pPt = e0.pPt0; pPt0 = e0.pPt1; pPt1 = e1.pPt1; } else if (e0.pPt0 == e1.pPt1) { pPt = e0.pPt0; pPt0 = e0.pPt1; pPt1 = e1.pPt0; } else if (e0.pPt1 == e1.pPt1) { pPt = e0.pPt1; pPt0 = e0.pPt0; pPt1 = e1.pPt0; } else { pPt = e0.pPt1; pPt0 = e0.pPt0; pPt1 = e1.pPt1; } TGVector2D vt0(*pPt,*pPt0),vt1(*pPt,*pPt1); return vt1.GetAngleWith(vt0); } int TchSubPrivate::CompareEdge(const TPGeDscEdge &e0, const TPGeDscEdge &e1) { TPGeDscPoint *pPt,*pPt0,*pPt1; if (e0.pPt0 == e1.pPt0) { pPt = e0.pPt0; pPt0 = e0.pPt1; pPt1 = e1.pPt1; } else if (e0.pPt0 == e1.pPt1) { pPt = e0.pPt0; pPt0 = e0.pPt1; pPt1 = e1.pPt0; } else if (e0.pPt1 == e1.pPt1) { pPt = e0.pPt1; pPt0 = e0.pPt0; pPt1 = e1.pPt0; } else { pPt = e0.pPt1; pPt0 = e0.pPt0; pPt1 = e1.pPt1; } TGVector2D vt0(*pPt,*pPt0), vt1(*pPt,*pPt1); return vt0.GetAngle() > vt1.GetAngle(); } int TchSubPrivate::LineInt2D(const TGPoint&pt1,const TGVector2D&vt1, const TGPoint&pt2,const TGVector2D&vt2, double&pa1) { TGVector2D vt3(pt2,pt1); double A = vt1 * vt2,B = vt2 * vt3,C = vt1 * vt3; if (EQUAL_ZERO(A)) { double D = (fabs(B) + fabs(C)) / 2.0; return EQUAL_ZEROD(D) ? INT_LINE : INT_NULL; } pa1 = B / A; return INT_1PT; } int TchSubPrivate::LineInt2D(const TGPoint &pt1,const TGVector2D &vt1, const TGPoint &pt2,const TGVector2D &vt2, double &pa1,double &pa2) { TGVector2D vt3(pt2,pt1); double A = vt1 * vt2,B = vt2 * vt3,C = vt1 * vt3; if (EQUAL_ZERO(A)) { double D = (fabs(B) + fabs(C)) / 2.0; return EQUAL_ZEROD(D) ? INT_LINE : INT_NULL; } pa1 = B / A; pa2 = C / A; return INT_1PT; } int TchSubPrivate::LineCirInt2D(const TGPoint ¢er,double r, const TGPoint &pt,const TGVector2D &vt, TGPoint &pt1,TGPoint &pt2) { double x0 = pt.x - center.x; double y0 = pt.y - center.y; const double &a = vt.x; const double &b = vt.y; double B = 2 * (a * x0 + b * y0); double t = -B / 2; pt1.x = pt.x + vt.x * t; pt1.y = pt.y + vt.y * t; pt1.z = pt.z; double d = Distance2D(pt1,center) - r; if (EQUAL_ZEROD(d)) { return INT_1PT; } double C = x0 * x0 + y0 * y0 - r * r; double D = (B * B - 4 * C) / 4; if (DOWN_ZERO(D)) { return INT_NULL; } else if (UP_ZERO(D)) { double delt = sqrt(D); if (UP_ZERO(delt)) { double t1 = t - delt,t2 = t + delt; pt1.x = pt.x + vt.x * t1; pt1.y = pt.y + vt.y * t1; pt1.z = pt.z; pt2.x = pt.x + vt.x * t2; pt2.y = pt.y + vt.y * t2; pt2.z = pt.z; return INT_2PT; } } return INT_1PT; } int TchSubPrivate::LineCirInt2D(const TGPoint ¢er,double r, const TGPoint &pt,const TGVector2D &vt, double &pa1,double &pa2) { double x0 = pt.x - center.x; double y0 = pt.y - center.y; const double &a = vt.x,&b = vt.y; double B = 2 * (a * x0 + b * y0); pa1 = -B / 2; double d = Distance2D(TGPoint(pt.x + vt.x * pa1,pt.y + vt.y * pa1),center) - r; if (EQUAL_ZEROD(d)) { return INT_1PT; } double C = x0 * x0 + y0 * y0 - r * r; double D = (B * B - 4 * C) / 4; if (DOWN_ZERO(D)) { return INT_NULL; } else if (UP_ZERO(D)) { double delt = sqrt(D); if (UP_ZERO(delt)) { pa2 = pa1 + delt; pa1 = pa1 - delt; return INT_2PT; } } return INT_1PT; } bool TchSubPrivate::LB_IsOk(const double &dn,const double &nw,double &tl,double &tu) { if (UP_ZERO(dn)) { double t = nw / dn; if (t > tu) { return false; } else if (t > tl) { tl = t; } } else if (DOWN_ZERO(dn)) { double t = nw / dn; if (t < tl) { return false; } else if (t < tu) { tu = t; } } else if (UP_ZERO(nw)) { return false; } return true; } void TchSubPrivate::InitCircle2D(const TGPoint &pt0,const TGPoint &pt1,const TGPoint &pt2,TGPoint ¢er,double &r) { double pa; TGVector2D vt0,vt1; TGVector2D(pt0,pt1).GetLVertVector(vt0); vt0.Normalize(); TGVector2D(pt1,pt2).GetLVertVector(vt1); vt1.Normalize(); TGPoint pt00((pt0.x + pt1.x) / 2,(pt0.y + pt1.y) / 2),pt11((pt1.x + pt2.x) / 2,(pt1.y + pt2.y) / 2); TchSubPrivate::LineInt2D(pt00,vt0,pt11,vt1,pa); TchSubPrivate::LinePt2D(pt0,vt0,pa,center); r = Distance2D(center,pt0); } void TchSubPrivate::InitCircle2D(const TGPoint &pt0,const TGPoint &pt1,double angle,TGPoint ¢er,double &r) { double len = Distance2D(pt0,pt1); r = fabs(len / (2 * sin(angle / 2))); TGVector2D vt0(pt0,pt1),vt; vt0.GetLVertVector(vt); vt.SetLength(fabs(r * cos(angle / 2))); center.x = (pt0.x + pt1.x) / 2; center.y = (pt0.y + pt1.y) / 2; center.z = pt0.z; if ((UP_ZEROA(angle) && (DOWN_ZEROA(angle - PI))) || DOWN_ZEROA(angle + PI)) { center.x += vt.x; center.y += vt.y; } else if ((DOWN_ZEROA(angle) && UP_ZEROA(angle + PI)) || UP_ZEROA(angle - PI)) { center.x -= vt.x; center.y -= vt.y; } } int TchSubPrivate::CircleInt(const TGPoint ¢er1,double r1, const TGPoint ¢er2,double r2, TGPoint &pt1,TGPoint &pt2) { TGVector2D vt(center1,center2); if (vt.IsNullVector()) { double temp = r1 - r2; if (EQUAL_ZEROD(temp)) { return INT_CIRCLE; } else { return INT_NULL; } } else { double dist = vt.Length(); double dist1 = dist - fabs(r1 - r2); if (DOWN_ZEROD(dist1)) { return INT_NULL; } double dist2 = dist - r1 - r2; if (UP_ZEROD(dist2)) { return INT_NULL; } if (EQUAL_ZEROD(dist1)) { vt *= r1 > r2 ? (r1 / dist) : (-r1 / dist); pt1.x = center1.x + vt.x; pt1.y = center1.y + vt.y; pt1.z = center1.z; return INT_1PT; } if (EQUAL_ZEROD(dist2)) { vt *= (r1 / dist); pt1.x = center1.x + vt.x; pt1.y = center1.y + vt.y; pt1.z = center1.z; return INT_1PT; } double r12 = r1 * r1, r22 = r2 * r2, d2 = dist * dist; if (r1 >= r2) { double cos = (r12 + d2 - r22) / (2 * r1 * dist); double sin = sqrt(1 - cos * cos); TGVector2D vt1; vt.GetLVertVector(vt1); vt.SetLength(r1 * cos); vt1.SetLength(r1 * sin); pt1.x = center1.x + vt.x + vt1.x; pt1.y = center1.y + vt.y + vt1.y; pt2.x = center1.x + vt.x - vt1.x; pt2.y = center1.y + vt.y - vt1.y; } else { double cos = (r22 + d2 - r12) / (2 * r2 * dist); double sin = sqrt(1 - cos * cos); TGVector2D vt1; vt.Reverse(); vt.GetLVertVector(vt1); vt.SetLength(r2 * cos); vt1.SetLength(r2 * sin); pt1.x = center2.x + vt.x + vt1.x; pt1.y = center2.y + vt.y + vt1.y; pt2.x = center2.x + vt.x - vt1.x; pt2.y = center2.y + vt.y - vt1.y; } pt1.z = center1.z; pt2.z = center1.z; return INT_2PT; } } int TchSubPrivate::LineInt3D(const TGPoint &pt1,const TGVector3D &vt1, const TGPoint &pt2,const TGVector3D &vt2, double &pa1) { TGVector3D vt3(pt1,pt2); vt3.Normalize(); if (!(vt1 * vt3).IsParallel(vt2 * vt3,true)) { return INT_NULL; } double temp = (vt2.y * vt1.x - vt2.x * vt1.y); if (!EQUAL_ZERO(temp)) { pa1 = (vt2.y * pt2.x - vt2.y * pt1.x - vt2.x * pt2.y + vt2.x * pt1.y) / temp; return INT_1PT; } temp = (vt2.z * vt1.x - vt2.x * vt1.z); if (!EQUAL_ZERO(temp)) { pa1 = (vt2.z * pt2.x - vt2.z * pt1.x - vt2.x * pt2.z + vt2.x * pt1.z) / temp; return INT_1PT; } temp = (vt2.y * vt1.z - vt2.z * vt1.y); if (!EQUAL_ZERO(temp)) { pa1 = (vt2.y * pt2.z - vt2.y * pt1.z - vt2.z * pt2.y + vt2.z * pt1.y) / temp; return INT_1PT; } if (vt1.IsParallel(vt3,true)) { return INT_LINE; } else { return INT_NULL; } } int TchSubPrivate::LinePlaneInt3D(double A,double B,double C,double D, const TGPoint &pt0,const TGVector3D &vt, double &pa) { TGVector3D vt1(A,B,C); double n1 = vt1 & vt; double n2 = -D - (vt1 & pt0); if (EQUAL_ZERO(n1)) { if (EQUAL_ZERO(n2)) { return INT_LINE; } else { return INT_NULL; } } pa = n2 / n1; return INT_1PT; } int TchSubPrivate::LinePlaneInt3D(double A,double B,double C,double D, const TGPoint &pt0,const TGVector3D &vt, TGPoint &pt) { TGVector3D vt1(A,B,C); double n1 = vt1 & vt; double n2 = -D - (vt1 & pt0); if (EQUAL_ZERO(n1)) { if (EQUAL_ZERO(n2)) { return INT_LINE; } else { return INT_NULL; } } double pa = n2 / n1; pt.x = pt0.x + vt.x * pa; pt.y = pt0.y + vt.y * pa; pt.z = pt0.z + vt.z * pa; return INT_1PT; } int TchSubPrivate::PlaneInt(double A1,double B1,double C1,double D1, double A2,double B2,double C2,double D2, TGPoint &pt,TGVector3D &vt) { double A3 = B1 * C2 - C1 * B2,B3 = C1 * A2 - A1 * C2,C3 = A1 * B2 - B1 * A2; if (EQUAL_ZERO(A3) && EQUAL_ZERO(B3) && EQUAL_ZERO(C3)) { double temp = A1 * D2 - A2 * D1; if (EQUAL_ZERO(temp)) { return INT_PLANE; } else { return INT_NULL; } } vt.x = A3; vt.y = B3; vt.z = C3; if (!EQUAL_ZERO(C3)) { pt.z = 0; pt.x = (B1 * D2 - B2 * D1) / C3; pt.y = (-A1 * D2 + A2 * D1) / C3; } else if (!EQUAL_ZERO(B3)) { pt.y = 0; pt.x = (-C1 * D2 + C2 * D1) / B3; pt.z = (A1 * D2 - A2 * D1) / B3; } else if (!EQUAL_ZERO(A3)) { pt.x = 0; pt.z = (-B1 * D2 + B2 * D1) / A3; pt.y = (C1 * D2 - C2 * D1) / A3; } else { return INT_NULL; } vt.Normalize(); return INT_LINE; } void TchSubPrivate::CreateRegion2D(TGObjectList &curves,TGObjectList &res,bool bCheckHole) { TGObjectList closeCurves; for (curves.MoveToFirst(); !curves.IsOut(); curves.MoveToNext()) { TPGeCurve2D* pCurve = (TPGeCurve2D*)curves.GetCurData(); if (pCurve->IsClosed()) { closeCurves << curves.FetchCur(); } else if (!pCurve->IsCurveSeg()) { curves.DelCur(); } } TPGeGraph g; g.AppendEdge(curves); g.FindCurve(closeCurves,closeCurves); if (closeCurves.GetLength() == 1 || !bCheckHole) { for (closeCurves.MoveToFirst(); !closeCurves.IsOut(); closeCurves.MoveToNext()) { res << new TGRegionEx2D((TPGeCurve2D*)closeCurves.FetchCur(),false); } } else { TList face; for (closeCurves.MoveToFirst(); !closeCurves.IsOut(); closeCurves.MoveToNext()) { TPGeCurve2D* pCurve = (TPGeCurve2D*)closeCurves.GetCurData(); if (!pCurve->IsClockwise()) { closeCurves.FetchCur(); TGRegionEx2D* pFace = new TGRegionEx2D(pCurve,false); face << pFace; res << pFace; } } if (face.GetLength() == 1) { TGRegionEx2D *pFace = face.GetAt(0); for (closeCurves.MoveToFirst(); !closeCurves.IsOut(); closeCurves.MoveToNext()) { pFace->AppendHole((TPGeCurve2D*)closeCurves.FetchCur(),false); } } else { for (face.MoveToFirst(); !face.IsOut(); face.MoveToNext()) { TGRegionEx2D *pFace = face.GetCurData(); TPGeCurve2D&outline = pFace->Outline(); for (closeCurves.MoveToFirst(); !closeCurves.IsOut(); closeCurves.MoveToNext()) { GRelation r = outline.HitTest(closeCurves.GetCurPData().GetSamplePoint()); if (r.Is(GR_INSIDE)) { pFace->AppendHole((TPGeCurve2D*)closeCurves.FetchCur(),false); } } } } } } void TchSubPrivate::CreateRegion2DEx(TGObjectList &curves,TGObjectList &res,bool bCheckHole) { TGObjectList closeCurves,infiniteCurves; for (curves.MoveToFirst(); !curves.IsOut(); curves.MoveToNext()) { TPGeCurve2D* pCurve = (TPGeCurve2D*)curves.GetCurData(); if (pCurve->IsClosed()) { closeCurves << curves.FetchCur(); } else if (!pCurve->IsFinite(true) && !pCurve->IsFinite(false)) { infiniteCurves << curves.FetchCur(); } } TPGeGraph g; g.AppendEdge(curves); g.FindCurve(closeCurves,infiniteCurves); TList face; if (infiniteCurves.GetLength() == 2) { TPGeCurve2D *pCurve0 = (TPGeCurve2D*)infiniteCurves.Fetch(0); TPGeCurve2D *pCurve1 = (TPGeCurve2D*)infiniteCurves.Fetch(0); if (pCurve0->HitTest(pCurve1->GetSamplePoint()).Is(GR_RIGHT) && pCurve1->HitTest(pCurve0->GetSamplePoint()).Is(GR_RIGHT)) { TGRegionEx2D* pRegion0 = new TGRegionEx2D(pCurve0,false); TGRegionEx2D* pRegion1 = new TGRegionEx2D(pCurve1,false); res << pRegion0 << pRegion1; face << pRegion0 << pRegion1; } else { TGRegionEx2D *pRegion = new TGRegionEx2D(pCurve0,false); pRegion->AppendHole(pCurve1,false); res << pRegion; face << pRegion; } } else if (infiniteCurves.GetLength() == 1) { TGRegionEx2D *pRegion = new TGRegionEx2D((TPGeCurve2D*)infiniteCurves.Fetch(0),false); res << pRegion; face << pRegion; } if (!bCheckHole) { for (closeCurves.MoveToFirst(); !closeCurves.IsOut(); closeCurves.MoveToNext()) { res << new TGRegionEx2D((TPGeCurve2D*)closeCurves.FetchCur(),false); } } else { for (closeCurves.MoveToFirst(); !closeCurves.IsOut(); closeCurves.MoveToNext()) { TPGeCurve2D* pCurve = (TPGeCurve2D*)closeCurves.GetCurData(); if (!pCurve->IsClockwise()) { closeCurves.FetchCur(); TGRegionEx2D* pRegion = new TGRegionEx2D(pCurve,false); face << pRegion; res << pRegion; } } if (face.IsEmpty() && !closeCurves.IsEmpty()) { TGRegionEx2D *pRegion = new TGRegionEx2D; face << pRegion; res << pRegion; } if (face.GetLength() == 1) { TGRegionEx2D *pFace = face.GetAt(0); for (closeCurves.MoveToFirst(); !closeCurves.IsOut(); closeCurves.MoveToNext()) { pFace->AppendHole((TPGeCurve2D*)closeCurves.FetchCur(),false); } } else { for (face.MoveToFirst(); !face.IsOut(); face.MoveToNext()) { TGRegionEx2D *pFace = face.GetCurData(); TPGeCurve2D&outline = pFace->Outline(); for (closeCurves.MoveToFirst(); !closeCurves.IsOut(); closeCurves.MoveToNext()) { GRelation r = outline.HitTest(closeCurves.GetCurPData().GetSamplePoint()); if (r.Is(GR_INSIDE)) { pFace->AppendHole((TPGeCurve2D*)closeCurves.FetchCur(),false); } } } } } }