Formatted ttl library to comply with KiCad coding policy.
This commit is contained in:
parent
a0fb4ed0c1
commit
6fa2f060fa
File diff suppressed because it is too large
Load Diff
|
@ -40,111 +40,152 @@
|
|||
#ifndef _HALF_EDGE_DART_
|
||||
#define _HALF_EDGE_DART_
|
||||
|
||||
|
||||
#include <ttl/halfedge/hetriang.h>
|
||||
|
||||
namespace hed
|
||||
{
|
||||
/**
|
||||
* \class Dart
|
||||
* \brief \b %Dart class for the half-edge data structure.
|
||||
*
|
||||
* See \ref api for a detailed description of how the member functions
|
||||
* should be implemented.
|
||||
*/
|
||||
class DART
|
||||
{
|
||||
EDGE_PTR m_edge;
|
||||
|
||||
namespace hed {
|
||||
/// Dart direction: true if dart is counterclockwise in face
|
||||
bool m_dir;
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------------------------
|
||||
// Dart class for the half-edge data structure
|
||||
//------------------------------------------------------------------------------------------------
|
||||
|
||||
/** \class Dart
|
||||
* \brief \b %Dart class for the half-edge data structure.
|
||||
*
|
||||
* See \ref api for a detailed description of how the member functions
|
||||
* should be implemented.
|
||||
*/
|
||||
|
||||
class Dart {
|
||||
|
||||
EdgePtr edge_;
|
||||
bool dir_; // true if dart is counterclockwise in face
|
||||
|
||||
public:
|
||||
public:
|
||||
/// Default constructor
|
||||
Dart() { dir_ = true; }
|
||||
DART()
|
||||
{
|
||||
m_dir = true;
|
||||
}
|
||||
|
||||
/// Constructor
|
||||
Dart(const EdgePtr& edge, bool dir = true) { edge_ = edge; dir_ = dir; }
|
||||
DART( const EDGE_PTR& aEdge, bool aDir = true )
|
||||
{
|
||||
m_edge = aEdge;
|
||||
m_dir = aDir;
|
||||
}
|
||||
|
||||
/// Copy constructor
|
||||
Dart(const Dart& dart) { edge_ = dart.edge_; dir_ = dart.dir_; }
|
||||
DART( const DART& aDart )
|
||||
{
|
||||
m_edge = aDart.m_edge;
|
||||
m_dir = aDart.m_dir;
|
||||
}
|
||||
|
||||
/// Destructor
|
||||
~Dart() {}
|
||||
~DART()
|
||||
{
|
||||
}
|
||||
|
||||
/// Assignment operator
|
||||
Dart& operator = (const Dart& dart) {
|
||||
if (this == &dart)
|
||||
DART& operator=( const DART& aDart )
|
||||
{
|
||||
if( this == &aDart )
|
||||
return *this;
|
||||
|
||||
m_edge = aDart.m_edge;
|
||||
m_dir = aDart.m_dir;
|
||||
|
||||
return *this;
|
||||
edge_ = dart.edge_;
|
||||
dir_ = dart.dir_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// Comparing dart objects
|
||||
bool operator==(const Dart& dart) const {
|
||||
if (dart.edge_ == edge_ && dart.dir_ == dir_)
|
||||
return true;
|
||||
return false;
|
||||
bool operator==( const DART& aDart ) const
|
||||
{
|
||||
return ( aDart.m_edge == m_edge && aDart.m_dir == m_dir );
|
||||
}
|
||||
|
||||
/// Comparing dart objects
|
||||
bool operator!=(const Dart& dart) const {
|
||||
return !(dart==*this);
|
||||
bool operator!=( const DART& aDart ) const
|
||||
{
|
||||
return !( aDart == *this );
|
||||
}
|
||||
|
||||
/// Maps the dart to a different node
|
||||
Dart& alpha0() { dir_ = !dir_; return *this; }
|
||||
DART& Alpha0()
|
||||
{
|
||||
m_dir = !m_dir;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// Maps the dart to a different edge
|
||||
Dart& alpha1() {
|
||||
if (dir_) {
|
||||
edge_ = edge_->getNextEdgeInFace()->getNextEdgeInFace();
|
||||
dir_ = false;
|
||||
}
|
||||
else {
|
||||
edge_ = edge_->getNextEdgeInFace();
|
||||
dir_ = true;
|
||||
}
|
||||
return *this;
|
||||
DART& Alpha1()
|
||||
{
|
||||
if( m_dir )
|
||||
{
|
||||
m_edge = m_edge->GetNextEdgeInFace()->GetNextEdgeInFace();
|
||||
m_dir = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_edge = m_edge->GetNextEdgeInFace();
|
||||
m_dir = true;
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// Maps the dart to a different triangle. \b Note: the dart is not changed if it is at the boundary!
|
||||
Dart& alpha2() {
|
||||
if (edge_->getTwinEdge()) {
|
||||
edge_ = edge_->getTwinEdge();
|
||||
dir_ = !dir_;
|
||||
}
|
||||
// else, the dart is at the boundary and should not be changed
|
||||
return *this;
|
||||
DART& Alpha2()
|
||||
{
|
||||
if( m_edge->GetTwinEdge() )
|
||||
{
|
||||
m_edge = m_edge->GetTwinEdge();
|
||||
m_dir = !m_dir;
|
||||
}
|
||||
|
||||
// else, the dart is at the boundary and should not be changed
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
// Utilities not required by TTL
|
||||
// -----------------------------
|
||||
|
||||
/** @name Utilities not required by TTL */
|
||||
//@{
|
||||
void Init( const EDGE_PTR& aEdge, bool aDir = true )
|
||||
{
|
||||
m_edge = aEdge;
|
||||
m_dir = aDir;
|
||||
}
|
||||
|
||||
void init(const EdgePtr& edge, bool dir = true) { edge_ = edge; dir_ = dir; }
|
||||
double X() const
|
||||
{
|
||||
return GetNode()->GetX();
|
||||
}
|
||||
|
||||
double x() const { return getNode()->GetX(); } // x-coordinate of source node
|
||||
double y() const { return getNode()->GetY(); } // y-coordinate of source node
|
||||
double Y() const
|
||||
{
|
||||
return GetNode()->GetY();
|
||||
}
|
||||
|
||||
bool isCounterClockWise() const { return dir_; }
|
||||
bool IsCCW() const
|
||||
{
|
||||
return m_dir;
|
||||
}
|
||||
|
||||
const NodePtr& getNode() const { return dir_ ? edge_->getSourceNode() : edge_->getTargetNode(); }
|
||||
const NodePtr& getOppositeNode() const { return dir_ ? edge_->getTargetNode() : edge_->getSourceNode(); }
|
||||
EdgePtr& getEdge() { return edge_; }
|
||||
const NODE_PTR& GetNode() const
|
||||
{
|
||||
return m_dir ? m_edge->GetSourceNode() : m_edge->GetTargetNode();
|
||||
}
|
||||
|
||||
const NODE_PTR& GetOppositeNode() const
|
||||
{
|
||||
return m_dir ? m_edge->GetTargetNode() : m_edge->GetSourceNode();
|
||||
}
|
||||
|
||||
EDGE_PTR& GetEdge()
|
||||
{
|
||||
return m_edge;
|
||||
}
|
||||
|
||||
//@} // End of Utilities not required by TTL
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
}; // End of hed namespace
|
||||
} // End of hed namespace
|
||||
|
||||
#endif
|
||||
|
|
|
@ -40,136 +40,149 @@
|
|||
#ifndef _HALF_EDGE_TRAITS_
|
||||
#define _HALF_EDGE_TRAITS_
|
||||
|
||||
|
||||
#include <ttl/halfedge/hetriang.h>
|
||||
#include <ttl/halfedge/hedart.h>
|
||||
|
||||
|
||||
namespace hed {
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------------------------
|
||||
// Traits class for the half-edge data structure
|
||||
//------------------------------------------------------------------------------------------------
|
||||
|
||||
/** \struct TTLtraits
|
||||
* \brief \b Traits class (static struct) for the half-edge data structure.
|
||||
*
|
||||
* The member functions are those required by different function templates
|
||||
* in the TTL. Documentation is given here to explain what actions
|
||||
* should be carried out on the actual data structure as required by the functions
|
||||
* in the \ref ttl namespace.
|
||||
*
|
||||
* The source code of \c %HeTraits.h shows how the traits class is implemented for the
|
||||
* half-edge data structure.
|
||||
*
|
||||
* \see \ref api
|
||||
*
|
||||
*/
|
||||
|
||||
struct TTLtraits {
|
||||
|
||||
/** The floating point type used in calculations
|
||||
* involving scalar products and cross products.
|
||||
*/
|
||||
typedef double real_type;
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------------------------
|
||||
// ------------------------------- Geometric Predicates Group ---------------------------------
|
||||
//----------------------------------------------------------------------------------------------
|
||||
namespace hed
|
||||
{
|
||||
/**
|
||||
* \struct TTLtraits
|
||||
* \brief \b Traits class (static struct) for the half-edge data structure.
|
||||
*
|
||||
* The member functions are those required by different function templates
|
||||
* in the TTL. Documentation is given here to explain what actions
|
||||
* should be carried out on the actual data structure as required by the functions
|
||||
* in the \ref ttl namespace.
|
||||
*
|
||||
* The source code of \c %HeTraits.h shows how the traits class is implemented for the
|
||||
* half-edge data structure.
|
||||
*
|
||||
* \see \ref api
|
||||
*/
|
||||
struct TTLtraits
|
||||
{
|
||||
/**
|
||||
* The floating point type used in calculations involving scalar products and cross products.
|
||||
*/
|
||||
typedef double REAL_TYPE;
|
||||
|
||||
/** @name Geometric Predicates */
|
||||
//@{
|
||||
/**
|
||||
* Scalar product between two 2D vectors represented as darts.\n
|
||||
*
|
||||
* ttl_util::scalarProduct2d can be used.
|
||||
*/
|
||||
static REAL_TYPE ScalarProduct2D( const DART& aV1, const DART& aV2 )
|
||||
{
|
||||
DART v10 = aV1;
|
||||
v10.Alpha0();
|
||||
|
||||
//----------------------------------------------------------------------------------------------
|
||||
/** Scalar product between two 2D vectors represented as darts.\n
|
||||
*
|
||||
* ttl_util::scalarProduct2d can be used.
|
||||
*/
|
||||
static real_type scalarProduct2d(const Dart& v1, const Dart& v2) {
|
||||
Dart v10 = v1; v10.alpha0();
|
||||
Dart v20 = v2; v20.alpha0();
|
||||
return ttl_util::scalarProduct2d(v10.x()-v1.x(), v10.y()-v1.y(),
|
||||
v20.x()-v2.x(), v20.y()-v2.y());
|
||||
DART v20 = aV2;
|
||||
v20.Alpha0();
|
||||
|
||||
return ttl_util::ScalarProduct2D( v10.X() - aV1.X(), v10.Y() - aV1.Y(),
|
||||
v20.X() - aV2.X(), v20.Y() - aV2.Y() );
|
||||
}
|
||||
|
||||
/**
|
||||
* Scalar product between two 2D vectors.
|
||||
* The first vector is represented by a dart \e v, and the second
|
||||
* vector has direction from the source node of \e v to the point \e p.\n
|
||||
*
|
||||
* ttl_util::ScalarProduct2D can be used.
|
||||
*/
|
||||
static REAL_TYPE ScalarProduct2D( const DART& aV, const NODE_PTR& aP )
|
||||
{
|
||||
DART d0 = aV;
|
||||
d0.Alpha0();
|
||||
|
||||
//----------------------------------------------------------------------------------------------
|
||||
/** Scalar product between two 2D vectors.
|
||||
* The first vector is represented by a dart \e v, and the second
|
||||
* vector has direction from the source node of \e v to the point \e p.\n
|
||||
*
|
||||
* ttl_util::scalarProduct2d can be used.
|
||||
*/
|
||||
static real_type scalarProduct2d(const Dart& v, const NodePtr& p) {
|
||||
Dart d0 = v; d0.alpha0();
|
||||
return ttl_util::scalarProduct2d(d0.x() - v.x(), d0.y() - v.y(),
|
||||
p->GetX() - v.x(), p->GetY() - v.y());
|
||||
return ttl_util::ScalarProduct2D( d0.X() - aV.X(), d0.Y() - aV.Y(),
|
||||
aP->GetX() - aV.X(), aP->GetY() - aV.Y() );
|
||||
}
|
||||
|
||||
/**
|
||||
* Cross product between two vectors in the plane represented as darts.
|
||||
* The z-component of the cross product is returned.\n
|
||||
*
|
||||
* ttl_util::CrossProduct2D can be used.
|
||||
*/
|
||||
static REAL_TYPE CrossProduct2D( const DART& aV1, const DART& aV2 )
|
||||
{
|
||||
DART v10 = aV1;
|
||||
v10.Alpha0();
|
||||
|
||||
//----------------------------------------------------------------------------------------------
|
||||
/** Cross product between two vectors in the plane represented as darts.
|
||||
* The z-component of the cross product is returned.\n
|
||||
*
|
||||
* ttl_util::crossProduct2d can be used.
|
||||
*/
|
||||
static real_type crossProduct2d(const Dart& v1, const Dart& v2) {
|
||||
Dart v10 = v1; v10.alpha0();
|
||||
Dart v20 = v2; v20.alpha0();
|
||||
return ttl_util::crossProduct2d(v10.x()-v1.x(), v10.y()-v1.y(),
|
||||
v20.x()-v2.x(), v20.y()-v2.y());
|
||||
DART v20 = aV2;
|
||||
v20.Alpha0();
|
||||
|
||||
return ttl_util::CrossProduct2D( v10.X() - aV1.X(), v10.Y() - aV1.Y(),
|
||||
v20.X() - aV2.X(), v20.Y() - aV2.Y() );
|
||||
}
|
||||
|
||||
/**
|
||||
* Cross product between two vectors in the plane.
|
||||
* The first vector is represented by a dart \e v, and the second
|
||||
* vector has direction from the source node of \e v to the point \e p.
|
||||
* The z-component of the cross product is returned.\n
|
||||
*
|
||||
* ttl_util::CrossProduct2d can be used.
|
||||
*/
|
||||
static REAL_TYPE CrossProduct2D( const DART& aV, const NODE_PTR& aP )
|
||||
{
|
||||
DART d0 = aV;
|
||||
d0.Alpha0();
|
||||
|
||||
//----------------------------------------------------------------------------------------------
|
||||
/** Cross product between two vectors in the plane.
|
||||
* The first vector is represented by a dart \e v, and the second
|
||||
* vector has direction from the source node of \e v to the point \e p.
|
||||
* The z-component of the cross product is returned.\n
|
||||
*
|
||||
* ttl_util::crossProduct2d can be used.
|
||||
*/
|
||||
static real_type crossProduct2d(const Dart& v, const NodePtr& p) {
|
||||
Dart d0 = v; d0.alpha0();
|
||||
return ttl_util::crossProduct2d(d0.x() - v.x(), d0.y() - v.y(),
|
||||
p->GetX() - v.x(), p->GetY() - v.y());
|
||||
return ttl_util::CrossProduct2D( d0.X() - aV.X(), d0.Y() - aV.Y(),
|
||||
aP->GetX() - aV.X(), aP->GetY() - aV.Y() );
|
||||
}
|
||||
|
||||
/**
|
||||
* Let \e n1 and \e n2 be the nodes associated with two darts, and let \e p
|
||||
* be a point in the plane. Return a positive value if \e n1, \e n2,
|
||||
* and \e p occur in counterclockwise order; a negative value if they occur
|
||||
* in clockwise order; and zero if they are collinear.
|
||||
*/
|
||||
static REAL_TYPE Orient2D( const DART& aN1, const DART& aN2, const NODE_PTR& aP )
|
||||
{
|
||||
REAL_TYPE pa[2];
|
||||
REAL_TYPE pb[2];
|
||||
REAL_TYPE pc[2];
|
||||
|
||||
//----------------------------------------------------------------------------------------------
|
||||
/** Let \e n1 and \e n2 be the nodes associated with two darts, and let \e p
|
||||
* be a point in the plane. Return a positive value if \e n1, \e n2,
|
||||
* and \e p occur in counterclockwise order; a negative value if they occur
|
||||
* in clockwise order; and zero if they are collinear.
|
||||
*/
|
||||
static real_type orient2d(const Dart& n1, const Dart& n2, const NodePtr& p) {
|
||||
real_type pa[2]; real_type pb[2]; real_type pc[2];
|
||||
pa[0] = n1.x(); pa[1] = n1.y();
|
||||
pb[0] = n2.x(); pb[1] = n2.y();
|
||||
pc[0] = p->GetX(); pc[1] = p->GetY();
|
||||
return ttl_util::orient2dfast(pa, pb, pc);
|
||||
pa[0] = aN1.X();
|
||||
pa[1] = aN1.Y();
|
||||
pb[0] = aN2.X();
|
||||
pb[1] = aN2.Y();
|
||||
pc[0] = aP->GetX();
|
||||
pc[1] = aP->GetY();
|
||||
|
||||
return ttl_util::Orient2DFast( pa, pb, pc );
|
||||
}
|
||||
|
||||
/**
|
||||
* This is the same predicate as represented with the function above,
|
||||
* but with a slighty different interface:
|
||||
* The last parameter is given as a dart where the source node of the dart
|
||||
* represents a point in the plane.
|
||||
* This function is required for constrained triangulation.
|
||||
*/
|
||||
static REAL_TYPE Orient2D( const DART& aN1, const DART& aN2, const DART& aP )
|
||||
{
|
||||
REAL_TYPE pa[2];
|
||||
REAL_TYPE pb[2];
|
||||
REAL_TYPE pc[2];
|
||||
|
||||
//----------------------------------------------------------------------------------------------
|
||||
/** This is the same predicate as represented with the function above,
|
||||
* but with a slighty different interface:
|
||||
* The last parameter is given as a dart where the source node of the dart
|
||||
* represents a point in the plane.
|
||||
* This function is required for constrained triangulation.
|
||||
*/
|
||||
static real_type orient2d(const Dart& n1, const Dart& n2, const Dart& p) {
|
||||
real_type pa[2]; real_type pb[2]; real_type pc[2];
|
||||
pa[0] = n1.x(); pa[1] = n1.y();
|
||||
pb[0] = n2.x(); pb[1] = n2.y();
|
||||
pc[0] = p.x(); pc[1] = p.y();
|
||||
return ttl_util::orient2dfast(pa, pb, pc);
|
||||
pa[0] = aN1.X();
|
||||
pa[1] = aN1.Y();
|
||||
pb[0] = aN2.X();
|
||||
pb[1] = aN2.Y();
|
||||
pc[0] = aP.X();
|
||||
pc[1] = aP.Y();
|
||||
|
||||
return ttl_util::Orient2DFast( pa, pb, pc );
|
||||
}
|
||||
|
||||
//@} // End of Geometric Predicates Group
|
||||
};
|
||||
};
|
||||
|
||||
}; // End of hed namespace
|
||||
|
||||
|
|
|
@ -42,11 +42,9 @@
|
|||
#ifndef _HE_TRIANG_H_
|
||||
#define _HE_TRIANG_H_
|
||||
|
||||
|
||||
#define TTL_USE_NODE_ID // Each node gets it's own unique id
|
||||
#define TTL_USE_NODE_FLAG // Each node gets a flag (can be set to true or false)
|
||||
|
||||
|
||||
#include <list>
|
||||
#include <vector>
|
||||
#include <iostream>
|
||||
|
@ -55,43 +53,40 @@
|
|||
#include <boost/shared_ptr.hpp>
|
||||
#include <boost/weak_ptr.hpp>
|
||||
|
||||
namespace ttl {
|
||||
class TriangulationHelper;
|
||||
namespace ttl
|
||||
{
|
||||
class TRIANGULATION_HELPER;
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
// The half-edge data structure
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
||||
namespace hed {
|
||||
// Helper typedefs
|
||||
class Node;
|
||||
class Edge;
|
||||
typedef boost::shared_ptr<Node> NodePtr;
|
||||
typedef boost::shared_ptr<Edge> EdgePtr;
|
||||
typedef boost::weak_ptr<Edge> EdgeWeakPtr;
|
||||
typedef std::vector<NodePtr> NodesContainer;
|
||||
|
||||
//------------------------------------------------------------------------------------------------
|
||||
// Node class for data structures
|
||||
//------------------------------------------------------------------------------------------------
|
||||
|
||||
/** \class Node
|
||||
* \brief \b Node class for data structures (Inherits from HandleId)
|
||||
*
|
||||
* \note
|
||||
* - To enable node IDs, TTL_USE_NODE_ID must be defined.
|
||||
* - To enable node flags, TTL_USE_NODE_FLAG must be defined.
|
||||
* - TTL_USE_NODE_ID and TTL_USE_NODE_FLAG should only be enabled if this functionality is
|
||||
* required by the application, because they increase the memory usage for each Node object.
|
||||
*/
|
||||
|
||||
class Node {
|
||||
/**
|
||||
* The half-edge data structure
|
||||
*/
|
||||
namespace hed
|
||||
{
|
||||
// Helper typedefs
|
||||
class NODE;
|
||||
class EDGE;
|
||||
typedef boost::shared_ptr<NODE> NODE_PTR;
|
||||
typedef boost::shared_ptr<EDGE> EDGE_PTR;
|
||||
typedef boost::weak_ptr<EDGE> EDGE_WEAK_PTR;
|
||||
typedef std::vector<NODE_PTR> NODES_CONTAINER;
|
||||
|
||||
/**
|
||||
* \class NODE
|
||||
* \brief \b Node class for data structures (Inherits from HandleId)
|
||||
*
|
||||
* \note
|
||||
* - To enable node IDs, TTL_USE_NODE_ID must be defined.
|
||||
* - To enable node flags, TTL_USE_NODE_FLAG must be defined.
|
||||
* - TTL_USE_NODE_ID and TTL_USE_NODE_FLAG should only be enabled if this functionality is
|
||||
* required by the application, because they increase the memory usage for each Node object.
|
||||
*/
|
||||
class NODE
|
||||
{
|
||||
protected:
|
||||
#ifdef TTL_USE_NODE_FLAG
|
||||
/// TTL_USE_NODE_FLAG must be defined
|
||||
bool flag_;
|
||||
bool m_flag;
|
||||
#endif
|
||||
|
||||
#ifdef TTL_USE_NODE_ID
|
||||
|
@ -99,303 +94,378 @@ protected:
|
|||
static int id_count;
|
||||
|
||||
/// A unique id for each node (TTL_USE_NODE_ID must be defined)
|
||||
int id_;
|
||||
int m_id;
|
||||
#endif
|
||||
|
||||
int x_, y_;
|
||||
/// Node coordinates
|
||||
int m_x, m_y;
|
||||
|
||||
unsigned int refCount_;
|
||||
/// Reference count
|
||||
unsigned int m_refCount;
|
||||
|
||||
public:
|
||||
/// Constructor
|
||||
Node( int x = 0, int y = 0 ) :
|
||||
NODE( int aX = 0, int aY = 0 ) :
|
||||
#ifdef TTL_USE_NODE_FLAG
|
||||
flag_( false ),
|
||||
m_flag( false ),
|
||||
#endif
|
||||
#ifdef TTL_USE_NODE_ID
|
||||
id_( id_count++ ),
|
||||
m_id( id_count++ ),
|
||||
#endif
|
||||
x_( x ), y_( y ), refCount_( 0 ) {}
|
||||
m_x( aX ), m_y( aY ), m_refCount( 0 )
|
||||
{
|
||||
}
|
||||
|
||||
/// Destructor
|
||||
~Node() {}
|
||||
~NODE() {}
|
||||
|
||||
/// Returns the x-coordinate
|
||||
int GetX() const { return x_; }
|
||||
int GetX() const
|
||||
{
|
||||
return m_x;
|
||||
}
|
||||
|
||||
/// Returns the y-coordinate
|
||||
int GetY() const { return y_; }
|
||||
int GetY() const
|
||||
{
|
||||
return m_y;
|
||||
}
|
||||
|
||||
#ifdef TTL_USE_NODE_ID
|
||||
/// Returns the id (TTL_USE_NODE_ID must be defined)
|
||||
int Id() const { return id_; }
|
||||
int Id() const
|
||||
{
|
||||
return m_id;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef TTL_USE_NODE_FLAG
|
||||
/// Sets the flag (TTL_USE_NODE_FLAG must be defined)
|
||||
void SetFlag(bool aFlag) { flag_ = aFlag; }
|
||||
void SetFlag( bool aFlag )
|
||||
{
|
||||
m_flag = aFlag;
|
||||
}
|
||||
|
||||
/// Returns the flag (TTL_USE_NODE_FLAG must be defined)
|
||||
const bool& GetFlag() const { return flag_; }
|
||||
const bool& GetFlag() const
|
||||
{
|
||||
return m_flag;
|
||||
}
|
||||
#endif
|
||||
|
||||
void IncRefCount() { refCount_++; }
|
||||
void DecRefCount() { refCount_--; }
|
||||
unsigned int GetRefCount() const { return refCount_; }
|
||||
}; // End of class Node
|
||||
void IncRefCount()
|
||||
{
|
||||
m_refCount++;
|
||||
}
|
||||
|
||||
void DecRefCount()
|
||||
{
|
||||
m_refCount--;
|
||||
}
|
||||
|
||||
unsigned int GetRefCount() const
|
||||
{
|
||||
return m_refCount;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------------------------
|
||||
// Edge class in the half-edge data structure
|
||||
//------------------------------------------------------------------------------------------------
|
||||
|
||||
/** \class Edge
|
||||
* \brief \b %Edge class in the in the half-edge data structure.
|
||||
*/
|
||||
|
||||
class Edge {
|
||||
public:
|
||||
/**
|
||||
* \class EDGE
|
||||
* \brief \b %Edge class in the in the half-edge data structure.
|
||||
*/
|
||||
class EDGE
|
||||
{
|
||||
public:
|
||||
/// Constructor
|
||||
Edge() : weight_(0), isLeadingEdge_(false) {}
|
||||
EDGE() : m_weight( 0 ), m_isLeadingEdge( false )
|
||||
{
|
||||
}
|
||||
|
||||
/// Destructor
|
||||
virtual ~Edge() {}
|
||||
virtual ~EDGE()
|
||||
{
|
||||
}
|
||||
|
||||
/// Sets the source node
|
||||
void setSourceNode(const NodePtr& node) { sourceNode_ = node; }
|
||||
void SetSourceNode( const NODE_PTR& aNode )
|
||||
{
|
||||
m_sourceNode = aNode;
|
||||
}
|
||||
|
||||
/// Sets the next edge in face
|
||||
void setNextEdgeInFace(const EdgePtr& edge) { nextEdgeInFace_ = edge; }
|
||||
void SetNextEdgeInFace( const EDGE_PTR& aEdge )
|
||||
{
|
||||
m_nextEdgeInFace = aEdge;
|
||||
}
|
||||
|
||||
/// Sets the twin edge
|
||||
void setTwinEdge(const EdgePtr& edge) { twinEdge_ = edge; }
|
||||
void SetTwinEdge( const EDGE_PTR& aEdge )
|
||||
{
|
||||
m_twinEdge = aEdge;
|
||||
}
|
||||
|
||||
/// Sets the edge as a leading edge
|
||||
void setAsLeadingEdge(bool val=true) { isLeadingEdge_ = val; }
|
||||
void SetAsLeadingEdge( bool aLeading = true )
|
||||
{
|
||||
m_isLeadingEdge = aLeading;
|
||||
}
|
||||
|
||||
/// Checks if an edge is a leading edge
|
||||
bool isLeadingEdge() const { return isLeadingEdge_; }
|
||||
bool IsLeadingEdge() const
|
||||
{
|
||||
return m_isLeadingEdge;
|
||||
}
|
||||
|
||||
/// Returns the twin edge
|
||||
EdgePtr getTwinEdge() const { return twinEdge_.lock(); };
|
||||
EDGE_PTR GetTwinEdge() const
|
||||
{
|
||||
return m_twinEdge.lock();
|
||||
}
|
||||
|
||||
void clearTwinEdge() { twinEdge_.reset(); }
|
||||
void ClearTwinEdge()
|
||||
{
|
||||
m_twinEdge.reset();
|
||||
}
|
||||
|
||||
/// Returns the next edge in face
|
||||
const EdgePtr& getNextEdgeInFace() const { return nextEdgeInFace_; }
|
||||
const EDGE_PTR& GetNextEdgeInFace() const
|
||||
{
|
||||
return m_nextEdgeInFace;
|
||||
}
|
||||
|
||||
/// Retuns the source node
|
||||
const NodePtr& getSourceNode() const { return sourceNode_; }
|
||||
const NODE_PTR& GetSourceNode() const
|
||||
{
|
||||
return m_sourceNode;
|
||||
}
|
||||
|
||||
/// Returns the target node
|
||||
virtual const NodePtr& getTargetNode() const { return nextEdgeInFace_->getSourceNode(); }
|
||||
|
||||
void setWeight( unsigned int weight ) { weight_ = weight; }
|
||||
|
||||
unsigned int getWeight() const { return weight_; }
|
||||
|
||||
void clear()
|
||||
virtual const NODE_PTR& GetTargetNode() const
|
||||
{
|
||||
sourceNode_.reset();
|
||||
nextEdgeInFace_.reset();
|
||||
return m_nextEdgeInFace->GetSourceNode();
|
||||
}
|
||||
|
||||
if( !twinEdge_.expired() )
|
||||
void SetWeight( unsigned int weight )
|
||||
{
|
||||
m_weight = weight;
|
||||
}
|
||||
|
||||
unsigned int GetWeight() const
|
||||
{
|
||||
return m_weight;
|
||||
}
|
||||
|
||||
void Clear()
|
||||
{
|
||||
m_sourceNode.reset();
|
||||
m_nextEdgeInFace.reset();
|
||||
|
||||
if( !m_twinEdge.expired() )
|
||||
{
|
||||
twinEdge_.lock()->clearTwinEdge();
|
||||
twinEdge_.reset();
|
||||
m_twinEdge.lock()->ClearTwinEdge();
|
||||
m_twinEdge.reset();
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
NodePtr sourceNode_;
|
||||
EdgeWeakPtr twinEdge_;
|
||||
EdgePtr nextEdgeInFace_;
|
||||
unsigned int weight_;
|
||||
bool isLeadingEdge_;
|
||||
}; // End of class Edge
|
||||
protected:
|
||||
NODE_PTR m_sourceNode;
|
||||
EDGE_WEAK_PTR m_twinEdge;
|
||||
EDGE_PTR m_nextEdgeInFace;
|
||||
unsigned int m_weight;
|
||||
bool m_isLeadingEdge;
|
||||
};
|
||||
|
||||
|
||||
/** \class EdgeMST
|
||||
* \brief \b Specialization of %Edge class to be used for Minimum Spanning Tree algorithm.
|
||||
/**
|
||||
* \class EDGE_MST
|
||||
* \brief \b Specialization of %EDGE class to be used for Minimum Spanning Tree algorithm.
|
||||
*/
|
||||
class EdgeMST : public Edge
|
||||
{
|
||||
private:
|
||||
NodePtr target_;
|
||||
class EDGE_MST : public EDGE
|
||||
{
|
||||
private:
|
||||
NODE_PTR m_target;
|
||||
|
||||
public:
|
||||
EdgeMST( const NodePtr& source, const NodePtr& target, unsigned int weight = 0 ) :
|
||||
target_(target)
|
||||
{ sourceNode_ = source; weight_ = weight; }
|
||||
|
||||
EdgeMST( const Edge& edge )
|
||||
public:
|
||||
EDGE_MST( const NODE_PTR& aSource, const NODE_PTR& aTarget, unsigned int aWeight = 0 ) :
|
||||
m_target( aTarget )
|
||||
{
|
||||
sourceNode_ = edge.getSourceNode();
|
||||
target_ = edge.getTargetNode();
|
||||
weight_ = edge.getWeight();
|
||||
m_sourceNode = aSource;
|
||||
m_weight = aWeight;
|
||||
}
|
||||
|
||||
~EdgeMST() {};
|
||||
EDGE_MST( const EDGE& edge )
|
||||
{
|
||||
m_sourceNode = edge.GetSourceNode();
|
||||
m_target = edge.GetTargetNode();
|
||||
m_weight = edge.GetWeight();
|
||||
}
|
||||
|
||||
~EDGE_MST()
|
||||
{
|
||||
}
|
||||
|
||||
/// @copydoc Edge::setSourceNode()
|
||||
virtual const NodePtr& getTargetNode() const { return target_; }
|
||||
};
|
||||
virtual const NODE_PTR& GetTargetNode() const
|
||||
{
|
||||
return m_target;
|
||||
}
|
||||
};
|
||||
|
||||
class DART; // Forward declaration (class in this namespace)
|
||||
|
||||
//------------------------------------------------------------------------------------------------
|
||||
class Dart; // Forward declaration (class in this namespace)
|
||||
/**
|
||||
* \class TRIANGULATION
|
||||
* \brief \b %Triangulation class for the half-edge data structure with adaption to TTL.
|
||||
*/
|
||||
class TRIANGULATION
|
||||
{
|
||||
protected:
|
||||
/// One half-edge for each arc
|
||||
std::list<EDGE_PTR> m_leadingEdges;
|
||||
|
||||
//------------------------------------------------------------------------------------------------
|
||||
// Triangulation class in the half-edge data structure
|
||||
//------------------------------------------------------------------------------------------------
|
||||
ttl::TRIANGULATION_HELPER* m_helper;
|
||||
|
||||
/** \class Triangulation
|
||||
* \brief \b %Triangulation class for the half-edge data structure with adaption to TTL.
|
||||
*/
|
||||
|
||||
class Triangulation {
|
||||
|
||||
protected:
|
||||
std::list<EdgePtr> leadingEdges_; // one half-edge for each arc
|
||||
|
||||
ttl::TriangulationHelper* helper;
|
||||
|
||||
void addLeadingEdge(EdgePtr& edge) {
|
||||
edge->setAsLeadingEdge();
|
||||
leadingEdges_.push_front( edge );
|
||||
void addLeadingEdge( EDGE_PTR& aEdge )
|
||||
{
|
||||
aEdge->SetAsLeadingEdge();
|
||||
m_leadingEdges.push_front( aEdge );
|
||||
}
|
||||
|
||||
bool removeLeadingEdgeFromList(EdgePtr& leadingEdge);
|
||||
bool removeLeadingEdgeFromList( EDGE_PTR& aLeadingEdge );
|
||||
|
||||
void cleanAll();
|
||||
|
||||
/** Swaps the edge associated with \e dart in the actual data structure.
|
||||
*
|
||||
* <center>
|
||||
* \image html swapEdge.gif
|
||||
* </center>
|
||||
*
|
||||
* \param dart
|
||||
* Some of the functions require a dart as output.
|
||||
* If this is required by the actual function, the dart should be delivered
|
||||
* back in a position as seen if it was glued to the edge when swapping (rotating)
|
||||
* the edge CCW; see the figure.
|
||||
*
|
||||
* \note
|
||||
* - If the edge is \e constrained, or if it should not be swapped for
|
||||
* some other reason, this function need not do the actual swap of the edge.
|
||||
* - Some functions in TTL require that \c swapEdge is implemented such that
|
||||
* darts outside the quadrilateral are not affected by the swap.
|
||||
*/
|
||||
void swapEdge(Dart& dart);
|
||||
*
|
||||
* <center>
|
||||
* \image html swapEdge.gif
|
||||
* </center>
|
||||
*
|
||||
* \param aDart
|
||||
* Some of the functions require a dart as output.
|
||||
* If this is required by the actual function, the dart should be delivered
|
||||
* back in a position as seen if it was glued to the edge when swapping (rotating)
|
||||
* the edge CCW; see the figure.
|
||||
*
|
||||
* \note
|
||||
* - If the edge is \e constrained, or if it should not be swapped for
|
||||
* some other reason, this function need not do the actual swap of the edge.
|
||||
* - Some functions in TTL require that \c swapEdge is implemented such that
|
||||
* darts outside the quadrilateral are not affected by the swap.
|
||||
*/
|
||||
void swapEdge( DART& aDart );
|
||||
|
||||
/** Splits the triangle associated with \e dart in the actual data structure into
|
||||
* three new triangles joining at \e point.
|
||||
*
|
||||
* <center>
|
||||
* \image html splitTriangle.gif
|
||||
* </center>
|
||||
*
|
||||
* \param dart
|
||||
* Output: A CCW dart incident with the new node; see the figure.
|
||||
*/
|
||||
void splitTriangle(Dart& dart, const NodePtr& point);
|
||||
/**
|
||||
* Splits the triangle associated with \e dart in the actual data structure into
|
||||
* three new triangles joining at \e point.
|
||||
*
|
||||
* <center>
|
||||
* \image html splitTriangle.gif
|
||||
* </center>
|
||||
*
|
||||
* \param aDart
|
||||
* Output: A CCW dart incident with the new node; see the figure.
|
||||
*/
|
||||
void splitTriangle( DART& aDart, const NODE_PTR& aPoint );
|
||||
|
||||
/** The reverse operation of TTLtraits::splitTriangle.
|
||||
* This function is only required for functions that involve
|
||||
* removal of interior nodes; see for example TrinagulationHelper::removeInteriorNode.
|
||||
*
|
||||
* <center>
|
||||
* \image html reverse_splitTriangle.gif
|
||||
* </center>
|
||||
*/
|
||||
void reverse_splitTriangle(Dart& dart);
|
||||
/**
|
||||
* The reverse operation of TTLtraits::splitTriangle.
|
||||
* This function is only required for functions that involve
|
||||
* removal of interior nodes; see for example TrinagulationHelper::RemoveInteriorNode.
|
||||
*
|
||||
* <center>
|
||||
* \image html reverse_splitTriangle.gif
|
||||
* </center>
|
||||
*/
|
||||
void reverseSplitTriangle( DART& aDart );
|
||||
|
||||
/** Removes a triangle with an edge at the boundary of the triangulation
|
||||
* in the actual data structure
|
||||
*/
|
||||
void removeBoundaryTriangle(Dart& d);
|
||||
/**
|
||||
* Removes a triangle with an edge at the boundary of the triangulation
|
||||
* in the actual data structure
|
||||
*/
|
||||
void removeBoundaryTriangle( DART& aDart );
|
||||
|
||||
public:
|
||||
public:
|
||||
/// Default constructor
|
||||
Triangulation();
|
||||
TRIANGULATION();
|
||||
|
||||
/// Copy constructor
|
||||
Triangulation(const Triangulation& tr);
|
||||
TRIANGULATION( const TRIANGULATION& aTriangulation );
|
||||
|
||||
/// Destructor
|
||||
~Triangulation();
|
||||
~TRIANGULATION();
|
||||
|
||||
/// Creates a Delaunay triangulation from a set of points
|
||||
void createDelaunay(NodesContainer::iterator first,
|
||||
NodesContainer::iterator last);
|
||||
void CreateDelaunay( NODES_CONTAINER::iterator aFirst, NODES_CONTAINER::iterator aLast );
|
||||
|
||||
/// Creates an initial Delaunay triangulation from two enclosing triangles
|
||||
// When using rectangular boundary - loop through all points and expand.
|
||||
// (Called from createDelaunay(...) when starting)
|
||||
EdgePtr initTwoEnclosingTriangles(NodesContainer::iterator first,
|
||||
NodesContainer::iterator last);
|
||||
|
||||
EDGE_PTR InitTwoEnclosingTriangles( NODES_CONTAINER::iterator aFirst,
|
||||
NODES_CONTAINER::iterator aLast );
|
||||
|
||||
// These two functions are required by TTL for Delaunay triangulation
|
||||
|
||||
/// Swaps the edge associated with diagonal
|
||||
void swapEdge(EdgePtr& diagonal);
|
||||
void SwapEdge( EDGE_PTR& aDiagonal );
|
||||
|
||||
/// Splits the triangle associated with edge into three new triangles joining at point
|
||||
EdgePtr splitTriangle(EdgePtr& edge, const NodePtr& point);
|
||||
|
||||
EDGE_PTR SplitTriangle( EDGE_PTR& aEdge, const NODE_PTR& aPoint );
|
||||
|
||||
// Functions required by TTL for removing nodes in a Delaunay triangulation
|
||||
|
||||
/// Removes the boundary triangle associated with edge
|
||||
void removeTriangle(EdgePtr& edge); // boundary triangle required
|
||||
void RemoveTriangle( EDGE_PTR& aEdge ); // boundary triangle required
|
||||
|
||||
/// The reverse operation of removeTriangle
|
||||
void reverse_splitTriangle(EdgePtr& edge);
|
||||
void ReverseSplitTriangle( EDGE_PTR& aEdge );
|
||||
|
||||
/// Creates an arbitrary CCW dart
|
||||
Dart createDart();
|
||||
DART CreateDart();
|
||||
|
||||
/// Returns a list of "triangles" (one leading half-edge for each triangle)
|
||||
const std::list<EdgePtr>& getLeadingEdges() const { return leadingEdges_; }
|
||||
const std::list<EDGE_PTR>& GetLeadingEdges() const
|
||||
{
|
||||
return m_leadingEdges;
|
||||
}
|
||||
|
||||
/// Returns the number of triangles
|
||||
int noTriangles() const { return (int)leadingEdges_.size(); }
|
||||
int NoTriangles() const
|
||||
{
|
||||
return (int) m_leadingEdges.size();
|
||||
}
|
||||
|
||||
/// Returns a list of half-edges (one half-edge for each arc)
|
||||
std::list<EdgePtr>* getEdges(bool skip_boundary_edges = false) const;
|
||||
std::list<EDGE_PTR>* GetEdges( bool aSkipBoundaryEdges = false ) const;
|
||||
|
||||
#ifdef TTL_USE_NODE_FLAG
|
||||
/// Sets flag in all the nodes
|
||||
void flagNodes(bool flag) const;
|
||||
void FlagNodes( bool aFlag ) const;
|
||||
|
||||
/// Returns a list of nodes. This function requires TTL_USE_NODE_FLAG to be defined. \see Node.
|
||||
std::list<NodePtr>* getNodes() const;
|
||||
std::list<NODE_PTR>* GetNodes() const;
|
||||
#endif
|
||||
|
||||
/// Swaps edges until the triangulation is Delaunay (constrained edges are not swapped)
|
||||
void optimizeDelaunay();
|
||||
void OptimizeDelaunay();
|
||||
|
||||
/// Checks if the triangulation is Delaunay
|
||||
bool checkDelaunay() const;
|
||||
bool CheckDelaunay() const;
|
||||
|
||||
/// Returns an arbitrary interior node (as the source node of the returned edge)
|
||||
EdgePtr getInteriorNode() const;
|
||||
EDGE_PTR GetInteriorNode() const;
|
||||
|
||||
EdgePtr getBoundaryEdgeInTriangle(const EdgePtr& e) const;
|
||||
EDGE_PTR GetBoundaryEdgeInTriangle( const EDGE_PTR& aEdge ) const;
|
||||
|
||||
/// Returns an arbitrary boundary edge
|
||||
EdgePtr getBoundaryEdge() const;
|
||||
EDGE_PTR GetBoundaryEdge() const;
|
||||
|
||||
/// Print edges for plotting with, e.g., gnuplot
|
||||
void printEdges(std::ofstream& os) const;
|
||||
|
||||
friend class ttl::TriangulationHelper;
|
||||
|
||||
}; // End of class Triangulation
|
||||
|
||||
void PrintEdges( std::ofstream& aOutput ) const;
|
||||
|
||||
friend class ttl::TRIANGULATION_HELPER;
|
||||
};
|
||||
}; // End of hed namespace
|
||||
|
||||
#endif
|
||||
|
|
2715
include/ttl/ttl.h
2715
include/ttl/ttl.h
File diff suppressed because it is too large
Load Diff
|
@ -3,11 +3,11 @@
|
|||
* Applied Mathematics, Norway.
|
||||
*
|
||||
* Contact information: E-mail: tor.dokken@sintef.no
|
||||
* SINTEF ICT, Department of Applied Mathematics,
|
||||
* SINTEF ICT, DeaPArtment of Applied Mathematics,
|
||||
* P.O. Box 124 Blindern,
|
||||
* 0314 Oslo, Norway.
|
||||
*
|
||||
* This file is part of TTL.
|
||||
* This file is aPArt of TTL.
|
||||
*
|
||||
* TTL is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
|
@ -16,7 +16,7 @@
|
|||
*
|
||||
* TTL is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* MERCHANTABILITY or FITNESS FOR A aPARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public
|
||||
|
@ -40,28 +40,22 @@
|
|||
#ifndef _TTL_UTIL_H_
|
||||
#define _TTL_UTIL_H_
|
||||
|
||||
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
|
||||
|
||||
#ifdef _MSC_VER
|
||||
# if _MSC_VER < 1300
|
||||
# include <minmax.h>
|
||||
# endif
|
||||
#endif
|
||||
|
||||
|
||||
//using namespace std;
|
||||
|
||||
|
||||
/** \brief Utilities
|
||||
*
|
||||
* This name space contains utility functions for TTL.\n
|
||||
* This name saPAce contains utility functions for TTL.\n
|
||||
*
|
||||
* Point and vector algebra such as scalar product and cross product
|
||||
* between vectors are implemented here.
|
||||
* These functions are required by functions in the \ref ttl namespace,
|
||||
* These functions are required by functions in the \ref ttl namesaPAce,
|
||||
* where they are assumed to be present in the \ref hed::TTLtraits "TTLtraits" class.
|
||||
* Thus, the user can call these functions from the traits class.
|
||||
* For efficiency reasons, the user may consider implementing these
|
||||
|
@ -77,67 +71,59 @@
|
|||
* ttl and \ref api
|
||||
*
|
||||
* \author
|
||||
* Øyvind Hjelle, oyvindhj@ifi.uio.no
|
||||
* <EFBFBD>yvind Hjelle, oyvindhj@ifi.uio.no
|
||||
*/
|
||||
|
||||
namespace ttl_util
|
||||
{
|
||||
/** @name Computational geometry */
|
||||
//@{
|
||||
/** Scalar product between two 2D vectors.
|
||||
*
|
||||
* \aPAr Returns:
|
||||
* \code
|
||||
* aDX1*aDX2 + aDY1*aDY2
|
||||
* \endcode
|
||||
*/
|
||||
template <class REAL_TYPE>
|
||||
REAL_TYPE ScalarProduct2D( REAL_TYPE aDX1, REAL_TYPE aDY1, REAL_TYPE aDX2, REAL_TYPE aDY2 )
|
||||
{
|
||||
return aDX1 * aDX2 + aDY1 * aDY2;
|
||||
}
|
||||
|
||||
namespace ttl_util {
|
||||
/** Cross product between two 2D vectors. (The z-component of the actual cross product.)
|
||||
*
|
||||
* \aPAr Returns:
|
||||
* \code
|
||||
* aDX1*aDY2 - aDY1*aDX2
|
||||
* \endcode
|
||||
*/
|
||||
template <class REAL_TYPE>
|
||||
REAL_TYPE CrossProduct2D( REAL_TYPE aDX1, REAL_TYPE aDY1, REAL_TYPE aDX2, REAL_TYPE aDY2 )
|
||||
{
|
||||
return aDX1 * aDY2 - aDY1 * aDX2;
|
||||
}
|
||||
|
||||
/** Returns a positive value if the 2D nodes/points \e aPA, \e aPB, and
|
||||
* \e aPC occur in counterclockwise order; a negative value if they occur
|
||||
* in clockwise order; and zero if they are collinear.
|
||||
*
|
||||
* \note
|
||||
* - This is a finite arithmetic fast version. It can be made more robust using
|
||||
* exact arithmetic schemes by Jonathan Richard Shewchuk. See
|
||||
* http://www-2.cs.cmu.edu/~quake/robust.html
|
||||
*/
|
||||
template <class REAL_TYPE>
|
||||
REAL_TYPE Orient2DFast( REAL_TYPE aPA[2], REAL_TYPE aPB[2], REAL_TYPE aPC[2] )
|
||||
{
|
||||
REAL_TYPE acx = aPA[0] - aPC[0];
|
||||
REAL_TYPE bcx = aPB[0] - aPC[0];
|
||||
REAL_TYPE acy = aPA[1] - aPC[1];
|
||||
REAL_TYPE bcy = aPB[1] - aPC[1];
|
||||
|
||||
//------------------------------------------------------------------------------------------------
|
||||
// ------------------------------ Computational Geometry Group ----------------------------------
|
||||
//------------------------------------------------------------------------------------------------
|
||||
|
||||
/** @name Computational geometry */
|
||||
//@{
|
||||
|
||||
//------------------------------------------------------------------------------------------------
|
||||
/** Scalar product between two 2D vectors.
|
||||
*
|
||||
* \par Returns:
|
||||
* \code
|
||||
* dx1*dx2 + dy1*dy2
|
||||
* \endcode
|
||||
*/
|
||||
template <class real_type>
|
||||
real_type scalarProduct2d(real_type dx1, real_type dy1, real_type dx2, real_type dy2) {
|
||||
return dx1*dx2 + dy1*dy2;
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------------------------
|
||||
/** Cross product between two 2D vectors. (The z-component of the actual cross product.)
|
||||
*
|
||||
* \par Returns:
|
||||
* \code
|
||||
* dx1*dy2 - dy1*dx2
|
||||
* \endcode
|
||||
*/
|
||||
template <class real_type>
|
||||
real_type crossProduct2d(real_type dx1, real_type dy1, real_type dx2, real_type dy2) {
|
||||
return dx1*dy2 - dy1*dx2;
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------------------------
|
||||
/** Returns a positive value if the 2D nodes/points \e pa, \e pb, and
|
||||
* \e pc occur in counterclockwise order; a negative value if they occur
|
||||
* in clockwise order; and zero if they are collinear.
|
||||
*
|
||||
* \note
|
||||
* - This is a finite arithmetic fast version. It can be made more robust using
|
||||
* exact arithmetic schemes by Jonathan Richard Shewchuk. See
|
||||
* http://www-2.cs.cmu.edu/~quake/robust.html
|
||||
*/
|
||||
template <class real_type>
|
||||
real_type orient2dfast(real_type pa[2], real_type pb[2], real_type pc[2]) {
|
||||
real_type acx = pa[0] - pc[0];
|
||||
real_type bcx = pb[0] - pc[0];
|
||||
real_type acy = pa[1] - pc[1];
|
||||
real_type bcy = pb[1] - pc[1];
|
||||
return acx * bcy - acy * bcx;
|
||||
}
|
||||
}
|
||||
|
||||
}; // End of ttl_util namespace scope
|
||||
} // namespace ttl_util
|
||||
|
||||
#endif // _TTL_UTIL_H_
|
||||
|
|
|
@ -68,7 +68,7 @@ bool sortDistance( const RN_NODE_PTR& aOrigin, const RN_NODE_PTR& aNode1,
|
|||
|
||||
bool sortWeight( const RN_EDGE_PTR& aEdge1, const RN_EDGE_PTR& aEdge2 )
|
||||
{
|
||||
return aEdge1->getWeight() < aEdge2->getWeight();
|
||||
return aEdge1->GetWeight() < aEdge2->GetWeight();
|
||||
}
|
||||
|
||||
|
||||
|
@ -92,7 +92,7 @@ bool operator!=( const RN_NODE_PTR& aFirst, const RN_NODE_PTR& aSecond )
|
|||
|
||||
bool isEdgeConnectingNode( const RN_EDGE_PTR& aEdge, const RN_NODE_PTR& aNode )
|
||||
{
|
||||
return aEdge->getSourceNode() == aNode || aEdge->getTargetNode() == aNode;
|
||||
return aEdge->GetSourceNode() == aNode || aEdge->GetTargetNode() == aNode;
|
||||
}
|
||||
|
||||
|
||||
|
@ -125,8 +125,8 @@ std::vector<RN_EDGE_PTR>* kruskalMST( RN_LINKS::RN_EDGE_LIST& aEdges,
|
|||
{
|
||||
RN_EDGE_PTR& dt = *aEdges.begin();
|
||||
|
||||
int srcTag = tags[dt->getSourceNode()];
|
||||
int trgTag = tags[dt->getTargetNode()];
|
||||
int srcTag = tags[dt->GetSourceNode()];
|
||||
int trgTag = tags[dt->GetTargetNode()];
|
||||
|
||||
// Check if by adding this edge we are going to join two different forests
|
||||
if( srcTag != trgTag )
|
||||
|
@ -139,7 +139,7 @@ std::vector<RN_EDGE_PTR>* kruskalMST( RN_LINKS::RN_EDGE_LIST& aEdges,
|
|||
// Move nodes that were marked with old tag to the list marked with the new tag
|
||||
cycles[srcTag].splice( cycles[srcTag].end(), cycles[trgTag] );
|
||||
|
||||
if( dt->getWeight() == 0 ) // Skip already existing connections (weight == 0)
|
||||
if( dt->GetWeight() == 0 ) // Skip already existing connections (weight == 0)
|
||||
{
|
||||
mstExpectedSize--;
|
||||
}
|
||||
|
@ -148,9 +148,9 @@ std::vector<RN_EDGE_PTR>* kruskalMST( RN_LINKS::RN_EDGE_LIST& aEdges,
|
|||
// Do a copy of edge, but make it RN_EDGE_MST. In contrary to RN_EDGE,
|
||||
// RN_EDGE_MST saves both source and target node and does not require any other
|
||||
// edges to exist for getting source/target nodes
|
||||
RN_EDGE_MST_PTR newEdge = boost::make_shared<RN_EDGE_MST>( dt->getSourceNode(),
|
||||
dt->getTargetNode(),
|
||||
dt->getWeight() );
|
||||
RN_EDGE_MST_PTR newEdge = boost::make_shared<RN_EDGE_MST>( dt->GetSourceNode(),
|
||||
dt->GetTargetNode(),
|
||||
dt->GetWeight() );
|
||||
mst->push_back( newEdge );
|
||||
++mstSize;
|
||||
}
|
||||
|
@ -169,8 +169,8 @@ std::vector<RN_EDGE_PTR>* kruskalMST( RN_LINKS::RN_EDGE_LIST& aEdges,
|
|||
|
||||
void RN_NET::validateEdge( RN_EDGE_PTR& aEdge )
|
||||
{
|
||||
RN_NODE_PTR source = aEdge->getSourceNode();
|
||||
RN_NODE_PTR target = aEdge->getTargetNode();
|
||||
RN_NODE_PTR source = aEdge->GetSourceNode();
|
||||
RN_NODE_PTR target = aEdge->GetTargetNode();
|
||||
bool valid = true;
|
||||
|
||||
// If any of nodes belonging to the edge has the flag set,
|
||||
|
@ -280,13 +280,13 @@ void RN_NET::compute()
|
|||
std::partial_sort_copy( boardNodes.begin(), boardNodes.end(), nodes.begin(), nodes.end() );
|
||||
|
||||
TRIANGULATOR triangulator;
|
||||
triangulator.createDelaunay( nodes.begin(), nodes.end() );
|
||||
boost::scoped_ptr<RN_LINKS::RN_EDGE_LIST> triangEdges( triangulator.getEdges() );
|
||||
triangulator.CreateDelaunay( nodes.begin(), nodes.end() );
|
||||
boost::scoped_ptr<RN_LINKS::RN_EDGE_LIST> triangEdges( triangulator.GetEdges() );
|
||||
|
||||
// Compute weight/distance for edges resulting from triangulation
|
||||
RN_LINKS::RN_EDGE_LIST::iterator eit, eitEnd;
|
||||
for( eit = (*triangEdges).begin(), eitEnd = (*triangEdges).end(); eit != eitEnd; ++eit )
|
||||
(*eit)->setWeight( getDistance( (*eit)->getSourceNode(), (*eit)->getTargetNode() ) );
|
||||
(*eit)->SetWeight( getDistance( (*eit)->GetSourceNode(), (*eit)->GetTargetNode() ) );
|
||||
|
||||
// Add the currently existing connections list to the results of triangulation
|
||||
std::copy( boardEdges.begin(), boardEdges.end(), std::front_inserter( *triangEdges ) );
|
||||
|
@ -508,8 +508,8 @@ void RN_NET::RemoveItem( const TRACK* aTrack )
|
|||
RN_EDGE_PTR& edge = m_tracks.at( aTrack );
|
||||
|
||||
// Save nodes, so they can be cleared later
|
||||
RN_NODE_PTR aBegin = edge->getSourceNode();
|
||||
RN_NODE_PTR aEnd = edge->getTargetNode();
|
||||
RN_NODE_PTR aBegin = edge->GetSourceNode();
|
||||
RN_NODE_PTR aEnd = edge->GetTargetNode();
|
||||
m_links.RemoveConnection( edge );
|
||||
|
||||
// Remove nodes associated with the edge. It is done in a safe way, there is a check
|
||||
|
@ -696,8 +696,8 @@ std::list<RN_NODE_PTR> RN_NET::GetNodes( const BOARD_CONNECTED_ITEM* aItem ) con
|
|||
const TRACK* track = static_cast<const TRACK*>( aItem );
|
||||
RN_EDGE_PTR edge = m_tracks.at( track );
|
||||
|
||||
nodes.push_back( edge->getSourceNode() );
|
||||
nodes.push_back( edge->getTargetNode() );
|
||||
nodes.push_back( edge->GetSourceNode() );
|
||||
nodes.push_back( edge->GetTargetNode() );
|
||||
}
|
||||
break;
|
||||
|
||||
|
|
|
@ -50,13 +50,13 @@ class ZONE_CONTAINER;
|
|||
class CPolyPt;
|
||||
|
||||
// Preserve KiCad coding style policy
|
||||
typedef hed::Node RN_NODE;
|
||||
typedef hed::NodePtr RN_NODE_PTR;
|
||||
typedef hed::Edge RN_EDGE;
|
||||
typedef hed::EdgePtr RN_EDGE_PTR;
|
||||
typedef hed::EdgeMST RN_EDGE_MST;
|
||||
typedef boost::shared_ptr<hed::EdgeMST> RN_EDGE_MST_PTR;
|
||||
typedef hed::Triangulation TRIANGULATOR;
|
||||
typedef hed::NODE RN_NODE;
|
||||
typedef hed::NODE_PTR RN_NODE_PTR;
|
||||
typedef hed::EDGE RN_EDGE;
|
||||
typedef hed::EDGE_PTR RN_EDGE_PTR;
|
||||
typedef hed::EDGE_MST RN_EDGE_MST;
|
||||
typedef hed::TRIANGULATION TRIANGULATOR;
|
||||
typedef boost::shared_ptr<hed::EDGE_MST> RN_EDGE_MST_PTR;
|
||||
|
||||
bool operator==( const RN_NODE_PTR& aFirst, const RN_NODE_PTR& aSecond );
|
||||
bool operator!=( const RN_NODE_PTR& aFirst, const RN_NODE_PTR& aSecond );
|
||||
|
|
|
@ -97,8 +97,8 @@ void RATSNEST_VIEWITEM::ViewDraw( int aLayer, GAL* aGal ) const
|
|||
|
||||
BOOST_FOREACH( const RN_EDGE_PTR& edge, *edges )
|
||||
{
|
||||
const RN_NODE_PTR& sourceNode = edge->getSourceNode();
|
||||
const RN_NODE_PTR& targetNode = edge->getTargetNode();
|
||||
const RN_NODE_PTR& sourceNode = edge->GetSourceNode();
|
||||
const RN_NODE_PTR& targetNode = edge->GetTargetNode();
|
||||
VECTOR2D source( sourceNode->GetX(), sourceNode->GetY() );
|
||||
VECTOR2D target( targetNode->GetX(), targetNode->GetY() );
|
||||
|
||||
|
|
Loading…
Reference in New Issue