Files
envi-code/SourceCode/Code2026/tg_shs/shs_subgeLib/TchSubPrivateGlobalFunc.cpp
T
2026-09-28 15:28:50 +08:00

685 lines
14 KiB
C++

//-----------------------------------------------------------------------------+
// 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 &center,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 &center,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 &center,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 &center,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 &center1,double r1,
const TGPoint &center2,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<TGRegionEx2D*> 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<TGRegionEx2D*> 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);
}
}
}
}
}
}