Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
K
kicad-source-mirror
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Commits
Open sidebar
Elphel
kicad-source-mirror
Commits
a10d918c
Commit
a10d918c
authored
Jan 27, 2014
by
Maciej Suminski
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Thread-safe version of Delaunay triangulation.
parent
fe97521b
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
317 additions
and
321 deletions
+317
-321
hetriang.cpp
common/geometry/hetriang.cpp
+57
-15
hetraits.h
include/ttl/halfedge/hetraits.h
+0
-124
hetriang.h
include/ttl/halfedge/hetriang.h
+67
-11
ttl.h
include/ttl/ttl.h
+158
-139
ttl_constr.h
include/ttl/ttl_constr.h
+34
-31
ratsnest_data.cpp
pcbnew/ratsnest_data.cpp
+1
-1
No files found.
common/geometry/hetriang.cpp
View file @
a10d918c
...
...
@@ -51,8 +51,6 @@ using namespace hed;
using
namespace
std
;
Triangulation
*
TTLtraits
::
triang_
=
NULL
;
#ifdef TTL_USE_NODE_ID
int
Node
::
id_count
=
0
;
#endif
...
...
@@ -164,11 +162,30 @@ EdgePtr Triangulation::initTwoEnclosingTriangles(NodesContainer::iterator first,
}
//--------------------------------------------------------------------------------------------------
Triangulation
::
Triangulation
()
{
helper
=
new
ttl
::
TriangulationHelper
(
*
this
);
}
//--------------------------------------------------------------------------------------------------
Triangulation
::
Triangulation
(
const
Triangulation
&
tr
)
{
std
::
cout
<<
"Triangulation: Copy constructor not present - EXIT."
;
exit
(
-
1
);
}
//--------------------------------------------------------------------------------------------------
Triangulation
::~
Triangulation
()
{
cleanAll
();
delete
helper
;
}
//--------------------------------------------------------------------------------------------------
void
Triangulation
::
createDelaunay
(
NodesContainer
::
iterator
first
,
NodesContainer
::
iterator
last
)
{
TTLtraits
::
triang_
=
this
;
cleanAll
();
EdgePtr
bedge
=
initTwoEnclosingTriangles
(
first
,
last
);
...
...
@@ -178,7 +195,7 @@ void Triangulation::createDelaunay(NodesContainer::iterator first,
NodesContainer
::
iterator
it
;
for
(
it
=
first
;
it
!=
last
;
++
it
)
{
ttl
::
insertNode
<
TTLtraits
>
(
d_iter
,
*
it
);
helper
->
insertNode
<
TTLtraits
>
(
d_iter
,
*
it
);
}
// In general (e.g. for the triangle based data structure), the initial dart
...
...
@@ -189,7 +206,7 @@ void Triangulation::createDelaunay(NodesContainer::iterator first,
// triangle "outside" the triangulation.)
// Assumes rectangular domain
ttl
::
removeRectangularBoundary
<
TTLtraits
>
(
dc
);
helper
->
removeRectangularBoundary
<
TTLtraits
>
(
dc
);
}
...
...
@@ -269,7 +286,7 @@ cout << "Iterate boundary 2" << endl;
Dart dart_iter = dart;
do {
if (
ttl::
isBoundaryEdge(dart_iter))
if (
helper->
isBoundaryEdge(dart_iter))
dart_iter.alpha0().alpha1();
else
dart_iter.alpha2().alpha1();
...
...
@@ -322,6 +339,31 @@ void Triangulation::cleanAll() {
}
//--------------------------------------------------------------------------------------------------
void
Triangulation
::
swapEdge
(
Dart
&
dart
)
{
if
(
!
dart
.
getEdge
()
->
isConstrained
())
swapEdge
(
dart
.
getEdge
());
}
//--------------------------------------------------------------------------------------------------
void
Triangulation
::
splitTriangle
(
Dart
&
dart
,
NodePtr
point
)
{
EdgePtr
edge
=
splitTriangle
(
dart
.
getEdge
(),
point
);
dart
.
init
(
edge
);
}
//--------------------------------------------------------------------------------------------------
void
Triangulation
::
reverse_splitTriangle
(
Dart
&
dart
)
{
reverse_splitTriangle
(
dart
.
getEdge
());
}
//--------------------------------------------------------------------------------------------------
void
Triangulation
::
removeBoundaryTriangle
(
Dart
&
d
)
{
removeTriangle
(
d
.
getEdge
());
}
#ifdef TTL_USE_NODE_FLAG
//--------------------------------------------------------------------------------------------------
// This is a "template" for accessing all nodes (but multiple tests)
...
...
@@ -486,7 +528,7 @@ void Triangulation::swapEdge(EdgePtr& diagonal) {
// Note that diagonal is both input and output and it is always
// kept in counterclockwise direction (this is not required by all
// f
inctions in ttl::
now)
// f
unctions in TriangulationHelper
now)
// Swap by rotating counterclockwise
// Use the same objects - no deletion or new objects
...
...
@@ -567,7 +609,7 @@ bool Triangulation::checkDelaunay() const {
// only one of the half-edges
if
(
!
twinedge
||
(
size_t
)
edge
.
get
()
>
(
size_t
)
twinedge
.
get
())
{
Dart
dart
(
edge
);
if
(
ttl
::
swapTestDelaunay
<
TTLtraits
>
(
dart
))
{
if
(
helper
->
swapTestDelaunay
<
TTLtraits
>
(
dart
))
{
noNotDelaunay
++
;
//printEdge(dart,os); os << "\n";
...
...
@@ -610,7 +652,7 @@ void Triangulation::optimizeDelaunay() {
Dart
dart
(
edge
);
// Constrained edges should not be swapped
if
(
!
edge
->
isConstrained
()
&&
ttl
::
swapTestDelaunay
<
TTLtraits
>
(
dart
,
cycling_check
))
{
if
(
!
edge
->
isConstrained
()
&&
helper
->
swapTestDelaunay
<
TTLtraits
>
(
dart
,
cycling_check
))
{
optimal
=
false
;
swapEdge
(
edge
);
}
...
...
@@ -632,7 +674,7 @@ EdgePtr Triangulation::getInteriorNode() const {
for
(
int
i
=
0
;
i
<
3
;
++
i
)
{
if
(
edge
->
getTwinEdge
())
{
if
(
!
ttl
::
isBoundaryNode
(
Dart
(
edge
)))
if
(
!
helper
->
isBoundaryNode
(
Dart
(
edge
)))
return
edge
;
}
edge
=
edge
->
getNextEdgeInFace
();
...
...
@@ -643,18 +685,18 @@ EdgePtr Triangulation::getInteriorNode() const {
//--------------------------------------------------------------------------------------------------
static
EdgePtr
getBoundaryEdgeInTriangle
(
const
EdgePtr
&
e
)
{
EdgePtr
Triangulation
::
getBoundaryEdgeInTriangle
(
const
EdgePtr
&
e
)
const
{
EdgePtr
edge
=
e
;
if
(
ttl
::
isBoundaryEdge
(
Dart
(
edge
)))
if
(
helper
->
isBoundaryEdge
(
Dart
(
edge
)))
return
edge
;
edge
=
edge
->
getNextEdgeInFace
();
if
(
ttl
::
isBoundaryEdge
(
Dart
(
edge
)))
if
(
helper
->
isBoundaryEdge
(
Dart
(
edge
)))
return
edge
;
edge
=
edge
->
getNextEdgeInFace
();
if
(
ttl
::
isBoundaryEdge
(
Dart
(
edge
)))
if
(
helper
->
isBoundaryEdge
(
Dart
(
edge
)))
return
edge
;
return
EdgePtr
();
...
...
include/ttl/halfedge/hetraits.h
View file @
a10d918c
...
...
@@ -69,9 +69,6 @@ namespace hed {
struct
TTLtraits
{
// The actual triangulation object
static
Triangulation
*
triang_
;
/** The floating point type used in calculations
* involving scalar products and cross products.
*/
...
...
@@ -172,127 +169,6 @@ namespace hed {
}
//@} // End of Geometric Predicates Group
// A rationale for directing these functions to traits is:
// e.g., constraints
//----------------------------------------------------------------------------------------------
/* Checks if the edge associated with \e dart should be swapped
* according to the Delaunay criterion.<br>
*
* \note
* This function is also present in the TTL as ttl::swapTestDelaunay.<br>
* Thus, the function can be implemented simply as:
* \code
* { return ttl::swapTestDelaunay<TTLtraits>(dart); }
* \endcode
*/
//static bool swapTestDelaunay(const Dart& dart) {
// return ttl::swapTestDelaunay<TTLtraits>(dart);
//}
//----------------------------------------------------------------------------------------------
/* Checks if the edge associated with \e dart can be swapped, i.e.,
* if the edge is a diagonal in a (strictly) convex quadrilateral.
* This function is also present as ttl::swappableEdge.
*/
//static bool swappableEdge(const Dart& dart) {
// return ttl::swappableEdge<TTLtraits>(dart);
//}
//----------------------------------------------------------------------------------------------
/* Checks if the edge associated with \e dart should be \e fixed, meaning
* that it should never be swapped. ??? Use when constraints.
*/
//static bool fixedEdge(const Dart& dart) {
// return dart.getEdge()->isConstrained();
//}
//----------------------------------------------------------------------------------------------
// ----------------------- Functions for Delaunay Triangulation Group -------------------------
//----------------------------------------------------------------------------------------------
/** @name Functions for Delaunay Triangulation */
//@{
//----------------------------------------------------------------------------------------------
/** 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.
*/
static
void
swapEdge
(
Dart
&
dart
)
{
if
(
!
dart
.
getEdge
()
->
isConstrained
())
triang_
->
swapEdge
(
dart
.
getEdge
());
}
//----------------------------------------------------------------------------------------------
/** 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.
*/
static
void
splitTriangle
(
Dart
&
dart
,
NodePtr
point
)
{
EdgePtr
edge
=
triang_
->
splitTriangle
(
dart
.
getEdge
(),
point
);
dart
.
init
(
edge
);
}
//@} // End of Functions for Delaunay Triangulation group
//----------------------------------------------------------------------------------------------
// --------------------------- Functions for removing nodes Group -----------------------------
//----------------------------------------------------------------------------------------------
/** @name Functions for removing nodes */
//@{
//----------------------------------------------------------------------------------------------
/** The reverse operation of TTLtraits::splitTriangle.
* This function is only required for functions that involve
* removal of interior nodes; see for example ttl::removeInteriorNode.
*
* <center>
* \image html reverse_splitTriangle.gif
* </center>
*/
static
void
reverse_splitTriangle
(
Dart
&
dart
)
{
triang_
->
reverse_splitTriangle
(
dart
.
getEdge
());
}
//----------------------------------------------------------------------------------------------
/** Removes a triangle with an edge at the boundary of the triangulation
* in the actual data structure
*/
static
void
removeBoundaryTriangle
(
Dart
&
d
)
{
triang_
->
removeTriangle
(
d
.
getEdge
());
}
//@} // End of Functions for removing nodes Group
};
};
// End of hed namespace
...
...
include/ttl/halfedge/hetriang.h
View file @
a10d918c
...
...
@@ -51,10 +51,13 @@
#include <vector>
#include <iostream>
#include <fstream>
#include <ttl/ttl.h>
#include <ttl/ttl_util.h>
#include <boost/shared_ptr.hpp>
namespace
ttl
{
class
TriangulationHelper
;
};
//--------------------------------------------------------------------------------------------------
// The half-edge data structure
//--------------------------------------------------------------------------------------------------
...
...
@@ -242,26 +245,75 @@ public:
class
Triangulation
{
protected
:
list
<
EdgePtr
>
leadingEdges_
;
// one half-edge for each arc
std
::
list
<
EdgePtr
>
leadingEdges_
;
// one half-edge for each arc
ttl
::
TriangulationHelper
*
helper
;
void
addLeadingEdge
(
EdgePtr
&
edge
)
{
edge
->
setAsLeadingEdge
();
leadingEdges_
.
push_front
(
edge
);
}
bool
removeLeadingEdgeFromList
(
EdgePtr
&
leadingEdge
);
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
);
/** 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
,
NodePtr
point
);
/** 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
);
/** Removes a triangle with an edge at the boundary of the triangulation
* in the actual data structure
*/
void
removeBoundaryTriangle
(
Dart
&
d
);
public
:
/// Default constructor
Triangulation
()
{}
Triangulation
()
;
/// Copy constructor
Triangulation
(
const
Triangulation
&
tr
)
{
std
::
cout
<<
"Triangulation: Copy constructor not present - EXIT."
;
exit
(
-
1
);
}
Triangulation
(
const
Triangulation
&
tr
);
/// Destructor
~
Triangulation
()
{
cleanAll
();
}
~
Triangulation
()
;
/// Creates a Delaunay triangulation from a set of points
void
createDelaunay
(
NodesContainer
::
iterator
first
,
...
...
@@ -295,20 +347,20 @@ public:
Dart
createDart
();
/// Returns a list of "triangles" (one leading half-edge for each triangle)
const
list
<
EdgePtr
>&
getLeadingEdges
()
const
{
return
leadingEdges_
;
}
const
std
::
list
<
EdgePtr
>&
getLeadingEdges
()
const
{
return
leadingEdges_
;
}
/// Returns the number of triangles
int
noTriangles
()
const
{
return
(
int
)
leadingEdges_
.
size
();
}
/// Returns a list of half-edges (one half-edge for each arc)
list
<
EdgePtr
>*
getEdges
(
bool
skip_boundary_edges
=
false
)
const
;
std
::
list
<
EdgePtr
>*
getEdges
(
bool
skip_boundary_edges
=
false
)
const
;
#ifdef TTL_USE_NODE_FLAG
/// Sets flag in all the nodes
void
flagNodes
(
bool
flag
)
const
;
/// Returns a list of nodes. This function requires TTL_USE_NODE_FLAG to be defined. \see Node.
list
<
NodePtr
>*
getNodes
()
const
;
std
::
list
<
NodePtr
>*
getNodes
()
const
;
#endif
/// Swaps edges until the triangulation is Delaunay (constrained edges are not swapped)
...
...
@@ -320,12 +372,16 @@ public:
/// Returns an arbitrary interior node (as the source node of the returned edge)
EdgePtr
getInteriorNode
()
const
;
EdgePtr
getBoundaryEdgeInTriangle
(
const
EdgePtr
&
e
)
const
;
/// Returns an arbitrary boundary edge
EdgePtr
getBoundaryEdge
()
const
;
/// Print edges for plotting with, e.g., gnuplot
void
printEdges
(
std
::
ofstream
&
os
)
const
;
friend
class
ttl
::
TriangulationHelper
;
};
// End of class Triangulation
...
...
include/ttl/ttl.h
View file @
a10d918c
...
...
@@ -52,8 +52,6 @@
}
#endif
using
std
::
list
;
// Next on TOPOLOGY:
// - get triangle strips
...
...
@@ -102,7 +100,7 @@
* - \e CW - clockwise
* - \e 0_orbit, \e 1_orbit and \e 2_orbit: A sequence of darts around
* a node, around an edge and in a triangle respectively;
* see
ttl::get_0_orbit_interior and ttl::
get_0_orbit_boundary
* see
get_0_orbit_interior and
get_0_orbit_boundary
* - \e arc - In a triangulation an arc is equivalent with an edge
*
* \see
...
...
@@ -115,15 +113,15 @@
namespace
ttl
{
class
TriangulationHelper
{
#ifndef DOXYGEN_SHOULD_SKIP_THIS
//------------------------------------------------------------------------------------------------
// ----------------------------------- Forward declarations -------------------------------------
//------------------------------------------------------------------------------------------------
#if ((_MSC_VER > 0) && (_MSC_VER < 1300))
#else
public
:
TriangulationHelper
(
hed
::
Triangulation
&
triang
)
:
triangulation
(
triang
)
{
}
// Delaunay Triangulation
// ----------------------
template
<
class
TraitsType
,
class
DartType
,
class
PointType
>
...
...
@@ -145,55 +143,55 @@ namespace ttl {
// Topological and Geometric Queries
// ---------------------------------
template
<
class
TraitsType
,
class
PointType
,
class
DartType
>
bool
locateFaceSimplest
(
const
PointType
&
point
,
DartType
&
dart
);
static
bool
locateFaceSimplest
(
const
PointType
&
point
,
DartType
&
dart
);
template
<
class
TraitsType
,
class
PointType
,
class
DartType
>
bool
locateTriangle
(
const
PointType
&
point
,
DartType
&
dart
);
static
bool
locateTriangle
(
const
PointType
&
point
,
DartType
&
dart
);
template
<
class
TraitsType
,
class
PointType
,
class
DartType
>
bool
inTriangleSimplest
(
const
PointType
&
point
,
const
DartType
&
dart
);
static
bool
inTriangleSimplest
(
const
PointType
&
point
,
const
DartType
&
dart
);
template
<
class
TraitsType
,
class
PointType
,
class
DartType
>
bool
inTriangle
(
const
PointType
&
point
,
const
DartType
&
dart
);
static
bool
inTriangle
(
const
PointType
&
point
,
const
DartType
&
dart
);
template
<
class
DartType
,
class
DartListType
>
void
getBoundary
(
const
DartType
&
dart
,
DartListType
&
boundary
);
static
void
getBoundary
(
const
DartType
&
dart
,
DartListType
&
boundary
);
template
<
class
DartType
>
bool
isBoundaryEdge
(
const
DartType
&
dart
);
static
bool
isBoundaryEdge
(
const
DartType
&
dart
);
template
<
class
DartType
>
bool
isBoundaryFace
(
const
DartType
&
dart
);
static
bool
isBoundaryFace
(
const
DartType
&
dart
);
template
<
class
DartType
>
bool
isBoundaryNode
(
const
DartType
&
dart
);
static
bool
isBoundaryNode
(
const
DartType
&
dart
);
template
<
class
DartType
>
int
getDegreeOfNode
(
const
DartType
&
dart
);
static
int
getDegreeOfNode
(
const
DartType
&
dart
);
template
<
class
DartType
,
class
DartListType
>
void
get_0_orbit_interior
(
const
DartType
&
dart
,
DartListType
&
orbit
);
static
void
get_0_orbit_interior
(
const
DartType
&
dart
,
DartListType
&
orbit
);
template
<
class
DartType
,
class
DartListType
>
void
get_0_orbit_boundary
(
const
DartType
&
dart
,
DartListType
&
orbit
);
static
void
get_0_orbit_boundary
(
const
DartType
&
dart
,
DartListType
&
orbit
);
template
<
class
DartType
>
bool
same_0_orbit
(
const
DartType
&
d1
,
const
DartType
&
d2
);
static
bool
same_0_orbit
(
const
DartType
&
d1
,
const
DartType
&
d2
);
template
<
class
DartType
>
bool
same_1_orbit
(
const
DartType
&
d1
,
const
DartType
&
d2
);
static
bool
same_1_orbit
(
const
DartType
&
d1
,
const
DartType
&
d2
);
template
<
class
DartType
>
bool
same_2_orbit
(
const
DartType
&
d1
,
const
DartType
&
d2
);
static
bool
same_2_orbit
(
const
DartType
&
d1
,
const
DartType
&
d2
);
template
<
class
TraitsType
,
class
DartType
>
bool
swappableEdge
(
const
DartType
&
dart
,
bool
allowDegeneracy
=
false
);
static
bool
swappableEdge
(
const
DartType
&
dart
,
bool
allowDegeneracy
=
false
);
template
<
class
DartType
>
void
positionAtNextBoundaryEdge
(
DartType
&
dart
);
static
void
positionAtNextBoundaryEdge
(
DartType
&
dart
);
template
<
class
TraitsType
,
class
DartType
>
bool
convexBoundary
(
const
DartType
&
dart
);
static
bool
convexBoundary
(
const
DartType
&
dart
);
// Utilities for Delaunay Triangulation
...
...
@@ -205,7 +203,7 @@ namespace ttl {
void
optimizeDelaunay
(
DartListType
&
elist
,
const
typename
DartListType
::
iterator
end
);
template
<
class
TraitsType
,
class
DartType
>
bool
swapTestDelaunay
(
const
DartType
&
dart
,
bool
cycling_check
=
false
);
bool
swapTestDelaunay
(
const
DartType
&
dart
,
bool
cycling_check
=
false
)
const
;
template
<
class
TraitsType
,
class
DartType
>
void
recSwapDelaunay
(
DartType
&
diagonal
);
...
...
@@ -223,9 +221,29 @@ namespace ttl {
// Constrained Triangulation
// -------------------------
template
<
class
TraitsType
,
class
DartType
>
DartType
insertConstraint
(
DartType
&
dstart
,
DartType
&
dend
,
bool
optimize_delaunay
);
#endif
static
DartType
insertConstraint
(
DartType
&
dstart
,
DartType
&
dend
,
bool
optimize_delaunay
);
private
:
hed
::
Triangulation
&
triangulation
;
template
<
class
TraitsType
,
class
ForwardIterator
,
class
DartType
>
void
insertNodes
(
ForwardIterator
first
,
ForwardIterator
last
,
DartType
&
dart
);
template
<
class
TopologyElementType
,
class
DartType
>
static
bool
isMemberOfFace
(
const
TopologyElementType
&
topologyElement
,
const
DartType
&
dart
);
template
<
class
TraitsType
,
class
NodeType
,
class
DartType
>
static
bool
locateFaceWithNode
(
const
NodeType
&
node
,
DartType
&
dart_iter
);
template
<
class
DartType
>
static
void
getAdjacentTriangles
(
const
DartType
&
dart
,
DartType
&
t1
,
DartType
&
t2
,
DartType
&
t3
);
template
<
class
DartType
>
static
void
getNeighborNodes
(
const
DartType
&
dart
,
std
::
list
<
DartType
>&
node_list
,
bool
&
boundary
);
template
<
class
TraitsType
,
class
DartType
>
static
bool
degenerateTriangle
(
const
DartType
&
dart
);
};
#endif // DOXYGEN_SHOULD_SKIP_THIS
...
...
@@ -245,7 +263,7 @@ namespace ttl {
* can be created as two triangles forming a rectangle that contains
* all the points.
* After \c insertNode has been called repeatedly with all the points,
*
ttl::
removeRectangularBoundary can be called to remove triangles
* removeRectangularBoundary can be called to remove triangles
* at the boundary of the triangulation so that the boundary
* form the convex hull of the points.
*
...
...
@@ -268,19 +286,19 @@ namespace ttl {
* - \ref hed::TTLtraits::splitTriangle "TraitsType::splitTriangle" (DartType&, const PointType&)
*
* \using
* -
ttl::
locateTriangle
* -
ttl::
recSwapDelaunay
* - locateTriangle
* - recSwapDelaunay
*
* \note
* - For efficiency reasons \e dart should be close to the insertion \e point.
*
* \see
*
ttl::
removeRectangularBoundary
* removeRectangularBoundary
*/
template
<
class
TraitsType
,
class
DartType
,
class
PointType
>
bool
insertNode
(
DartType
&
dart
,
PointType
&
point
)
{
bool
TriangulationHelper
::
insertNode
(
DartType
&
dart
,
PointType
&
point
)
{
bool
found
=
ttl
::
locateTriangle
<
TraitsType
>
(
point
,
dart
);
bool
found
=
locateTriangle
<
TraitsType
>
(
point
,
dart
);
if
(
!
found
)
{
#ifdef DEBUG_TTL
cout
<<
"ERROR: Triangulation::insertNode: NO triangle found. /n"
;
...
...
@@ -289,7 +307,7 @@ namespace ttl {
}
// ??? can we hide the dart? this is not possible if one triangle only
TraitsType
::
splitTriangle
(
dart
,
point
);
triangulation
.
splitTriangle
(
dart
,
point
);
DartType
d1
=
dart
;
d1
.
alpha2
().
alpha1
().
alpha2
().
alpha0
().
alpha1
();
...
...
@@ -304,14 +322,14 @@ namespace ttl {
//DartType dsav = d3;
d3
.
alpha0
().
alpha1
();
//if (!TraitsType::fixedEdge(d1) && !
ttl::
isBoundaryEdge(d1)) {
if
(
!
ttl
::
isBoundaryEdge
(
d1
))
{
//if (!TraitsType::fixedEdge(d1) && !isBoundaryEdge(d1)) {
if
(
!
isBoundaryEdge
(
d1
))
{
d1
.
alpha2
();
recSwapDelaunay
<
TraitsType
>
(
d1
);
}
//if (!TraitsType::fixedEdge(d2) && !
ttl::
isBoundaryEdge(d2)) {
if
(
!
ttl
::
isBoundaryEdge
(
d2
))
{
//if (!TraitsType::fixedEdge(d2) && !isBoundaryEdge(d2)) {
if
(
!
isBoundaryEdge
(
d2
))
{
d2
.
alpha2
();
recSwapDelaunay
<
TraitsType
>
(
d2
);
}
...
...
@@ -319,8 +337,8 @@ namespace ttl {
// Preserve the incoming dart as output incident to the node and CCW
//d = dsav.alpha2();
dart
.
alpha2
();
//if (!TraitsType::fixedEdge(d3) && !
ttl::
isBoundaryEdge(d3)) {
if
(
!
ttl
::
isBoundaryEdge
(
d3
))
{
//if (!TraitsType::fixedEdge(d3) && !isBoundaryEdge(d3)) {
if
(
!
isBoundaryEdge
(
d3
))
{
d3
.
alpha2
();
recSwapDelaunay
<
TraitsType
>
(
d3
);
}
...
...
@@ -332,7 +350,7 @@ namespace ttl {
//------------------------------------------------------------------------------------------------
// Private/Hidden function (might change later)
template
<
class
TraitsType
,
class
ForwardIterator
,
class
DartType
>
void
insertNodes
(
ForwardIterator
first
,
ForwardIterator
last
,
DartType
&
dart
)
{
void
TriangulationHelper
::
insertNodes
(
ForwardIterator
first
,
ForwardIterator
last
,
DartType
&
dart
)
{
// Assumes that the dereferenced point objects are pointers.
// References to the point objects are then passed to TTL.
...
...
@@ -355,14 +373,14 @@ namespace ttl {
* Output: A CCW dart at the new boundary
*
* \using
* -
ttl::
removeBoundaryNode
* - removeBoundaryNode
*
* \note
* - This function requires that the boundary of the triangulation is
* a rectangle with four nodes (one in each corner).
*/
template
<
class
TraitsType
,
class
DartType
>
void
removeRectangularBoundary
(
DartType
&
dart
)
{
void
TriangulationHelper
::
removeRectangularBoundary
(
DartType
&
dart
)
{
DartType
d_next
=
dart
;
DartType
d_iter
;
...
...
@@ -370,8 +388,8 @@ namespace ttl {
for
(
int
i
=
0
;
i
<
4
;
i
++
)
{
d_iter
=
d_next
;
d_next
.
alpha0
();
ttl
::
positionAtNextBoundaryEdge
(
d_next
);
ttl
::
removeBoundaryNode
<
TraitsType
>
(
d_iter
);
positionAtNextBoundaryEdge
(
d_next
);
removeBoundaryNode
<
TraitsType
>
(
d_iter
);
}
dart
=
d_next
;
// Return a dart at the new boundary
...
...
@@ -383,20 +401,20 @@ namespace ttl {
* updates the triangulation to be Delaunay.
*
* \using
* -
ttl::
removeBoundaryNode if \e dart represents a node at the boundary
* -
ttl::
removeInteriorNode if \e dart represents an interior node
* - removeBoundaryNode if \e dart represents a node at the boundary
* - removeInteriorNode if \e dart represents an interior node
*
* \note
* - The node cannot belong to a fixed (constrained) edge that is not
* swappable. (An endless loop is likely to occur in this case).
*/
template
<
class
TraitsType
,
class
DartType
>
void
removeNode
(
DartType
&
dart
)
{
void
TriangulationHelper
::
removeNode
(
DartType
&
dart
)
{
if
(
ttl
::
isBoundaryNode
(
dart
))
ttl
::
removeBoundaryNode
<
TraitsType
>
(
dart
);
if
(
isBoundaryNode
(
dart
))
removeBoundaryNode
<
TraitsType
>
(
dart
);
else
ttl
::
removeInteriorNode
<
TraitsType
>
(
dart
);
removeInteriorNode
<
TraitsType
>
(
dart
);
}
...
...
@@ -405,14 +423,14 @@ namespace ttl {
* updates the triangulation to be Delaunay.
*
* \using
* -
ttl::
swapEdgesAwayFromBoundaryNode
* -
ttl::
optimizeDelaunay
* - swapEdgesAwayFromBoundaryNode
* - optimizeDelaunay
*
* \require
* - \ref hed::TTLtraits::removeBoundaryTriangle "TraitsType::removeBoundaryTriangle" (Dart&)
*/
template
<
class
TraitsType
,
class
DartType
>
void
removeBoundaryNode
(
DartType
&
dart
)
{
void
TriangulationHelper
::
removeBoundaryNode
(
DartType
&
dart
)
{
// ... and update Delaunay
// - CCW dart must be given (for remove)
...
...
@@ -420,13 +438,13 @@ namespace ttl {
// we assume that there is not only one triangle left in the triangulation.
// Position at boundary edge and CCW
if
(
!
ttl
::
isBoundaryEdge
(
dart
))
{
if
(
!
isBoundaryEdge
(
dart
))
{
dart
.
alpha1
();
// ensures that next function delivers back a CCW dart (if the given dart is CCW)
ttl
::
positionAtNextBoundaryEdge
(
dart
);
positionAtNextBoundaryEdge
(
dart
);
}
list
<
DartType
>
swapped_edges
;
ttl
::
swapEdgesAwayFromBoundaryNode
<
TraitsType
>
(
dart
,
swapped_edges
);
std
::
list
<
DartType
>
swapped_edges
;
swapEdgesAwayFromBoundaryNode
<
TraitsType
>
(
dart
,
swapped_edges
);
// Remove boundary triangles and remove the new boundary from the list
// of swapped edges, see below.
...
...
@@ -435,7 +453,7 @@ namespace ttl {
bool
bend
=
false
;
while
(
bend
==
false
)
{
dnext
.
alpha1
().
alpha2
();
if
(
ttl
::
isBoundaryEdge
(
dnext
))
if
(
isBoundaryEdge
(
dnext
))
bend
=
true
;
// Stop when boundary
// Generic: Also remove the new boundary from the list of swapped edges
...
...
@@ -443,20 +461,20 @@ namespace ttl {
n_bedge
.
alpha1
().
alpha0
().
alpha1
().
alpha2
();
// new boundary edge
// ??? can we avoid find if we do this in swap away?
typename
list
<
DartType
>::
iterator
it
;
typename
std
::
list
<
DartType
>::
iterator
it
;
it
=
find
(
swapped_edges
.
begin
(),
swapped_edges
.
end
(),
n_bedge
);
if
(
it
!=
swapped_edges
.
end
())
swapped_edges
.
erase
(
it
);
// Remove the boundary triangle
TraitsType
::
removeBoundaryTriangle
(
d_iter
);
triangulation
.
removeBoundaryTriangle
(
d_iter
);
d_iter
=
dnext
;
}
// Optimize Delaunay
typedef
list
<
DartType
>
DartListType
;
ttl
::
optimizeDelaunay
<
TraitsType
,
DartType
,
DartListType
>
(
swapped_edges
);
typedef
std
::
list
<
DartType
>
DartListType
;
optimizeDelaunay
<
TraitsType
,
DartType
,
DartListType
>
(
swapped_edges
);
}
...
...
@@ -465,8 +483,8 @@ namespace ttl {
* updates the triangulation to be Delaunay.
*
* \using
* -
ttl::
swapEdgesAwayFromInteriorNode
* -
ttl::optimizeDelaunay
* - swapEdgesAwayFromInteriorNode
* -
optimizeDelaunay
*
* \require
* - \ref hed::TTLtraits::reverse_splitTriangle "TraitsType::reverse_splitTriangle" (Dart&)
...
...
@@ -476,7 +494,7 @@ namespace ttl {
* swappable. (An endless loop is likely to occur in this case).
*/
template
<
class
TraitsType
,
class
DartType
>
void
removeInteriorNode
(
DartType
&
dart
)
{
void
TriangulationHelper
::
removeInteriorNode
(
DartType
&
dart
)
{
// ... and update to Delaunay.
// Must allow degeneracy temporarily, see comments in swap edges away
...
...
@@ -492,13 +510,13 @@ namespace ttl {
// Assumes dart is counterclockwise
list
<
DartType
>
swapped_edges
;
ttl
::
swapEdgesAwayFromInteriorNode
<
TraitsType
>
(
dart
,
swapped_edges
);
std
::
list
<
DartType
>
swapped_edges
;
swapEdgesAwayFromInteriorNode
<
TraitsType
>
(
dart
,
swapped_edges
);
// The reverse operation of split triangle:
// Make one triangle of the three triangles at the node associated with dart
// TraitsType::
TraitsType
::
reverse_splitTriangle
(
dart
);
triangulation
.
reverse_splitTriangle
(
dart
);
// ???? Not generic yet if we are very strict:
// When calling unsplit triangle, darts at the three opposite sides may
...
...
@@ -511,7 +529,7 @@ namespace ttl {
// Note the theoretical result: if there are no edges in the list,
// the triangulation is Delaunay already
ttl
::
optimizeDelaunay
<
TraitsType
,
DartType
>
(
swapped_edges
);
optimizeDelaunay
<
TraitsType
,
DartType
>
(
swapped_edges
);
}
//@} // End of Delaunay Triangulation Group
...
...
@@ -527,7 +545,7 @@ namespace ttl {
//------------------------------------------------------------------------------------------------
// Private/Hidden function (might change later)
template
<
class
TopologyElementType
,
class
DartType
>
bool
isMemberOfFace
(
const
TopologyElementType
&
topologyElement
,
const
DartType
&
dart
)
{
bool
TriangulationHelper
::
isMemberOfFace
(
const
TopologyElementType
&
topologyElement
,
const
DartType
&
dart
)
{
// Check if the given topology element (node, edge or face) is a member of the face
// Assumes:
...
...
@@ -547,7 +565,7 @@ namespace ttl {
//------------------------------------------------------------------------------------------------
// Private/Hidden function (might change later)
template
<
class
TraitsType
,
class
NodeType
,
class
DartType
>
bool
locateFaceWithNode
(
const
NodeType
&
node
,
DartType
&
dart_iter
)
{
bool
TriangulationHelper
::
locateFaceWithNode
(
const
NodeType
&
node
,
DartType
&
dart_iter
)
{
// Locate a face in the topology structure with the given node as a member
// Assumes:
// - TraitsType::orient2d(DartType, DartType, NodeType)
...
...
@@ -594,10 +612,10 @@ namespace ttl {
* \e regular as explained above.
*
* \see
*
ttl::
locateTriangle
* locateTriangle
*/
template
<
class
TraitsType
,
class
PointType
,
class
DartType
>
bool
locateFaceSimplest
(
const
PointType
&
point
,
DartType
&
dart
)
{
bool
TriangulationHelper
::
locateFaceSimplest
(
const
PointType
&
point
,
DartType
&
dart
)
{
// Not degenerate triangles if point is on the extension of the edges
// But inTriangle may be called in case of true (may update to inFace2)
// Convex boundary
...
...
@@ -660,11 +678,11 @@ namespace ttl {
* then the edge associated with \e dart will be at the boundary of the triangulation.
*
* \using
* -
ttl::
locateFaceSimplest
* -
ttl::
inTriangle
* - locateFaceSimplest
* - inTriangle
*/
template
<
class
TraitsType
,
class
PointType
,
class
DartType
>
bool
locateTriangle
(
const
PointType
&
point
,
DartType
&
dart
)
{
bool
TriangulationHelper
::
locateTriangle
(
const
PointType
&
point
,
DartType
&
dart
)
{
// The purpose is to have a fast and stable procedure that
// i) avoids concluding that a point is inside a triangle if it is not inside
// ii) avoids infinite loops
...
...
@@ -713,10 +731,10 @@ namespace ttl {
* - \ref hed::TTLtraits::orient2d "TraitsType::orient2d" (DartType&, DartType&, PointType&)
*
* \see
*
ttl::
inTriangle for a more robust function
* inTriangle for a more robust function
*/
template
<
class
TraitsType
,
class
PointType
,
class
DartType
>
bool
inTriangleSimplest
(
const
PointType
&
point
,
const
DartType
&
dart
)
{
bool
TriangulationHelper
::
inTriangleSimplest
(
const
PointType
&
point
,
const
DartType
&
dart
)
{
// Fast and simple: Do not deal with degenerate faces, i.e., if there is
// degeneracy, true will be returned if the point is on the extension of the
...
...
@@ -757,10 +775,10 @@ namespace ttl {
* - \ref hed::TTLtraits::scalarProduct2d "TraitsType::scalarProduct2d" (DartType&, PointType&)
*
* \see
*
ttl::
inTriangleSimplest
* inTriangleSimplest
*/
template
<
class
TraitsType
,
class
PointType
,
class
DartType
>
bool
inTriangle
(
const
PointType
&
point
,
const
DartType
&
dart
)
{
bool
TriangulationHelper
::
inTriangle
(
const
PointType
&
point
,
const
DartType
&
dart
)
{
// SHOULD WE INCLUDE A STRATEGY WITH EDGE X e_1 ETC? TO GUARANTEE THAT
// ONLY ON ONE EDGE? BUT THIS DOES NOT SOLVE PROBLEMS WITH
...
...
@@ -841,7 +859,7 @@ namespace ttl {
//------------------------------------------------------------------------------------------------
// Private/Hidden function (might change later)
template
<
class
DartType
>
void
getAdjacentTriangles
(
const
DartType
&
dart
,
DartType
&
t1
,
DartType
&
t2
,
DartType
&
t3
)
{
void
TriangulationHelper
::
getAdjacentTriangles
(
const
DartType
&
dart
,
DartType
&
t1
,
DartType
&
t2
,
DartType
&
t3
)
{
DartType
dart_iter
=
dart
;
...
...
@@ -886,7 +904,7 @@ namespace ttl {
* - DartListType::push_back (DartType&)
*/
template
<
class
DartType
,
class
DartListType
>
void
getBoundary
(
const
DartType
&
dart
,
DartListType
&
boundary
)
{
void
TriangulationHelper
::
getBoundary
(
const
DartType
&
dart
,
DartListType
&
boundary
)
{
// assumes the given dart is at the boundary (by edge)
DartType
dart_iter
(
dart
);
...
...
@@ -932,7 +950,7 @@ namespace ttl {
* \endcode
*/
template
<
class
DartType
>
bool
isBoundaryEdge
(
const
DartType
&
dart
)
{
bool
TriangulationHelper
::
isBoundaryEdge
(
const
DartType
&
dart
)
{
DartType
dart_iter
=
dart
;
if
(
dart_iter
.
alpha2
()
==
dart
)
...
...
@@ -947,7 +965,7 @@ namespace ttl {
* the boundary of the triangulation.
*/
template
<
class
DartType
>
bool
isBoundaryFace
(
const
DartType
&
dart
)
{
bool
TriangulationHelper
::
isBoundaryFace
(
const
DartType
&
dart
)
{
// Strategy: boundary if alpha2(d)=d
...
...
@@ -976,7 +994,7 @@ namespace ttl {
* the boundary of the triangulation.
*/
template
<
class
DartType
>
bool
isBoundaryNode
(
const
DartType
&
dart
)
{
bool
TriangulationHelper
::
isBoundaryNode
(
const
DartType
&
dart
)
{
// Strategy: boundary if alpha2(d)=d
...
...
@@ -1009,7 +1027,7 @@ namespace ttl {
* the number of edges joining \e V with another node in the triangulation.
*/
template
<
class
DartType
>
int
getDegreeOfNode
(
const
DartType
&
dart
)
{
int
TriangulationHelper
::
getDegreeOfNode
(
const
DartType
&
dart
)
{
DartType
dart_iter
(
dart
);
DartType
dart_prev
;
...
...
@@ -1069,7 +1087,8 @@ namespace ttl {
// Private/Hidden function
template
<
class
DartType
>
void
getNeighborNodes
(
const
DartType
&
dart
,
std
::
list
<
DartType
>&
node_list
,
bool
&
boundary
)
{
void
TriangulationHelper
::
getNeighborNodes
(
const
DartType
&
dart
,
std
::
list
<
DartType
>&
node_list
,
bool
&
boundary
)
{
DartType
dart_iter
(
dart
);
...
...
@@ -1131,10 +1150,10 @@ namespace ttl {
* - DartListType::push_back (DartType&)
*
* \see
*
ttl::
get_0_orbit_boundary
* get_0_orbit_boundary
*/
template
<
class
DartType
,
class
DartListType
>
void
get_0_orbit_interior
(
const
DartType
&
dart
,
DartListType
&
orbit
)
{
void
TriangulationHelper
::
get_0_orbit_interior
(
const
DartType
&
dart
,
DartListType
&
orbit
)
{
DartType
d_iter
=
dart
;
orbit
.
push_back
(
d_iter
);
...
...
@@ -1165,10 +1184,10 @@ namespace ttl {
* - The last dart in the sequence have opposite orientation compared to the others!
*
* \see
*
ttl::
get_0_orbit_interior
* get_0_orbit_interior
*/
template
<
class
DartType
,
class
DartListType
>
void
get_0_orbit_boundary
(
const
DartType
&
dart
,
DartListType
&
orbit
)
{
void
TriangulationHelper
::
get_0_orbit_boundary
(
const
DartType
&
dart
,
DartListType
&
orbit
)
{
DartType
dart_prev
;
DartType
d_iter
=
dart
;
...
...
@@ -1195,17 +1214,17 @@ namespace ttl {
* own version.)
*/
template
<
class
DartType
>
bool
same_0_orbit
(
const
DartType
&
d1
,
const
DartType
&
d2
)
{
bool
TriangulationHelper
::
same_0_orbit
(
const
DartType
&
d1
,
const
DartType
&
d2
)
{
// Two copies of the same dart
DartType
d_iter
=
d2
;
DartType
d_end
=
d2
;
if
(
ttl
::
isBoundaryNode
(
d_iter
))
{
if
(
isBoundaryNode
(
d_iter
))
{
// position at both boundary edges
ttl
::
positionAtNextBoundaryEdge
(
d_iter
);
positionAtNextBoundaryEdge
(
d_iter
);
d_end
.
alpha1
();
ttl
::
positionAtNextBoundaryEdge
(
d_end
);
positionAtNextBoundaryEdge
(
d_end
);
}
for
(;;)
{
...
...
@@ -1229,7 +1248,7 @@ namespace ttl {
* \e d1 and/or \e d2 can be CCW or CW.
*/
template
<
class
DartType
>
bool
same_1_orbit
(
const
DartType
&
d1
,
const
DartType
&
d2
)
{
bool
TriangulationHelper
::
same_1_orbit
(
const
DartType
&
d1
,
const
DartType
&
d2
)
{
DartType
d_iter
=
d2
;
// (Also works at the boundary)
...
...
@@ -1245,7 +1264,7 @@ namespace ttl {
* \e d1 and/or \e d2 can be CCW or CW
*/
template
<
class
DartType
>
bool
same_2_orbit
(
const
DartType
&
d1
,
const
DartType
&
d2
)
{
bool
TriangulationHelper
::
same_2_orbit
(
const
DartType
&
d1
,
const
DartType
&
d2
)
{
DartType
d_iter
=
d2
;
if
(
d_iter
==
d1
||
d_iter
.
alpha0
()
==
d1
||
...
...
@@ -1259,7 +1278,7 @@ namespace ttl {
//------------------------------------------------------------------------------------------------
// Private/Hidden function
template
<
class
TraitsType
,
class
DartType
>
bool
degenerateTriangle
(
const
DartType
&
dart
)
{
bool
TriangulationHelper
::
degenerateTriangle
(
const
DartType
&
dart
)
{
// Check if triangle is degenerate
// Assumes CCW dart
...
...
@@ -1287,7 +1306,7 @@ namespace ttl {
* - \ref hed::TTLtraits::crossProduct2d "TraitsType::crossProduct2d" (Dart&, Dart&)
*/
template
<
class
TraitsType
,
class
DartType
>
bool
swappableEdge
(
const
DartType
&
dart
,
bool
allowDegeneracy
)
{
bool
TriangulationHelper
::
swappableEdge
(
const
DartType
&
dart
,
bool
allowDegeneracy
)
{
// How "safe" is it?
...
...
@@ -1340,7 +1359,7 @@ namespace ttl {
* infinit loop occurs.
*/
template
<
class
DartType
>
void
positionAtNextBoundaryEdge
(
DartType
&
dart
)
{
void
TriangulationHelper
::
positionAtNextBoundaryEdge
(
DartType
&
dart
)
{
DartType
dart_prev
;
...
...
@@ -1365,14 +1384,14 @@ namespace ttl {
* - \ref hed::TTLtraits::crossProduct2d "TraitsType::crossProduct2d" (const Dart&, const Dart&)
*/
template
<
class
TraitsType
,
class
DartType
>
bool
convexBoundary
(
const
DartType
&
dart
)
{
bool
TriangulationHelper
::
convexBoundary
(
const
DartType
&
dart
)
{
list
<
DartType
>
blist
;
ttl
::
getBoundary
(
dart
,
blist
);
std
::
list
<
DartType
>
blist
;
getBoundary
(
dart
,
blist
);
int
no
;
no
=
(
int
)
blist
.
size
();
typename
list
<
DartType
>::
const_iterator
bit
=
blist
.
begin
();
typename
std
::
list
<
DartType
>::
const_iterator
bit
=
blist
.
begin
();
DartType
d1
=
*
bit
;
++
bit
;
DartType
d2
;
...
...
@@ -1428,17 +1447,17 @@ namespace ttl {
* seen if it was glued to the edge when swapping (rotating) the edge CCW
*
* \using
* -
ttl::
swapTestDelaunay
* - swapTestDelaunay
*/
template
<
class
TraitsType
,
class
DartType
,
class
DartListType
>
void
optimizeDelaunay
(
DartListType
&
elist
)
{
void
TriangulationHelper
::
optimizeDelaunay
(
DartListType
&
elist
)
{
optimizeDelaunay
<
TraitsType
,
DartType
,
DartListType
>
(
elist
,
elist
.
end
());
}
//------------------------------------------------------------------------------------------------
template
<
class
TraitsType
,
class
DartType
,
class
DartListType
>
void
optimizeDelaunay
(
DartListType
&
elist
,
const
typename
DartListType
::
iterator
end
)
{
void
TriangulationHelper
::
optimizeDelaunay
(
DartListType
&
elist
,
const
typename
DartListType
::
iterator
end
)
{
// CCW darts
// Optimize here means Delaunay, but could be any criterion by
...
...
@@ -1481,14 +1500,14 @@ namespace ttl {
while
(
!
optimal
)
{
optimal
=
true
;
for
(
it
=
elist
.
begin
();
it
!=
end_opt
;
++
it
)
{
if
(
ttl
::
swapTestDelaunay
<
TraitsType
>
(
*
it
,
cycling_check
))
{
if
(
swapTestDelaunay
<
TraitsType
>
(
*
it
,
cycling_check
))
{
// Preserve darts. Potential darts in the list are:
// - The current dart
// - the four CCW darts on the boundary of the quadrilateral
// (the current arc has only one dart)
ttl
::
swapEdgeInList
<
TraitsType
,
DartType
>
(
it
,
elist
);
swapEdgeInList
<
TraitsType
,
DartType
>
(
it
,
elist
);
optimal
=
false
;
}
// end if should swap
...
...
@@ -1513,9 +1532,9 @@ namespace ttl {
*/
template
<
class
TraitsType
,
class
DartType
>
#if ((_MSC_VER > 0) && (_MSC_VER < 1300))//#ifdef _MSC_VER
bool
swapTestDelaunay
(
const
DartType
&
dart
,
bool
cycling_check
=
false
)
{
bool
TriangulationHelper
::
swapTestDelaunay
(
const
DartType
&
dart
,
bool
cycling_check
=
false
)
const
{
#else
bool
swapTestDelaunay
(
const
DartType
&
dart
,
bool
cycling_check
)
{
bool
TriangulationHelper
::
swapTestDelaunay
(
const
DartType
&
dart
,
bool
cycling_check
)
const
{
#endif
// The general strategy is taken from Cline & Renka. They claim that
...
...
@@ -1627,17 +1646,17 @@ namespace ttl {
* - Calls itself recursively
*/
template
<
class
TraitsType
,
class
DartType
>
void
recSwapDelaunay
(
DartType
&
diagonal
)
{
void
TriangulationHelper
::
recSwapDelaunay
(
DartType
&
diagonal
)
{
if
(
!
ttl
::
swapTestDelaunay
<
TraitsType
>
(
diagonal
))
// ???
ttl::
swapTestDelaunay also checks if boundary, so this can be optimized
if
(
!
swapTestDelaunay
<
TraitsType
>
(
diagonal
))
// ??? swapTestDelaunay also checks if boundary, so this can be optimized
return
;
// Get the other "edges" of the current triangle; see illustration above.
DartType
oppEdge1
=
diagonal
;
oppEdge1
.
alpha1
();
bool
b1
;
if
(
ttl
::
isBoundaryEdge
(
oppEdge1
))
if
(
isBoundaryEdge
(
oppEdge1
))
b1
=
true
;
else
{
b1
=
false
;
...
...
@@ -1648,7 +1667,7 @@ namespace ttl {
DartType
oppEdge2
=
diagonal
;
oppEdge2
.
alpha0
().
alpha1
().
alpha0
();
bool
b2
;
if
(
ttl
::
isBoundaryEdge
(
oppEdge2
))
if
(
isBoundaryEdge
(
oppEdge2
))
b2
=
true
;
else
{
b2
=
false
;
...
...
@@ -1656,7 +1675,7 @@ namespace ttl {
}
// Swap the given diagonal
TraitsType
::
swapEdge
(
diagonal
);
triangulation
.
swapEdge
(
diagonal
);
if
(
!
b1
)
recSwapDelaunay
<
TraitsType
>
(
oppEdge1
);
...
...
@@ -1669,7 +1688,7 @@ namespace ttl {
/** Swaps edges away from the (interior) node associated with
* \e dart such that that exactly three edges remain incident
* with the node.
* This function is used as a first step in
ttl::
removeInteriorNode
* This function is used as a first step in removeInteriorNode
*
* \retval dart
* A CCW dart incident with the node
...
...
@@ -1689,10 +1708,10 @@ namespace ttl {
* at the node that is given as input.
*
* \see
*
ttl::
swapEdgesAwayFromBoundaryNode
* swapEdgesAwayFromBoundaryNode
*/
template
<
class
TraitsType
,
class
DartType
,
class
ListType
>
void
swapEdgesAwayFromInteriorNode
(
DartType
&
dart
,
ListType
&
swapped_edges
)
{
void
TriangulationHelper
::
swapEdgesAwayFromInteriorNode
(
DartType
&
dart
,
ListType
&
swapped_edges
)
{
// Same iteration as in fixEdgesAtCorner, but not boundary
DartType
dnext
=
dart
;
...
...
@@ -1706,14 +1725,14 @@ namespace ttl {
// infinite loop with degree > 3.
bool
allowDegeneracy
=
true
;
int
degree
=
ttl
::
getDegreeOfNode
(
dart
);
int
degree
=
getDegreeOfNode
(
dart
);
DartType
d_iter
;
while
(
degree
>
3
)
{
d_iter
=
dnext
;
dnext
.
alpha1
().
alpha2
();
if
(
ttl
::
swappableEdge
<
TraitsType
>
(
d_iter
,
allowDegeneracy
))
{
TraitsType
::
swapEdge
(
d_iter
);
// swap the edge away
if
(
swappableEdge
<
TraitsType
>
(
d_iter
,
allowDegeneracy
))
{
triangulation
.
swapEdge
(
d_iter
);
// swap the edge away
// Collect swapped edges in the list
// "Hide" the dart on the other side of the edge to avoid it being changed for
// other swaps
...
...
@@ -1733,7 +1752,7 @@ namespace ttl {
/** Swaps edges away from the (boundary) node associated with
* \e dart in such a way that when removing the edges that remain incident
* with the node, the boundary of the triangulation will be convex.
* This function is used as a first step in
ttl::
removeBoundaryNode
* This function is used as a first step in removeBoundaryNode
*
* \retval dart
* A CCW dart incident with the node
...
...
@@ -1747,10 +1766,10 @@ namespace ttl {
* - The node associated with \e dart is at the boundary of the triangulation.
*
* \see
*
ttl::
swapEdgesAwayFromInteriorNode
* swapEdgesAwayFromInteriorNode
*/
template
<
class
TraitsType
,
class
DartType
,
class
ListType
>
void
swapEdgesAwayFromBoundaryNode
(
DartType
&
dart
,
ListType
&
swapped_edges
)
{
void
TriangulationHelper
::
swapEdgesAwayFromBoundaryNode
(
DartType
&
dart
,
ListType
&
swapped_edges
)
{
// All darts that are swappable.
// To treat collinear nodes at an existing boundary, we must allow degeneracy
...
...
@@ -1762,7 +1781,7 @@ namespace ttl {
// - A dart on the swapped edge is delivered back in a position as
// seen if it was glued to the edge when swapping (rotating) the edge CCW
//int degree =
ttl::
getDegreeOfNode(dart);
//int degree = getDegreeOfNode(dart);
passes
:
...
...
@@ -1780,7 +1799,7 @@ passes:
while
(
!
bend
)
{
d_next
.
alpha1
().
alpha2
();
if
(
ttl
::
isBoundaryEdge
(
d_next
))
if
(
isBoundaryEdge
(
d_next
))
bend
=
true
;
// then it is CW since alpha2
// To allow removing among collinear nodes at the boundary,
...
...
@@ -1789,13 +1808,13 @@ passes:
tmp1
=
d_iter
;
tmp1
.
alpha1
();
tmp2
=
d_iter
;
tmp2
.
alpha2
().
alpha1
();
// don't bother with boundary (checked later)
if
(
ttl
::
isBoundaryEdge
(
tmp1
)
&&
ttl
::
isBoundaryEdge
(
tmp2
))
if
(
isBoundaryEdge
(
tmp1
)
&&
isBoundaryEdge
(
tmp2
))
allowDegeneracy
=
true
;
else
allowDegeneracy
=
false
;
if
(
ttl
::
swappableEdge
<
TraitsType
>
(
d_iter
,
allowDegeneracy
))
{
TraitsType
::
swapEdge
(
d_iter
);
if
(
swappableEdge
<
TraitsType
>
(
d_iter
,
allowDegeneracy
))
{
triangulation
.
swapEdge
(
d_iter
);
// Collect swapped edges in the list
// "Hide" the dart on the other side of the edge to avoid it being changed for
...
...
@@ -1821,7 +1840,7 @@ passes:
else
{
d_iter
.
alpha1
();
// CW and see below
}
ttl
::
positionAtNextBoundaryEdge
(
d_iter
);
// CCW
positionAtNextBoundaryEdge
(
d_iter
);
// CCW
dart
=
d_iter
;
// for next pass or output
...
...
@@ -1839,7 +1858,7 @@ passes:
* keep them in \e elist.
*/
template
<
class
TraitsType
,
class
DartType
,
class
DartListType
>
void
swapEdgeInList
(
const
typename
DartListType
::
iterator
&
it
,
DartListType
&
elist
)
{
void
TriangulationHelper
::
swapEdgeInList
(
const
typename
DartListType
::
iterator
&
it
,
DartListType
&
elist
)
{
typename
DartListType
::
iterator
it1
,
it2
,
it3
,
it4
;
DartType
dart
(
*
it
);
...
...
@@ -1867,7 +1886,7 @@ passes:
it3
=
find
(
elist
.
begin
(),
elist
.
end
(),
d3
);
it4
=
find
(
elist
.
begin
(),
elist
.
end
(),
d4
);
TraitsType
::
swapEdge
(
dart
);
triangulation
.
swapEdge
(
dart
);
// Update the current dart which may have changed
*
it
=
dart
;
...
...
include/ttl/ttl_constr.h
View file @
a10d918c
...
...
@@ -51,9 +51,6 @@
static
ofstream
ofile_constr
(
"qweCons.dat"
);
#endif
//using namespace std;
/** \brief Constrained Delaunay triangulation
*
* Basic generic algorithms in TTL for inserting a constrained edge between two existing nodes.\n
...
...
@@ -61,7 +58,7 @@
* See documentation for the namespace ttl for general requirements and assumptions.
*
* \author
* Øyvind Hjelle, oyvindhj@ifi.uio.no
*
�
yvind Hjelle, oyvindhj@ifi.uio.no
*/
namespace
ttl_constr
{
...
...
@@ -73,6 +70,9 @@ namespace ttl_constr {
#endif
class
ConstrainedTriangulation
{
public
:
//------------------------------------------------------------------------------------------------
/* Checks if \e dart has start and end points in \e dstart and \e dend.
*
...
...
@@ -89,14 +89,14 @@ namespace ttl_constr {
* A bool confirming that it's the constraint or not
*
* \using
*
ttl::
same_0_orbit
* same_0_orbit
*/
template
<
class
DartType
>
bool
isTheConstraint
(
const
DartType
&
dart
,
const
DartType
&
dstart
,
const
DartType
&
dend
)
{
static
bool
isTheConstraint
(
const
DartType
&
dart
,
const
DartType
&
dstart
,
const
DartType
&
dend
)
{
DartType
d0
=
dart
;
d0
.
alpha0
();
// CW
if
((
ttl
::
same_0_orbit
(
dstart
,
dart
)
&&
ttl
::
same_0_orbit
(
dend
,
d0
))
||
(
ttl
::
same_0_orbit
(
dstart
,
d0
)
&&
ttl
::
same_0_orbit
(
dend
,
dart
)))
{
if
((
ttl
::
TriangulationHelper
::
same_0_orbit
(
dstart
,
dart
)
&&
ttl
::
TriangulationHelper
::
same_0_orbit
(
dend
,
d0
))
||
(
ttl
::
TriangulationHelper
::
same_0_orbit
(
dstart
,
d0
)
&&
ttl
::
TriangulationHelper
::
same_0_orbit
(
dend
,
dart
)))
{
return
true
;
}
return
false
;
...
...
@@ -123,7 +123,7 @@ namespace ttl_constr {
* TraitsType::orient2d
*/
template
<
class
TraitsType
,
class
DartType
>
bool
crossesConstraint
(
DartType
&
dstart
,
DartType
&
dend
,
DartType
&
d1
,
DartType
&
d2
)
{
static
bool
crossesConstraint
(
DartType
&
dstart
,
DartType
&
dend
,
DartType
&
d1
,
DartType
&
d2
)
{
typename
TraitsType
::
real_type
orient_1
=
TraitsType
::
orient2d
(
dstart
,
d1
,
dend
);
typename
TraitsType
::
real_type
orient_2
=
TraitsType
::
orient2d
(
dstart
,
d2
,
dend
);
...
...
@@ -156,12 +156,12 @@ namespace ttl_constr {
* The dart \e d making the smallest positive (or == 0) angle
*
* \using
*
ttl::
isBoundaryNode
*
ttl::
positionAtNextBoundaryEdge
* isBoundaryNode
* positionAtNextBoundaryEdge
* TraitsType::orient2d
*/
template
<
class
TraitsType
,
class
DartType
>
DartType
getAtSmallestAngle
(
const
DartType
&
dstart
,
const
DartType
&
dend
)
{
static
DartType
getAtSmallestAngle
(
const
DartType
&
dstart
,
const
DartType
&
dend
)
{
// - Must boundary be convex???
// - Handle the case where the constraint is already present???
...
...
@@ -169,9 +169,9 @@ namespace ttl_constr {
// (dstart and dend may define a boundary edge)
DartType
d_iter
=
dstart
;
if
(
ttl
::
isBoundaryNode
(
d_iter
))
{
if
(
ttl
::
TriangulationHelper
::
isBoundaryNode
(
d_iter
))
{
d_iter
.
alpha1
();
// CW
ttl
::
positionAtNextBoundaryEdge
(
d_iter
);
// CCW (was rotated CW to the boundary)
ttl
::
TriangulationHelper
::
positionAtNextBoundaryEdge
(
d_iter
);
// CCW (was rotated CW to the boundary)
}
// assume convex boundary; see comments
...
...
@@ -273,7 +273,7 @@ namespace ttl_constr {
* Returns the next "collinear" starting node such that dend is returned when done.
*/
template
<
class
TraitsType
,
class
DartType
,
class
ListType
>
DartType
findCrossingEdges
(
const
DartType
&
dstart
,
const
DartType
&
dend
,
ListType
&
elist
)
{
static
DartType
findCrossingEdges
(
const
DartType
&
dstart
,
const
DartType
&
dend
,
ListType
&
elist
)
{
const
DartType
my_start
=
getAtSmallestAngle
<
TraitsType
>
(
dstart
,
dend
);
DartType
my_end
=
getAtSmallestAngle
<
TraitsType
>
(
dend
,
dstart
);
...
...
@@ -387,15 +387,16 @@ namespace ttl_constr {
* A list containing all the edges crossing the spesified constraint
*
* \using
*
ttl::
swappableEdge
*
ttl::
swapEdgeInList
*
ttl::
crossesConstraint
*
ttl::
isTheConstraint
* swappableEdge
* swapEdgeInList
* crossesConstraint
* isTheConstraint
*/
template
<
class
TraitsType
,
class
DartType
>
void
transformToConstraint
(
DartType
&
dstart
,
DartType
&
dend
,
std
::
list
<
DartType
>&
elist
)
{
void
transformToConstraint
(
ttl
::
TriangulationHelper
helper
,
DartType
&
dstart
,
DartType
&
dend
,
std
::
list
<
DartType
>&
elist
)
const
{
typename
list
<
DartType
>::
iterator
it
,
used
;
typename
std
::
list
<
DartType
>::
iterator
it
,
used
;
// We may enter in a situation where dstart and dend are altered because of a swap.
// (The general rule is that darts inside the actual quadrilateral can be changed,
...
...
@@ -423,7 +424,7 @@ namespace ttl_constr {
if
(
counter
>
dartsInList
)
break
;
if
(
ttl
::
swappableEdge
<
TraitsType
,
DartType
>
(
*
it
,
true
))
{
if
(
ttl
::
TriangulationHelper
::
swappableEdge
<
TraitsType
,
DartType
>
(
*
it
,
true
))
{
// Dyn & Goren & Rippa 's notation:
// The node assosiated with dart *it is denoted u_m. u_m has edges crossing the constraint
// named w_1, ... , w_r . The other node to the edge assosiated with dart *it is w_s.
...
...
@@ -456,7 +457,7 @@ namespace ttl_constr {
end
=
true
;
// This is the only place swapping is called when inserting a constraint
ttl
::
swapEdgeInList
<
TraitsType
,
DartType
>
(
it
,
elist
);
helper
.
swapEdgeInList
<
TraitsType
,
DartType
>
(
it
,
elist
);
// If we, during look-ahead, found that dstart and/or dend were in the quadrilateral,
// we update them.
...
...
@@ -512,6 +513,8 @@ namespace ttl_constr {
}
};
// End of ConstrainedTriangulation class
};
// End of ttl_constr namespace scope
...
...
@@ -546,14 +549,14 @@ namespace ttl { // (extension)
* - \ref hed::TTLtraits::swapEdge "TraitsType::swapEdge" (DartType&)
*
* \using
* -
ttl::
optimizeDelaunay if \e optimize_delaunay is set to \c true
* - optimizeDelaunay if \e optimize_delaunay is set to \c true
*
* \par Assumes:
* - The constrained edge must be inside the existing triangulation (and it cannot
* cross the boundary of the triangulation).
*/
template
<
class
TraitsType
,
class
DartType
>
DartType
insertConstraint
(
DartType
&
dstart
,
DartType
&
dend
,
bool
optimize_delaunay
)
{
DartType
TriangulationHelper
::
insertConstraint
(
DartType
&
dstart
,
DartType
&
dend
,
bool
optimize_delaunay
)
{
// Assumes:
// - It is the users responsibility to avoid crossing constraints
...
...
@@ -567,8 +570,8 @@ namespace ttl { // (extension)
// calls itself recursively.
// RECURSION
list
<
DartType
>
elist
;
DartType
next_start
=
ttl_constr
::
findCrossingEdges
<
TraitsType
>
(
dstart
,
dend
,
elist
);
std
::
list
<
DartType
>
elist
;
DartType
next_start
=
ttl_constr
::
ConstrainedTriangulation
::
findCrossingEdges
<
TraitsType
>
(
dstart
,
dend
,
elist
);
// If there are no crossing edges (elist is empty), we assume that the constraint
// is an existing edge.
...
...
@@ -583,7 +586,7 @@ namespace ttl { // (extension)
// findCrossingEdges stops if it finds a node lying on the constraint.
// A dart with this node as start node is returned
// We call insertConstraint recursivly until the received dart is dend
if
(
!
ttl
::
same_0_orbit
(
next_start
,
dend
))
{
if
(
!
same_0_orbit
(
next_start
,
dend
))
{
#ifdef DEBUG_TTL_CONSTR_PLOT
cout
<<
"RECURSION due to collinearity along constraint"
<<
endl
;
...
...
@@ -594,7 +597,7 @@ namespace ttl { // (extension)
// Swap edges such that the constraint edge is present in the transformed triangulation.
if
(
elist
.
size
()
>
0
)
// by Thomas Sevaldrud
ttl_constr
::
transformToConstraint
<
TraitsType
>
(
dstart
,
next_start
,
elist
);
ttl_constr
::
ConstrainedTriangulation
::
transformToConstraint
<
TraitsType
>
(
dstart
,
next_start
,
elist
);
#ifdef DEBUG_TTL_CONSTR_PLOT
cout
<<
"size of elist = "
<<
elist
.
size
()
<<
endl
;
...
...
@@ -607,13 +610,13 @@ namespace ttl { // (extension)
#endif
// Optimize to constrained Delaunay triangulation if required.
typename
list
<
DartType
>::
iterator
end_opt
=
elist
.
end
();
typename
std
::
list
<
DartType
>::
iterator
end_opt
=
elist
.
end
();
if
(
optimize_delaunay
)
{
// Indicate that the constrained edge, which is the last element in the list,
// should not be swapped
--
end_opt
;
ttl
::
optimizeDelaunay
<
TraitsType
,
DartType
>
(
elist
,
end_opt
);
optimizeDelaunay
<
TraitsType
,
DartType
>
(
elist
,
end_opt
);
}
if
(
elist
.
size
()
==
0
)
// by Thomas Sevaldrud
...
...
pcbnew/ratsnest_data.cpp
View file @
a10d918c
...
...
@@ -240,7 +240,7 @@ void RN_NET::compute()
return
;
}
else
if
(
boardNodes
.
size
()
=
=
1
)
// This case is even simpler
else
if
(
boardNodes
.
size
()
<
=
1
)
// This case is even simpler
{
m_rnEdges
.
reset
(
new
std
::
vector
<
RN_EDGE_PTR
>
(
0
)
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment