279 lines
6.0 KiB
C++
279 lines
6.0 KiB
C++
//-----------------------------------------------------------------------------+
|
|
// Copyright (C), 1998-2007, Beijing Tangent Software Co. Ltd.
|
|
// = FileName : TGGeRegion 类
|
|
// = Version : ver2.0
|
|
// = Author : wlw
|
|
// = CreateDate : 2002-09-09
|
|
// = Description: TGGeRegion 定义
|
|
// = Maintainers:
|
|
//
|
|
//-----------------------------------------------------------------------------+
|
|
#include "StdAfx.h"
|
|
#include "TGGeRegion.h"
|
|
#include "TGGiScreenDrawStream.h"
|
|
#include "TSortSideOnVertex.h"
|
|
|
|
TDPtrList<TGGeRegion> * TGGeRegion::g_pAllSpaces = NULL;
|
|
int TGGeRegion::g_nGlobalIndex = 0;
|
|
|
|
static int CompareSideForFind(const TGGeRegionSide *p1, const void *p2)
|
|
{
|
|
return (p1 == p2 ? 0 : 1);
|
|
}
|
|
|
|
TGGeRegion::TGGeRegion()
|
|
{
|
|
m_nIndex = g_nGlobalIndex;
|
|
g_nGlobalIndex++;
|
|
}
|
|
|
|
TGGeRegion::~TGGeRegion()
|
|
{
|
|
g_nGlobalIndex--;
|
|
}
|
|
|
|
// 求路径积分的面积
|
|
// Modify on 2002/2/22, 当存在误差时,微小的不封闭可能导致巨大的误差。
|
|
ads_real TGGeRegion::PathArea() const
|
|
{
|
|
int nLen = Length();
|
|
if (!nLen)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
TADSGePoint3d ptTmp = (*this)[0].GetStartPoint();
|
|
TADSGePoint3d ptBack = ptTmp;
|
|
ads_real dResult = 0.0;
|
|
|
|
for (int i = 0; i < nLen; i++)
|
|
{
|
|
dResult += (*this)[i].PathArea(ptTmp);
|
|
}
|
|
|
|
if (ptBack.Distance2d(ptTmp) > _DIST_SNAP)
|
|
{
|
|
dResult += (ptBack.x - ptTmp.x) * (ptTmp.y + ptBack.y) / 2.0;
|
|
}
|
|
|
|
return dResult;
|
|
}
|
|
|
|
//nFlag--0, 内; 1--外
|
|
TADSGePoint3d TGGeRegion::GetPoint(int nFlag, double nDist) const
|
|
{
|
|
int nLen = Length();
|
|
ASSERT(nLen);
|
|
|
|
const TGGeCurveSegment &seg = (*this)[0];
|
|
TADSGePoint3d ptMid;
|
|
if (nFlag == 0)
|
|
{
|
|
TGGeCurveSegment lCurve = seg.Offset(-nDist, LS_FINITE);
|
|
ptMid = lCurve.MidPoint();
|
|
}
|
|
else
|
|
{
|
|
TGGeCurveSegment rCurve = seg.Offset(nDist, LS_FINITE);
|
|
ptMid = rCurve.MidPoint();
|
|
}
|
|
|
|
return ptMid;
|
|
}
|
|
|
|
// 得到中心线上的POLYLINE -- Usefull
|
|
// poly -- result
|
|
// Status: 没有判断相邻两弧边是否可以并成一条弧边
|
|
// 考虑了墙体底标高
|
|
//用点是否位于节点范围进行比较
|
|
int TGGeRegion::CenterPoly2D(TGGePoly2D &poly) const
|
|
{
|
|
poly.Reset();
|
|
int nLen = Length();
|
|
if (!nLen)
|
|
{
|
|
return RTERROR;
|
|
}
|
|
|
|
const TGGeRegionSide &wall = (*this)[nLen - 1];
|
|
if (nLen == 1 && wall.Is(CURVE_CIRCLE)) // 分成两个半圆
|
|
{
|
|
ASSERT(0); //不考虑圆墙
|
|
}
|
|
else
|
|
{
|
|
poly.SetFlag(1);
|
|
TGGeCurveSegment lastSeg = wall;
|
|
lastSeg.SetLineFlag(LS_INFINITE);
|
|
|
|
TADSGePoint3d spt = (*this)[0].GetStartPoint(); // 房间的绕向由第一个墙的方向确定
|
|
|
|
TADSGePoint3d ptNext;
|
|
for (int i = 0; i < nLen; i++)
|
|
{
|
|
const TGGeRegionSide &curWall = (*this)[i];
|
|
TGGeCurveSegment curSeg = curWall;
|
|
curSeg.SetLineFlag(LS_INFINITE);
|
|
spt.z = curWall.GetEndPoint().z;
|
|
|
|
TADSGePoint3d ept = curWall.GetStartNode()->Include(spt) ? curWall.GetEndPoint() : curWall.GetStartPoint();
|
|
TADSGePoint3d pt1, pt2, ptCur;
|
|
if (!i) // 求当前点
|
|
{
|
|
int nPtNum = curSeg.Intersection(lastSeg, pt1, pt2);
|
|
if (nPtNum == 2)
|
|
{
|
|
ptCur = TGGeLine(pt1,pt2).NearPoint(spt);
|
|
}
|
|
else if (nPtNum == 1)
|
|
{
|
|
ptCur = pt1;
|
|
}
|
|
else
|
|
{
|
|
ptCur = curSeg.NearPoint(spt); // 同一方向上, 两段衔接.
|
|
}
|
|
}
|
|
else
|
|
{
|
|
ptCur = ptNext; //上次求得的下一点
|
|
}
|
|
|
|
// 求下一个端点
|
|
int nNextIndex = i >= nLen-1 ? 0 : i + 1; // 当前段为最后时, 下一段为起始段
|
|
const TGGeRegionSide &nextWall = (*this)[nNextIndex];
|
|
|
|
TGGeCurveSegment nextSeg = nextWall;
|
|
nextSeg.SetLineFlag(LS_INFINITE);
|
|
|
|
int nPtNum = curSeg.Intersection(nextSeg, pt1, pt2);
|
|
if (nPtNum == 2)
|
|
{
|
|
ptNext = TGGeLine(pt1, pt2).NearPoint(ept);
|
|
}
|
|
else if (nPtNum == 1)
|
|
{
|
|
ptNext = pt1;
|
|
}
|
|
else
|
|
{
|
|
ptNext = curSeg.NearPoint(ept); // 同一方向上, 两段衔接.
|
|
}
|
|
|
|
//添一段
|
|
poly.Append(new TADSGePoint3d(ptCur));
|
|
if (curSeg.Is(CURVE_LINE))
|
|
{
|
|
poly.AppendBugle(0.0);
|
|
}
|
|
else if (curSeg.Is(CURVE_ARC))
|
|
{
|
|
TGGeArc arc = curSeg.GetArc();
|
|
if (spt == curWall.GetStartPoint()) //逆时针
|
|
{
|
|
arc.SetStarAngle(ads_angle(arc.GetCenterPt(), ptCur));
|
|
arc.SetEndAngle(ads_angle(arc.GetCenterPt(), ptNext));
|
|
poly.AppendBugle(arc.Bulge());
|
|
}
|
|
else
|
|
{
|
|
arc.SetEndAngle(ads_angle(arc.GetCenterPt(), ptCur));
|
|
arc.SetStarAngle(ads_angle(arc.GetCenterPt(), ptNext));
|
|
poly.AppendBugle(-arc.Bulge());
|
|
}
|
|
}
|
|
else
|
|
{
|
|
TchGeLib::adsout << _T("\nFetal error!");
|
|
assert(0);
|
|
}
|
|
|
|
spt = ept;
|
|
lastSeg = curSeg;
|
|
}
|
|
}
|
|
|
|
return RTNORM;
|
|
}
|
|
|
|
int TGGeRegion::ShowMe() const
|
|
{
|
|
ads_redraw(NULL,0);
|
|
TGGiScreenDrawStream dc(1, 1);
|
|
|
|
int nLen = Length();
|
|
for (int i = 0; i < nLen; i++)
|
|
{
|
|
dc << (*this)[i];
|
|
}
|
|
|
|
return RTNORM;
|
|
}
|
|
|
|
//求房间中心线的界限
|
|
int TGGeRegion::GetExtend(TADSGePoint3d &ptLow, TADSGePoint3d &ptUp) const
|
|
{
|
|
if (!Length())
|
|
{
|
|
return RTERROR;
|
|
}
|
|
|
|
for (int i = 0; i < Length(); i++)
|
|
{
|
|
const TGGeRegionSide &wall = (*this)[i];
|
|
if (i == 0)
|
|
{
|
|
wall.GetExtend(ptLow, ptUp);
|
|
}
|
|
else
|
|
{
|
|
TADSGePoint3d ptMin, ptMax;
|
|
wall.GetExtend(ptMin, ptMax);
|
|
ptLow = Min(ptLow, ptMin);
|
|
ptUp = Max(ptUp, ptMax);
|
|
}
|
|
}
|
|
|
|
return RTNORM;
|
|
}
|
|
|
|
// 比较是否相反
|
|
BOOL TGGeRegion::IsEqualTo(const TGGeRegion ®ion) const
|
|
{
|
|
const TGGeRegion ®ionThis = *this;
|
|
int nSideNum = Length();
|
|
if (nSideNum != region.Length())
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
for (int i = 0; i < nSideNum; i++)
|
|
{
|
|
const TGGeRegionSide &side1 = regionThis[i];
|
|
const TGGeRegionSide &side2 = region[i];
|
|
if (&side1 != &side2)
|
|
{
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
// 比较是否相邻
|
|
BOOL TGGeRegion::IsAdjacentTo(const TGGeRegion ®ion) const
|
|
{
|
|
const TGGeRegion ®ionThis = *this;
|
|
int nSideNum = Length();
|
|
for (int i = 0; i < nSideNum; i++)
|
|
{
|
|
const TGGeRegionSide &side1 = regionThis[i];
|
|
if (((TGGeRegion &)region).FindNode(&side1, CompareSideForFind))
|
|
{
|
|
return TRUE;
|
|
}
|
|
}
|
|
|
|
return FALSE;
|
|
}
|