422 lines
9.2 KiB
C++
422 lines
9.2 KiB
C++
////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// File: hgrid.h
|
|
// Created by: Jerzy Majewski - jmajewsk@meil.pw.edu.pl
|
|
// Modified by:
|
|
// 2005-04-19 JM: mbIsOutside flag for HGrdTri was not initialized;
|
|
// CheckBoundIntegr was creating flat or negative triangles
|
|
//
|
|
// Copyright notice:
|
|
// Copyright (C) 2000-2003 Jerzy Majewski
|
|
//
|
|
// This is free software. You can redistribute it and/or
|
|
// modify it under the terms of the GNU Lesser General Public License
|
|
// as published by the Free Software Foundation.
|
|
//
|
|
// This software is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY. See the GNU Lesser General Public License
|
|
// for more details.
|
|
//
|
|
//
|
|
// rem:
|
|
// 在vs2010 下 标准模板容器 list 的迭代器和 vs2008 比代码实现已经不一样
|
|
// 所以在 vs2010 下编译 需要用本项目目录下的 list 文件替代 vs2010的 list
|
|
// 编译.
|
|
//
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
#ifndef __HGRID_H__
|
|
#define __HGRID_H__
|
|
|
|
#include "mgdecl.h"
|
|
#include "vect.h"
|
|
#include "hrect.h"
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
// class HGrdPnt
|
|
//////////////////////////////////////////////////////////////////////
|
|
class HGrdPnt : public Vect2D
|
|
{
|
|
public:
|
|
HGrdPnt() {}
|
|
HGrdPnt( const Vect2D& vec) : Vect2D( vec) {}
|
|
HGrdPnt( const MGFloat& dx, const MGFloat& dy) : Vect2D( dx, dy) {}
|
|
~HGrdPnt() {}
|
|
|
|
const MGInt& Index() const { return mInd;}
|
|
MGInt& rIndex() { return mInd;}
|
|
|
|
protected:
|
|
MGInt mInd;
|
|
};
|
|
//--------------------------------------------------------------------
|
|
|
|
|
|
typedef std::list<HGrdPnt*> CollGPnt;
|
|
typedef CollGPnt::iterator IterGPnt;
|
|
|
|
|
|
|
|
|
|
|
|
const MGInt NUM_TRI = 3;
|
|
|
|
class HFroSeg;
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
/// class HGrdTri
|
|
//////////////////////////////////////////////////////////////////////
|
|
|
|
class HGrdTri
|
|
{
|
|
public:
|
|
|
|
typedef std::list<HGrdTri*> CollGCell;
|
|
typedef CollGCell::iterator IterGCell;
|
|
|
|
HGrdTri();
|
|
~HGrdTri() {}
|
|
|
|
|
|
const bool& IsOutside() const { return mbIsOutside;}
|
|
bool& rIsOutside() { return mbIsOutside;}
|
|
|
|
const MGInt& Cross() const { return mCross;}
|
|
MGInt& rCross() { return mCross;}
|
|
|
|
IterGPnt Node( const MGInt& i) const;
|
|
IterGCell Cell( const MGInt& i) const;
|
|
|
|
IterGPnt& rNode( const MGInt& i);
|
|
IterGCell& rCell( const MGInt& i);
|
|
|
|
bool IsInside( const Vect2D& vct);
|
|
void NullifyThis( HGrdTri *pcl);
|
|
void NullifyThis( HFroSeg *pseg);
|
|
void InvalidateNeighb();
|
|
void SetNeighbour( const IterGCell& itrcl);
|
|
|
|
MGFloat Area() const;
|
|
Vect2D Center();
|
|
IterGCell NextCell( const Vect2D& vct);
|
|
IterGCell NextCell( HFroSeg *pseg, const IterGCell& iclprv = IterGCell());
|
|
|
|
const Vect2D& CircCenter() const;
|
|
bool SetCircCenter();
|
|
|
|
bool IsInsideCirc( const Vect2D& vct);
|
|
bool IsVisible( const IterGCell& icl, const Vect2D& vct);
|
|
bool IsVisibleDump( const IterGCell& icl, const Vect2D& vct);
|
|
|
|
bool Check();
|
|
void DumpTri();
|
|
void DumpTEC( FILE *f);
|
|
|
|
protected:
|
|
IterGPnt mlstNod[NUM_TRI]; // ref. to three nodes
|
|
IterGCell mlstCell[NUM_TRI]; // ref. to three neighbours
|
|
bool mbIsOutside;
|
|
Vect2D mCircCenter;
|
|
|
|
MGInt mCross;
|
|
};
|
|
|
|
//--------------------------------------------------------------------
|
|
|
|
typedef HGrdTri::CollGCell CollGCell;
|
|
typedef HGrdTri::IterGCell IterGCell;
|
|
|
|
|
|
|
|
inline const Vect2D& HGrdTri::CircCenter() const
|
|
{
|
|
return mCircCenter;
|
|
}
|
|
|
|
|
|
inline IterGPnt HGrdTri::Node( const MGInt& i) const
|
|
{
|
|
ASSERT( i>=0 && i<NUM_TRI);
|
|
return mlstNod[i];
|
|
}
|
|
|
|
inline IterGCell HGrdTri::Cell( const MGInt& i) const
|
|
{
|
|
ASSERT( i>=0 && i<NUM_TRI);
|
|
return mlstCell[i];
|
|
}
|
|
|
|
|
|
inline IterGPnt& HGrdTri::rNode( const MGInt& i)
|
|
{
|
|
ASSERT( i>=0 && i<NUM_TRI);
|
|
return mlstNod[i];
|
|
}
|
|
|
|
inline IterGCell& HGrdTri::rCell( const MGInt& i)
|
|
{
|
|
ASSERT( i>=0 && i<NUM_TRI);
|
|
return mlstCell[i];
|
|
}
|
|
|
|
inline bool HGrdTri::Check()
|
|
{
|
|
Vect2D v1 = *(*Node(1)) - *(*Node(0));
|
|
Vect2D v2 = *(*Node(2)) - *(*Node(0));
|
|
MGFloat d = v1.X()*v2.Y() - v1.Y()*v2.X();
|
|
|
|
if ( fabs(d) < 1.0e-16)
|
|
return false;
|
|
else
|
|
return true;
|
|
}
|
|
|
|
|
|
inline MGFloat HGrdTri::Area() const
|
|
{
|
|
Vect2D v1 = *(*Node(1)) - *(*Node(0));
|
|
Vect2D v2 = *(*Node(2)) - *(*Node(0));
|
|
MGFloat d = v1.X()*v2.Y() - v1.Y()*v2.X();
|
|
|
|
return 0.5*d;
|
|
}
|
|
|
|
inline void HGrdTri::DumpTri()
|
|
{
|
|
char sbuf[256];
|
|
sprintf( sbuf, "n0 = (%lg %lg) n1 = (%lg %lg) n2 = (%lg %lg)",
|
|
(*Node(0))->X(), (*Node(0))->Y(),
|
|
(*Node(1))->X(), (*Node(1))->Y(),
|
|
(*Node(2))->X(), (*Node(2))->Y() );
|
|
|
|
TRACE( sbuf);
|
|
|
|
void *cp0, *cp1, *cp2;
|
|
|
|
cp0 = cp1 = cp2 = NULL;
|
|
if ( Cell(0) != IterGCell())
|
|
cp0 = *Cell(0);
|
|
|
|
if ( Cell(1) != IterGCell())
|
|
cp1 = *Cell(1);
|
|
|
|
if ( Cell(2) != IterGCell())
|
|
cp2 = *Cell(2);
|
|
|
|
//sprintf( sbuf, "c0 = (%p %p) c1 = (%p %p) c2 = (%p %p)", Cell(0), cp0, Cell(1), cp1, Cell(2), cp2);
|
|
sprintf( sbuf, "c0 = (%p) c1 = (%p) c2 = (%p)", cp0, cp1, cp2);
|
|
|
|
TRACE( sbuf);
|
|
}
|
|
|
|
|
|
inline void HGrdTri::DumpTEC( FILE *f)
|
|
{
|
|
fprintf( f, "VARIABLES = \"X\", \"Y\"\n");
|
|
fprintf( f, "ZONE T=\"TRIANGLES\", ");
|
|
fprintf( f, "N=%2ld, ", 3 );
|
|
fprintf( f, "E=%2ld, F=FEPOINT, ET=QUADRILATERAL C=BLACK\n ", 1 );
|
|
|
|
fprintf( f, "%lg %lg\n%lg %lg\n%lg %lg\n",
|
|
(*Node(0))->X(), (*Node(0))->Y(),
|
|
(*Node(1))->X(), (*Node(1))->Y(),
|
|
(*Node(2))->X(), (*Node(2))->Y() );
|
|
fprintf( f, "1 2 3 3\n");
|
|
|
|
}
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
/// class HFroSeg
|
|
//////////////////////////////////////////////////////////////////////
|
|
class HFroSeg
|
|
{
|
|
public:
|
|
HFroSeg();
|
|
HFroSeg( const HFroSeg& seg);
|
|
HFroSeg( IterGPnt ip1, IterGPnt ip2,
|
|
IterGCell ic1=IterGCell(), IterGCell ic2=IterGCell() );
|
|
|
|
~HFroSeg() {}
|
|
|
|
const IterGPnt& PntLf() const { return miPntLf;}
|
|
const IterGPnt& PntRt() const { return miPntRt;}
|
|
IterGPnt& rPntLf() { return miPntLf;}
|
|
IterGPnt& rPntRt() { return miPntRt;}
|
|
|
|
const IterGCell& CellUp() const { return miCellUp;}
|
|
const IterGCell& CellLo() const { return miCellLo;}
|
|
IterGCell& rCellUp() { return miCellUp;}
|
|
IterGCell& rCellLo() { return miCellLo;}
|
|
|
|
|
|
|
|
protected:
|
|
IterGPnt miPntLf; // ref. to left GrdPoint
|
|
IterGPnt miPntRt; // ref. to right GrdPoint
|
|
IterGCell miCellUp; // ref. to upper cell
|
|
IterGCell miCellLo; // ref. to lower cell
|
|
|
|
public:
|
|
bool mbtmp;
|
|
};
|
|
//--------------------------------------------------------------------
|
|
|
|
typedef std::list<HFroSeg*> CollFSeg;
|
|
typedef CollFSeg::iterator IterFSeg;
|
|
|
|
|
|
|
|
inline HFroSeg::HFroSeg()
|
|
{
|
|
miPntLf = miPntRt = IterGPnt();
|
|
miCellUp = miCellLo = IterGCell();
|
|
}
|
|
|
|
inline HFroSeg::HFroSeg( const HFroSeg& seg)
|
|
{
|
|
miPntLf = seg.miPntLf;
|
|
miPntRt = seg.miPntRt;
|
|
miCellUp = seg.miCellUp;
|
|
miCellLo = seg.miCellLo;
|
|
}
|
|
|
|
|
|
inline HFroSeg::HFroSeg( IterGPnt ip1, IterGPnt ip2,
|
|
IterGCell ic1, IterGCell ic2)
|
|
{
|
|
miPntLf = ip1;
|
|
miPntRt = ip2;
|
|
miCellUp = ic1;
|
|
miCellLo = ic2;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
// class HFront
|
|
//////////////////////////////////////////////////////////////////////
|
|
class HFront : public CollFSeg
|
|
{
|
|
friend class HFrontLoop;
|
|
|
|
public:
|
|
HFront() {}
|
|
~HFront();
|
|
|
|
MGFloat Angle( const Vect2D& vct);
|
|
|
|
};
|
|
//--------------------------------------------------------------------
|
|
|
|
typedef std::list<HFront> CollFro;
|
|
typedef CollFro::iterator IterFro;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
/// class HGrid
|
|
//////////////////////////////////////////////////////////////////////
|
|
class HGrid
|
|
{
|
|
public:
|
|
HGrid() {}
|
|
~HGrid();
|
|
|
|
void Init( const std::vector<Vect2D>& tabp, const std::vector<MGInt>& tabn );
|
|
void Generate();
|
|
void ExportTECTmp( FILE *f);
|
|
void WriteFrontTEC( const char name[]);
|
|
|
|
|
|
IterGCell CellBegin() { return mcolCell.begin(); }
|
|
IterGCell CellEnd() { return mcolCell.end(); }
|
|
|
|
protected:
|
|
// protected attributes
|
|
CollGPnt mcolPnt; // list of boundary grid points
|
|
CollGCell mcolCell; // list of cells
|
|
CollFro mcolFro;
|
|
|
|
// auxiliary attributes
|
|
IterGPnt mind1, mind2, mind3, mind4; //iterators to 4 corners of the bounding box
|
|
HRect mBox;
|
|
|
|
|
|
// protected methods for internal use
|
|
bool IsOutside( const Vect2D& vct);
|
|
bool IsBoxCorner( const IterGPnt& ipnt);
|
|
|
|
IterGPnt InsertPoint( HGrdPnt *gpnt);
|
|
IterGCell InsertCell( HGrdTri *gcell);
|
|
|
|
// UNSTRUCTURED GRID GENERATIUON
|
|
void CheckBoundIntegr();
|
|
void FlagOuterTris();
|
|
void InitTriangles(); // init. triangulation (2 cells)
|
|
void RemoveOuterTris();
|
|
|
|
bool CheckSwapTriangles( HGrdTri *ptri1, HGrdTri *ptri2);
|
|
void SwapTriangles( HGrdTri *ptri1, HGrdTri *ptri2, bool bgo = true);
|
|
|
|
bool CheckNeighb( IterGCell icl, CollFSeg& lstsg,
|
|
const Vect2D& vct, const IterGCell& ipvcl);
|
|
|
|
MGInt InsertPointIntoMesh( IterGPnt itr);
|
|
|
|
HFroSeg* NewFace( MGInt i, IterGCell icl = IterGCell());
|
|
|
|
// SOURCES !!!!!!
|
|
bool PointExists( const Vect2D& ip);
|
|
|
|
|
|
void CheckPoints( char st[]);
|
|
void CheckGrid();
|
|
};
|
|
//--------------------------------------------------------------------
|
|
|
|
|
|
|
|
inline IterGPnt HGrid::InsertPoint( HGrdPnt *gpnt)
|
|
{
|
|
return mcolPnt.insert( mcolPnt.end(), gpnt );
|
|
}
|
|
|
|
|
|
|
|
|
|
inline IterGCell HGrid::InsertCell( HGrdTri *gcell)
|
|
{
|
|
return mcolCell.insert( mcolCell.end(), gcell );
|
|
}
|
|
|
|
|
|
|
|
inline bool HGrid::IsBoxCorner( const IterGPnt& ipnt)
|
|
{
|
|
if ( ipnt == mind1 || ipnt == mind2 || ipnt == mind3 || ipnt == mind4 )
|
|
return true;
|
|
|
|
return false;
|
|
}
|
|
|
|
|
|
|
|
#endif // __HGRID_H__
|
|
|