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
6fa2f060
Commit
6fa2f060
authored
Apr 07, 2014
by
Maciej Suminski
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Formatted ttl library to comply with KiCad coding policy.
parent
a0fb4ed0
Changes
9
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
2654 additions
and
2517 deletions
+2654
-2517
hetriang.cpp
common/geometry/hetriang.cpp
+556
-560
hedart.h
include/ttl/halfedge/hedart.h
+108
-67
hetraits.h
include/ttl/halfedge/hetraits.h
+124
-111
hetriang.h
include/ttl/halfedge/hetriang.h
+277
-207
ttl.h
include/ttl/ttl.h
+1510
-1479
ttl_util.h
include/ttl/ttl_util.h
+53
-67
ratsnest_data.cpp
pcbnew/ratsnest_data.cpp
+17
-17
ratsnest_data.h
pcbnew/ratsnest_data.h
+7
-7
ratsnest_viewitem.cpp
pcbnew/ratsnest_viewitem.cpp
+2
-2
No files found.
common/geometry/hetriang.cpp
View file @
6fa2f060
...
@@ -48,685 +48,681 @@
...
@@ -48,685 +48,681 @@
#include <boost/foreach.hpp>
#include <boost/foreach.hpp>
#include <boost/make_shared.hpp>
#include <boost/make_shared.hpp>
using
namespace
hed
;
using
namespace
hed
;
using
namespace
std
;
#ifdef TTL_USE_NODE_ID
#ifdef TTL_USE_NODE_ID
int
N
ode
::
id_count
=
0
;
int
N
ODE
::
id_count
=
0
;
#endif
#endif
//#define DEBUG_HE
//#define DEBUG_HE
#ifdef DEBUG_HE
#ifdef DEBUG_HE
#include <iostream>
#include <iostream>
static
void
errorAndExit
(
char
*
message
)
{
static
void
errorAndExit
(
char
*
aMessage
)
cout
<<
"
\n
!!! ERROR: "
<<
message
<<
" !!!
\n
"
<<
endl
;
exit
(
-
1
);
{
}
cout
<<
"
\n
!!! ERROR: "
<<
aMessage
<<
" !!!
\n
"
<<
endl
;
exit
(
-
1
);
}
#endif
#endif
//--------------------------------------------------------------------------------------------------
static
EDGE_PTR
getLeadingEdgeInTriangle
(
const
EDGE_PTR
&
aEdge
)
static
EdgePtr
getLeadingEdgeInTriangle
(
const
EdgePtr
&
e
)
{
{
EdgePtr
edge
=
e
;
EDGE_PTR
edge
=
aEdge
;
// Code: 3EF (assumes triangle)
// Code: 3EF (assumes triangle)
if
(
!
edge
->
isLeadingEdge
())
{
if
(
!
edge
->
IsLeadingEdge
()
)
edge
=
edge
->
getNextEdgeInFace
();
{
if
(
!
edge
->
isLeadingEdge
())
edge
=
edge
->
GetNextEdgeInFace
();
edge
=
edge
->
getNextEdgeInFace
();
}
if
(
!
edge
->
IsLeadingEdge
()
)
edge
=
edge
->
GetNextEdgeInFace
();
if
(
!
edge
->
isLeadingEdge
())
{
}
return
EdgePtr
();
}
if
(
!
edge
->
IsLeadingEdge
()
)
{
return
edge
;
return
EDGE_PTR
();
}
return
edge
;
}
}
//--------------------------------------------------------------------------------------------------
static
void
getLimits
(
NODES_CONTAINER
::
iterator
aFirst
,
NODES_CONTAINER
::
iterator
aLast
,
static
void
getLimits
(
NodesContainer
::
iterator
first
,
int
&
aXmin
,
int
&
aYmin
,
int
&
aXmax
,
int
&
aYmax
)
NodesContainer
::
iterator
last
,
{
int
&
xmin
,
int
&
ymin
,
aXmin
=
aYmin
=
std
::
numeric_limits
<
int
>::
min
();
int
&
xmax
,
int
&
ymax
)
{
aXmax
=
aYmax
=
std
::
numeric_limits
<
int
>::
max
();
xmin
=
ymin
=
std
::
numeric_limits
<
int
>::
min
();
NODES_CONTAINER
::
iterator
it
;
xmax
=
ymax
=
std
::
numeric_limits
<
int
>::
max
();
for
(
it
=
aFirst
;
it
!=
aLast
;
++
it
)
NodesContainer
::
iterator
it
;
{
for
(
it
=
first
;
it
!=
last
;
++
it
)
{
aXmin
=
std
::
min
(
aXmin
,
(
*
it
)
->
GetX
()
);
xmin
=
min
(
xmin
,
(
*
it
)
->
GetX
());
aYmin
=
std
::
min
(
aYmin
,
(
*
it
)
->
GetY
()
);
ymin
=
min
(
ymin
,
(
*
it
)
->
GetY
());
aXmax
=
std
::
max
(
aXmax
,
(
*
it
)
->
GetX
()
);
xmax
=
max
(
xmax
,
(
*
it
)
->
GetX
());
aYmax
=
std
::
max
(
aYmax
,
(
*
it
)
->
GetY
()
);
ymax
=
max
(
ymax
,
(
*
it
)
->
GetY
());
}
}
}
}
//--------------------------------------------------------------------------------------------------
EDGE_PTR
TRIANGULATION
::
InitTwoEnclosingTriangles
(
NODES_CONTAINER
::
iterator
aFirst
,
EdgePtr
Triangulation
::
initTwoEnclosingTriangles
(
NodesContainer
::
iterator
first
,
NODES_CONTAINER
::
iterator
aLast
)
NodesContainer
::
iterator
last
)
{
{
int
xmin
,
ymin
,
xmax
,
ymax
;
int
xmin
,
ymin
,
xmax
,
ymax
;
getLimits
(
aFirst
,
aLast
,
xmin
,
ymin
,
xmax
,
ymax
);
getLimits
(
first
,
last
,
xmin
,
ymin
,
xmax
,
ymax
);
// Add 10% of range:
// Add 10% of range:
double
fac
=
10.0
;
double
fac
=
10.0
;
double
dx
=
(
xmax
-
xmin
)
/
fac
;
double
dx
=
(
xmax
-
xmin
)
/
fac
;
double
dy
=
(
ymax
-
ymin
)
/
fac
;
double
dy
=
(
ymax
-
ymin
)
/
fac
;
NODE_PTR
n1
=
boost
::
make_shared
<
NODE
>
(
xmin
-
dx
,
ymin
-
dy
);
NodePtr
n1
=
boost
::
make_shared
<
Node
>
(
xmin
-
dx
,
ymin
-
dy
);
NODE_PTR
n2
=
boost
::
make_shared
<
NODE
>
(
xmax
+
dx
,
ymin
-
dy
);
NodePtr
n2
=
boost
::
make_shared
<
Node
>
(
xmax
+
dx
,
ymin
-
dy
);
NODE_PTR
n3
=
boost
::
make_shared
<
NODE
>
(
xmax
+
dx
,
ymax
+
dy
);
NodePtr
n3
=
boost
::
make_shared
<
Node
>
(
xmax
+
dx
,
ymax
+
dy
);
NODE_PTR
n4
=
boost
::
make_shared
<
NODE
>
(
xmin
-
dx
,
ymax
+
dy
);
NodePtr
n4
=
boost
::
make_shared
<
Node
>
(
xmin
-
dx
,
ymax
+
dy
);
// diagonal
// diagonal
EDGE_PTR
e1d
=
boost
::
make_shared
<
EDGE
>
();
EdgePtr
e1d
=
boost
::
make_shared
<
Edge
>
();
EDGE_PTR
e2d
=
boost
::
make_shared
<
EDGE
>
();
EdgePtr
e2d
=
boost
::
make_shared
<
Edge
>
();
// lower triangle
// lower triangle
EDGE_PTR
e11
=
boost
::
make_shared
<
EDGE
>
();
EdgePtr
e11
=
boost
::
make_shared
<
Edge
>
();
EDGE_PTR
e12
=
boost
::
make_shared
<
EDGE
>
();
EdgePtr
e12
=
boost
::
make_shared
<
Edge
>
();
// upper triangle
// upper triangle
EDGE_PTR
e21
=
boost
::
make_shared
<
EDGE
>
();
EdgePtr
e21
=
boost
::
make_shared
<
Edge
>
();
EDGE_PTR
e22
=
boost
::
make_shared
<
EDGE
>
();
EdgePtr
e22
=
boost
::
make_shared
<
Edge
>
();
// lower triangle
// lower triangle
e1d
->
SetSourceNode
(
n3
);
e1d
->
setSourceNode
(
n3
);
e1d
->
SetNextEdgeInFace
(
e11
);
e1d
->
setNextEdgeInFace
(
e11
);
e1d
->
SetTwinEdge
(
e2d
);
e1d
->
setTwinEdge
(
e2d
);
addLeadingEdge
(
e1d
);
addLeadingEdge
(
e1d
);
e11
->
SetSourceNode
(
n1
);
e11
->
setSourceNode
(
n1
);
e11
->
SetNextEdgeInFace
(
e12
);
e11
->
setNextEdgeInFace
(
e12
);
e12
->
SetSourceNode
(
n2
);
e12
->
setSourceNode
(
n2
);
e12
->
SetNextEdgeInFace
(
e1d
);
e12
->
setNextEdgeInFace
(
e1d
);
// upper triangle
// upper triangle
e2d
->
SetSourceNode
(
n1
);
e2d
->
setSourceNode
(
n1
);
e2d
->
SetNextEdgeInFace
(
e21
);
e2d
->
setNextEdgeInFace
(
e21
);
e2d
->
SetTwinEdge
(
e1d
);
e2d
->
setTwinEdge
(
e1d
);
addLeadingEdge
(
e2d
);
addLeadingEdge
(
e2d
);
e21
->
SetSourceNode
(
n3
);
e21
->
setSourceNode
(
n3
);
e21
->
SetNextEdgeInFace
(
e22
);
e21
->
setNextEdgeInFace
(
e22
);
e22
->
SetSourceNode
(
n4
);
e22
->
setSourceNode
(
n4
);
e22
->
SetNextEdgeInFace
(
e2d
);
e22
->
setNextEdgeInFace
(
e2d
);
return
e11
;
return
e11
;
}
}
//--------------------------------------------------------------------------------------------------
TRIANGULATION
::
TRIANGULATION
()
Triangulation
::
Triangulation
()
{
{
helper
=
new
ttl
::
TriangulationHelper
(
*
this
);
m_helper
=
new
ttl
::
TRIANGULATION_HELPER
(
*
this
);
}
}
//--------------------------------------------------------------------------------------------------
TRIANGULATION
::
TRIANGULATION
(
const
TRIANGULATION
&
aTriangulation
)
Triangulation
::
Triangulation
(
const
Triangulation
&
tr
)
{
{
std
::
cout
<<
"Triangulation: Copy constructor not present - EXIT."
;
// Triangulation: Copy constructor not present
exit
(
-
1
);
assert
(
false
);
}
}
//--------------------------------------------------------------------------------------------------
TRIANGULATION
::~
TRIANGULATION
()
Triangulation
::~
Triangulation
()
{
{
cleanAll
();
cleanAll
();
delete
helper
;
delete
m_
helper
;
}
}
//--------------------------------------------------------------------------------------------------
void
TRIANGULATION
::
CreateDelaunay
(
NODES_CONTAINER
::
iterator
aFirst
,
void
Triangulation
::
createDelaunay
(
NodesContainer
::
iterator
first
,
NODES_CONTAINER
::
iterator
aLast
)
NodesContainer
::
iterator
last
)
{
{
cleanAll
();
cleanAll
();
EDGE_PTR
bedge
=
InitTwoEnclosingTriangles
(
aFirst
,
aLast
);
EdgePtr
bedge
=
initTwoEnclosingTriangles
(
first
,
last
);
DART
dc
(
bedge
);
Dart
dc
(
bedge
);
DART
d_iter
=
dc
;
Dart
d_iter
=
dc
;
NODES_CONTAINER
::
iterator
it
;
NodesContainer
::
iterator
it
;
for
(
it
=
aFirst
;
it
!=
aLast
;
++
it
)
for
(
it
=
first
;
it
!=
last
;
++
it
)
{
{
helper
->
insertNode
<
TTLtraits
>
(
d_iter
,
*
it
);
m_helper
->
InsertNode
<
TTLtraits
>
(
d_iter
,
*
it
);
}
}
// In general (e.g. for the triangle based data structure), the initial dart
// In general (e.g. for the triangle based data structure), the initial dart
// may have been changed.
// may have been changed.
// It is the users responsibility to get a valid boundary dart here.
// It is the users responsibility to get a valid boundary dart here.
// The half-edge data structure preserves the initial dart.
// The half-edge data structure preserves the initial dart.
// (A dart at the boundary can also be found by trying to locate a
// (A dart at the boundary can also be found by trying to locate a
// triangle "outside" the triangulation.)
// triangle "outside" the triangulation.)
// Assumes rectangular domain
// Assumes rectangular domain
helper
->
removeRectangularBoundary
<
TTLtraits
>
(
dc
);
m_helper
->
RemoveRectangularBoundary
<
TTLtraits
>
(
dc
);
}
}
//--------------------------------------------------------------------------------------------------
void
TRIANGULATION
::
RemoveTriangle
(
EDGE_PTR
&
aEdge
)
void
Triangulation
::
removeTriangle
(
EdgePtr
&
edge
)
{
{
EDGE_PTR
e1
=
getLeadingEdgeInTriangle
(
aEdge
);
EdgePtr
e1
=
getLeadingEdgeInTriangle
(
edge
);
#ifdef DEBUG_HE
#ifdef DEBUG_HE
if
(
!
e1
)
if
(
!
e1
)
errorAndExit
(
"Triangulation::removeTriangle: could not find leading edge"
);
errorAndExit
(
"Triangulation::removeTriangle: could not find leading aEdge"
);
#endif
#endif
removeLeadingEdgeFromList
(
e1
);
removeLeadingEdgeFromList
(
e1
);
// cout << "No leading edges = " << leadingEdges_.size() << endl;
// cout << "No leading edges = " << leadingEdges_.size() << endl;
// Remove the triangle
// Remove the triangle
EdgePtr
e2
(
e1
->
getNextEdgeInFace
()
);
EDGE_PTR
e2
(
e1
->
GetNextEdgeInFace
()
);
EdgePtr
e3
(
e2
->
getNextEdgeInFace
()
);
EDGE_PTR
e3
(
e2
->
GetNextEdgeInFace
()
);
e1
->
c
lear
();
e1
->
C
lear
();
e2
->
c
lear
();
e2
->
C
lear
();
e3
->
c
lear
();
e3
->
C
lear
();
}
}
//--------------------------------------------------------------------------------------------------
void
TRIANGULATION
::
ReverseSplitTriangle
(
EDGE_PTR
&
aEdge
)
void
Triangulation
::
reverse_splitTriangle
(
EdgePtr
&
edge
)
{
{
// Reverse operation of splitTriangle
// Reverse operation of splitTriangle
EDGE_PTR
e1
(
aEdge
->
GetNextEdgeInFace
()
);
EDGE_PTR
le
(
getLeadingEdgeInTriangle
(
e1
)
);
EdgePtr
e1
(
edge
->
getNextEdgeInFace
());
EdgePtr
le
(
getLeadingEdgeInTriangle
(
e1
));
#ifdef DEBUG_HE
#ifdef DEBUG_HE
if
(
!
le
)
if
(
!
le
)
errorAndExit
(
"Triangulation::removeTriangle: could not find leading edge"
);
errorAndExit
(
"Triangulation::removeTriangle: could not find leading edge"
);
#endif
#endif
removeLeadingEdgeFromList
(
le
);
removeLeadingEdgeFromList
(
le
);
EdgePtr
e2
(
e1
->
getNextEdgeInFace
()
->
getTwinEdge
()
->
getNextEdgeInFace
()
);
EDGE_PTR
e2
(
e1
->
GetNextEdgeInFace
()
->
GetTwinEdge
()
->
GetNextEdgeInFace
()
);
le
=
getLeadingEdgeInTriangle
(
e2
);
le
=
getLeadingEdgeInTriangle
(
e2
);
#ifdef DEBUG_HE
#ifdef DEBUG_HE
if
(
!
le
)
if
(
!
le
)
errorAndExit
(
"Triangulation::removeTriangle: could not find leading edge"
);
errorAndExit
(
"Triangulation::removeTriangle: could not find leading edge"
);
#endif
#endif
removeLeadingEdgeFromList
(
le
);
removeLeadingEdgeFromList
(
le
);
EdgePtr
e3
(
edge
->
getTwinEdge
()
->
getNextEdgeInFace
()
->
getNextEdgeInFace
()
);
EDGE_PTR
e3
(
aEdge
->
GetTwinEdge
()
->
GetNextEdgeInFace
()
->
GetNextEdgeInFace
()
);
le
=
getLeadingEdgeInTriangle
(
e3
);
le
=
getLeadingEdgeInTriangle
(
e3
);
#ifdef DEBUG_HE
#ifdef DEBUG_HE
if
(
!
le
)
if
(
!
le
)
errorAndExit
(
"Triangulation::removeTriangle: could not find leading edge"
);
errorAndExit
(
"Triangulation::removeTriangle: could not find leading edge"
);
#endif
#endif
removeLeadingEdgeFromList
(
le
);
removeLeadingEdgeFromList
(
le
);
// The three triangles at the node have now been removed
// The three triangles at the node have now been removed
// from the triangulation, but the arcs have not been deleted.
// from the triangulation, but the arcs have not been deleted.
// Next delete the 6 half edges radiating from the node
// Next delete the 6 half edges radiating from the node
// The node is maintained by handle and need not be deleted explicitly
// The node is maintained by handle and need not be deleted explicitly
EdgePtr
estar
=
edge
;
EDGE_PTR
estar
=
aEdge
;
EdgePtr
enext
=
estar
->
getTwinEdge
()
->
getNextEdgeInFace
();
EDGE_PTR
enext
=
estar
->
GetTwinEdge
()
->
GetNextEdgeInFace
();
estar
->
getTwinEdge
()
->
clear
();
estar
->
GetTwinEdge
()
->
Clear
();
estar
->
clear
();
estar
->
Clear
();
estar
=
enext
;
estar
=
enext
;
enext
=
estar
->
getTwinEdge
()
->
getNextEdgeInFace
();
enext
=
estar
->
GetTwinEdge
()
->
GetNextEdgeInFace
();
estar
->
getTwinEdge
()
->
clear
();
estar
->
GetTwinEdge
()
->
Clear
();
estar
->
clear
();
estar
->
Clear
();
enext
->
getTwinEdge
()
->
clear
();
enext
->
GetTwinEdge
()
->
Clear
();
enext
->
clear
();
enext
->
Clear
();
// Create the new triangle
// Create the new triangle
e1
->
SetNextEdgeInFace
(
e2
);
e1
->
setNextEdgeInFace
(
e2
);
e2
->
SetNextEdgeInFace
(
e3
);
e2
->
setNextEdgeInFace
(
e3
);
e3
->
SetNextEdgeInFace
(
e1
);
e3
->
setNextEdgeInFace
(
e1
);
addLeadingEdge
(
e1
);
addLeadingEdge
(
e1
);
}
}
//--------------------------------------------------------------------------------------------------
DART
TRIANGULATION
::
CreateDart
()
Dart
Triangulation
::
createDart
()
{
{
// Return an arbitrary CCW dart
// Return an arbitrary CCW dart
return
Dart
(
*
leadingEdges_
.
begin
()
);
return
DART
(
*
m_leadingEdges
.
begin
()
);
}
}
//--------------------------------------------------------------------------------------------------
bool
TRIANGULATION
::
removeLeadingEdgeFromList
(
EDGE_PTR
&
aLeadingEdge
)
bool
Triangulation
::
removeLeadingEdgeFromList
(
EdgePtr
&
leadingEdge
)
{
{
// Remove the edge from the list of leading edges,
// Remove the edge from the list of leading edges,
// but don't delete it.
// but don't delete it.
// Also set flag for leading edge to false.
// Also set flag for leading edge to false.
// Must search from start of list. Since edges are added to the
// Must search from start of list. Since edges are added to the
// start of the list during triangulation, this operation will
// start of the list during triangulation, this operation will
// normally be fast (when used in the triangulation algorithm)
// normally be fast (when used in the triangulation algorithm)
std
::
list
<
EDGE_PTR
>::
iterator
it
;
list
<
EdgePtr
>::
iterator
it
;
for
(
it
=
m_leadingEdges
.
begin
();
it
!=
m_leadingEdges
.
end
();
++
it
)
for
(
it
=
leadingEdges_
.
begin
();
it
!=
leadingEdges_
.
end
();
++
it
)
{
{
EDGE_PTR
edge
=
*
it
;
EdgePtr
edge
=
*
it
;
if
(
edge
==
leadingEdge
)
{
if
(
edge
==
aLeadingEdge
)
{
edge
->
setAsLeadingEdge
(
false
);
edge
->
SetAsLeadingEdge
(
false
);
it
=
leadingEdges_
.
erase
(
it
);
it
=
m_leadingEdges
.
erase
(
it
);
return
true
;
return
true
;
}
}
}
}
return
false
;
return
false
;
}
}
//--------------------------------------------------------------------------------------------------
void
TRIANGULATION
::
cleanAll
()
void
Triangulation
::
cleanAll
()
{
{
BOOST_FOREACH
(
EdgePtr
&
edge
,
leadingEdges_
)
BOOST_FOREACH
(
EDGE_PTR
&
edge
,
m_leadingEdges
)
edge
->
setNextEdgeInFace
(
EdgePtr
()
);
edge
->
SetNextEdgeInFace
(
EDGE_PTR
()
);
}
}
//--------------------------------------------------------------------------------------------------
void
TRIANGULATION
::
swapEdge
(
DART
&
aDart
)
void
Triangulation
::
swapEdge
(
Dart
&
dart
)
{
{
swapEdge
(
dart
.
getEdge
()
);
SwapEdge
(
aDart
.
GetEdge
()
);
}
}
//--------------------------------------------------------------------------------------------------
void
TRIANGULATION
::
splitTriangle
(
DART
&
aDart
,
const
NODE_PTR
&
aPoint
)
void
Triangulation
::
splitTriangle
(
Dart
&
dart
,
const
NodePtr
&
point
)
{
{
EdgePtr
edge
=
splitTriangle
(
dart
.
getEdge
(),
point
);
EDGE_PTR
edge
=
SplitTriangle
(
aDart
.
GetEdge
(),
aPoint
);
dart
.
init
(
edge
);
aDart
.
Init
(
edge
);
}
}
//--------------------------------------------------------------------------------------------------
void
TRIANGULATION
::
reverseSplitTriangle
(
DART
&
aDart
)
void
Triangulation
::
reverse_splitTriangle
(
Dart
&
dart
)
{
{
reverse_splitTriangle
(
dart
.
getEdge
()
);
ReverseSplitTriangle
(
aDart
.
GetEdge
()
);
}
}
//--------------------------------------------------------------------------------------------------
void
TRIANGULATION
::
removeBoundaryTriangle
(
DART
&
aDart
)
void
Triangulation
::
removeBoundaryTriangle
(
Dart
&
d
)
{
{
removeTriangle
(
d
.
getEdge
()
);
RemoveTriangle
(
aDart
.
GetEdge
()
);
}
}
#ifdef TTL_USE_NODE_FLAG
#ifdef TTL_USE_NODE_FLAG
//--------------------------------------------------------------------------------------------------
void
TRIANGULATION
::
FlagNodes
(
bool
aFlag
)
const
// This is a "template" for accessing all nodes (but multiple tests)
{
void
Triangulation
::
flagNodes
(
bool
flag
)
const
{
std
::
list
<
EDGE_PTR
>::
const_iterator
it
;
for
(
it
=
m_leadingEdges
.
begin
();
it
!=
m_leadingEdges
.
end
();
++
it
)
list
<
EdgePtr
>::
const_iterator
it
;
{
for
(
it
=
leadingEdges_
.
begin
();
it
!=
leadingEdges_
.
end
();
++
it
)
{
EDGE_PTR
edge
=
*
it
;
EdgePtr
edge
=
*
it
;
for
(
int
i
=
0
;
i
<
3
;
++
i
)
for
(
int
i
=
0
;
i
<
3
;
++
i
)
{
{
edge
->
getSourceNode
()
->
SetFlag
(
flag
);
edge
->
GetSourceNode
()
->
SetFlag
(
aFlag
);
edge
=
edge
->
getNextEdgeInFace
();
edge
=
edge
->
GetNextEdgeInFace
();
}
}
}
}
}
}
//--------------------------------------------------------------------------------------------------
std
::
list
<
NODE_PTR
>*
TRIANGULATION
::
GetNodes
()
const
list
<
NodePtr
>*
Triangulation
::
getNodes
()
const
{
{
FlagNodes
(
false
);
flagNodes
(
false
);
std
::
list
<
NODE_PTR
>*
nodeList
=
new
std
::
list
<
NODE_PTR
>
;
list
<
NodePtr
>*
nodeList
=
new
list
<
NodePtr
>
;
std
::
list
<
EDGE_PTR
>::
const_iterator
it
;
list
<
EdgePtr
>::
const_iterator
it
;
for
(
it
=
m_leadingEdges
.
begin
();
it
!=
m_leadingEdges
.
end
();
++
it
)
for
(
it
=
leadingEdges_
.
begin
();
it
!=
leadingEdges_
.
end
();
++
it
)
{
{
EdgePtr
edge
=
*
it
;
EDGE_PTR
edge
=
*
it
;
for
(
int
i
=
0
;
i
<
3
;
++
i
)
{
for
(
int
i
=
0
;
i
<
3
;
++
i
)
const
NodePtr
&
node
=
edge
->
getSourceNode
();
{
const
NODE_PTR
&
node
=
edge
->
GetSourceNode
();
if
(
node
->
GetFlag
()
==
false
)
{
nodeList
->
push_back
(
node
);
if
(
node
->
GetFlag
()
==
false
)
node
->
SetFlag
(
true
);
{
}
nodeList
->
push_back
(
node
);
edge
=
edge
->
getNextEdgeInFace
();
node
->
SetFlag
(
true
);
}
edge
=
edge
->
GetNextEdgeInFace
();
}
}
}
}
return
nodeList
;
return
nodeList
;
}
}
#endif
#endif
//--------------------------------------------------------------------------------------------------
std
::
list
<
EDGE_PTR
>*
TRIANGULATION
::
GetEdges
(
bool
aSkipBoundaryEdges
)
const
list
<
EdgePtr
>*
Triangulation
::
getEdges
(
bool
skip_boundary_edges
)
const
{
{
// collect all arcs (one half edge for each arc)
// collect all arcs (one half edge for each arc)
// (boundary edges are also collected).
// (boundary edges are also collected).
std
::
list
<
EDGE_PTR
>::
const_iterator
it
;
std
::
list
<
EDGE_PTR
>*
elist
=
new
std
::
list
<
EDGE_PTR
>
;
list
<
EdgePtr
>::
const_iterator
it
;
list
<
EdgePtr
>*
elist
=
new
list
<
EdgePtr
>
;
for
(
it
=
m_leadingEdges
.
begin
();
it
!=
m_leadingEdges
.
end
();
++
it
)
for
(
it
=
leadingEdges_
.
begin
();
it
!=
leadingEdges_
.
end
();
++
it
)
{
{
EdgePtr
edge
=
*
it
;
EDGE_PTR
edge
=
*
it
;
for
(
int
i
=
0
;
i
<
3
;
++
i
)
{
for
(
int
i
=
0
;
i
<
3
;
++
i
)
EdgePtr
twinedge
=
edge
->
getTwinEdge
();
{
// only one of the half-edges
EDGE_PTR
twinedge
=
edge
->
GetTwinEdge
();
// only one of the half-edges
if
(
(
!
twinedge
&&
!
skip_boundary_edges
)
||
(
twinedge
&&
((
size_t
)
edge
.
get
()
>
(
size_t
)
twinedge
.
get
()))
)
if
(
(
!
twinedge
&&
!
aSkipBoundaryEdges
)
elist
->
push_front
(
edge
);
||
(
twinedge
&&
(
(
size_t
)
edge
.
get
()
>
(
size_t
)
twinedge
.
get
()
)
)
)
elist
->
push_front
(
edge
);
edge
=
edge
->
getNextEdgeInFace
();
edge
=
edge
->
GetNextEdgeInFace
();
}
}
}
}
return
elist
;
return
elist
;
}
}
//--------------------------------------------------------------------------------------------------
EDGE_PTR
TRIANGULATION
::
SplitTriangle
(
EDGE_PTR
&
aEdge
,
const
NODE_PTR
&
aPoint
)
EdgePtr
Triangulation
::
splitTriangle
(
EdgePtr
&
edge
,
const
NodePtr
&
point
)
{
{
// Add a node by just splitting a triangle into three triangles
// Add a node by just splitting a triangle into three triangles
// Assumes the half aEdge is located in the triangle
// Assumes the half edge is located in the triangle
// Returns a half aEdge with source node as the new node
// Returns a half edge with source node as the new node
// e#_n are new edges
// double x, y, z;
// e# are existing edges
// x = point.x();
// e#_n and e##_n are new twin edges
// y = point.y();
// e##_n are edges incident to the new node
// z = point.z();
// Add the node to the structure
// e#_n are new edges
//NODE_PTR new_node(new Node(x,y,z));
// e# are existing edges
// e#_n and e##_n are new twin edges
NODE_PTR
n1
(
aEdge
->
GetSourceNode
()
);
// e##_n are edges incident to the new node
EDGE_PTR
e1
(
aEdge
);
// Add the node to the structure
EDGE_PTR
e2
(
aEdge
->
GetNextEdgeInFace
()
);
//NodePtr new_node(new Node(x,y,z));
NODE_PTR
n2
(
e2
->
GetSourceNode
()
);
NodePtr
n1
(
edge
->
getSourceNode
());
EDGE_PTR
e3
(
e2
->
GetNextEdgeInFace
()
);
EdgePtr
e1
(
edge
);
NODE_PTR
n3
(
e3
->
GetSourceNode
()
);
EdgePtr
e2
(
edge
->
getNextEdgeInFace
());
EDGE_PTR
e1_n
=
boost
::
make_shared
<
EDGE
>
();
NodePtr
n2
(
e2
->
getSourceNode
());
EDGE_PTR
e11_n
=
boost
::
make_shared
<
EDGE
>
();
EDGE_PTR
e2_n
=
boost
::
make_shared
<
EDGE
>
();
EdgePtr
e3
(
e2
->
getNextEdgeInFace
());
EDGE_PTR
e22_n
=
boost
::
make_shared
<
EDGE
>
();
NodePtr
n3
(
e3
->
getSourceNode
());
EDGE_PTR
e3_n
=
boost
::
make_shared
<
EDGE
>
();
EDGE_PTR
e33_n
=
boost
::
make_shared
<
EDGE
>
();
EdgePtr
e1_n
=
boost
::
make_shared
<
Edge
>
();
EdgePtr
e11_n
=
boost
::
make_shared
<
Edge
>
();
e1_n
->
SetSourceNode
(
n1
);
EdgePtr
e2_n
=
boost
::
make_shared
<
Edge
>
();
e11_n
->
SetSourceNode
(
aPoint
);
EdgePtr
e22_n
=
boost
::
make_shared
<
Edge
>
();
e2_n
->
SetSourceNode
(
n2
);
EdgePtr
e3_n
=
boost
::
make_shared
<
Edge
>
();
e22_n
->
SetSourceNode
(
aPoint
);
EdgePtr
e33_n
=
boost
::
make_shared
<
Edge
>
();
e3_n
->
SetSourceNode
(
n3
);
e33_n
->
SetSourceNode
(
aPoint
);
e1_n
->
setSourceNode
(
n1
);
e11_n
->
setSourceNode
(
point
);
e1_n
->
SetTwinEdge
(
e11_n
);
e2_n
->
setSourceNode
(
n2
);
e11_n
->
SetTwinEdge
(
e1_n
);
e22_n
->
setSourceNode
(
point
);
e2_n
->
SetTwinEdge
(
e22_n
);
e3_n
->
setSourceNode
(
n3
);
e22_n
->
SetTwinEdge
(
e2_n
);
e33_n
->
setSourceNode
(
point
);
e3_n
->
SetTwinEdge
(
e33_n
);
e33_n
->
SetTwinEdge
(
e3_n
);
e1_n
->
setTwinEdge
(
e11_n
);
e11_n
->
setTwinEdge
(
e1_n
);
e1_n
->
SetNextEdgeInFace
(
e33_n
);
e2_n
->
setTwinEdge
(
e22_n
);
e2_n
->
SetNextEdgeInFace
(
e11_n
);
e22_n
->
setTwinEdge
(
e2_n
);
e3_n
->
SetNextEdgeInFace
(
e22_n
);
e3_n
->
setTwinEdge
(
e33_n
);
e33_n
->
setTwinEdge
(
e3_n
);
e11_n
->
SetNextEdgeInFace
(
e1
);
e22_n
->
SetNextEdgeInFace
(
e2
);
e1_n
->
setNextEdgeInFace
(
e33_n
);
e33_n
->
SetNextEdgeInFace
(
e3
);
e2_n
->
setNextEdgeInFace
(
e11_n
);
e3_n
->
setNextEdgeInFace
(
e22_n
);
// and update old's next aEdge
e1
->
SetNextEdgeInFace
(
e2_n
);
e11_n
->
setNextEdgeInFace
(
e1
);
e2
->
SetNextEdgeInFace
(
e3_n
);
e22_n
->
setNextEdgeInFace
(
e2
);
e3
->
SetNextEdgeInFace
(
e1_n
);
e33_n
->
setNextEdgeInFace
(
e3
);
// add the three new leading edges,
// and update old's next edge
// Must remove the old leading aEdge from the list.
e1
->
setNextEdgeInFace
(
e2_n
);
// Use the field telling if an aEdge is a leading aEdge
e2
->
setNextEdgeInFace
(
e3_n
);
// NOTE: Must search in the list!!!
e3
->
setNextEdgeInFace
(
e1_n
);
if
(
e1
->
IsLeadingEdge
()
)
// add the three new leading edges,
removeLeadingEdgeFromList
(
e1
);
// Must remove the old leading edge from the list.
else
if
(
e2
->
IsLeadingEdge
()
)
// Use the field telling if an edge is a leading edge
removeLeadingEdgeFromList
(
e2
);
// NOTE: Must search in the list!!!
else
if
(
e3
->
IsLeadingEdge
()
)
removeLeadingEdgeFromList
(
e3
);
if
(
e1
->
isLeadingEdge
())
else
removeLeadingEdgeFromList
(
e1
);
assert
(
false
);
// one of the edges should be leading
else
if
(
e2
->
isLeadingEdge
())
removeLeadingEdgeFromList
(
e2
);
addLeadingEdge
(
e1_n
);
else
if
(
e3
->
isLeadingEdge
())
addLeadingEdge
(
e2_n
);
removeLeadingEdgeFromList
(
e3
);
addLeadingEdge
(
e3_n
);
else
assert
(
false
);
// one of the edges should be leading
// Return a half aEdge incident to the new node (with the new node as source node)
addLeadingEdge
(
e1_n
);
return
e11_n
;
addLeadingEdge
(
e2_n
);
addLeadingEdge
(
e3_n
);
// Return a half edge incident to the new node (with the new node as source node)
return
e11_n
;
}
}
//--------------------------------------------------------------------------------------------------
void
TRIANGULATION
::
SwapEdge
(
EDGE_PTR
&
aDiagonal
)
void
Triangulation
::
swapEdge
(
EdgePtr
&
diagonal
)
{
{
// Note that diagonal is both input and output and it is always
// Note that diagonal is both input and output and it is always
// kept in counterclockwise direction (this is not required by all
// kept in counterclockwise direction (this is not required by all
// functions in TriangulationHelper now)
// functions in TriangulationHelper now)
// Swap by rotating counterclockwise
// Swap by rotating counterclockwise
// Use the same objects - no deletion or new objects
// Use the same objects - no deletion or new objects
EDGE_PTR
eL
(
aDiagonal
);
EdgePtr
eL
(
diagonal
);
EDGE_PTR
eR
(
eL
->
GetTwinEdge
()
);
EdgePtr
eR
(
eL
->
getTwinEdge
());
EDGE_PTR
eL_1
(
eL
->
GetNextEdgeInFace
()
);
EdgePtr
eL_1
(
eL
->
getNextEdgeInFace
());
EDGE_PTR
eL_2
(
eL_1
->
GetNextEdgeInFace
()
);
EdgePtr
eL_2
(
eL_1
->
getNextEdgeInFace
());
EDGE_PTR
eR_1
(
eR
->
GetNextEdgeInFace
()
);
EdgePtr
eR_1
(
eR
->
getNextEdgeInFace
());
EDGE_PTR
eR_2
(
eR_1
->
GetNextEdgeInFace
()
);
EdgePtr
eR_2
(
eR_1
->
getNextEdgeInFace
());
// avoid node to be dereferenced to zero and deleted
// avoid node to be dereferenced to zero and deleted
NODE_PTR
nR
(
eR_2
->
GetSourceNode
()
);
NodePtr
nR
(
eR_2
->
getSourceNode
());
NODE_PTR
nL
(
eL_2
->
GetSourceNode
()
);
NodePtr
nL
(
eL_2
->
getSourceNode
());
eL
->
SetSourceNode
(
nR
);
eL
->
setSourceNode
(
nR
);
eR
->
SetSourceNode
(
nL
);
eR
->
setSourceNode
(
nL
);
// and now 6 1-sewings
// and now 6 1-sewings
eL
->
SetNextEdgeInFace
(
eL_2
);
eL
->
setNextEdgeInFace
(
eL_2
);
eL_2
->
SetNextEdgeInFace
(
eR_1
);
eL_2
->
setNextEdgeInFace
(
eR_1
);
eR_1
->
SetNextEdgeInFace
(
eL
);
eR_1
->
setNextEdgeInFace
(
eL
);
eR
->
SetNextEdgeInFace
(
eR_2
);
eR
->
setNextEdgeInFace
(
eR_2
);
eR_2
->
SetNextEdgeInFace
(
eL_1
);
eR_2
->
setNextEdgeInFace
(
eL_1
);
eL_1
->
SetNextEdgeInFace
(
eR
);
eL_1
->
setNextEdgeInFace
(
eR
);
if
(
eL
->
IsLeadingEdge
()
)
if
(
eL
->
isLeadingEdge
())
removeLeadingEdgeFromList
(
eL
);
removeLeadingEdgeFromList
(
eL
);
else
if
(
eL_1
->
IsLeadingEdge
()
)
else
if
(
eL_1
->
isLeadingEdge
())
removeLeadingEdgeFromList
(
eL_1
);
removeLeadingEdgeFromList
(
eL_1
);
else
if
(
eL_2
->
IsLeadingEdge
()
)
else
if
(
eL_2
->
isLeadingEdge
())
removeLeadingEdgeFromList
(
eL_2
);
removeLeadingEdgeFromList
(
eL_2
);
if
(
eR
->
IsLeadingEdge
()
)
if
(
eR
->
isLeadingEdge
())
removeLeadingEdgeFromList
(
eR
);
removeLeadingEdgeFromList
(
eR
);
else
if
(
eR_1
->
IsLeadingEdge
()
)
else
if
(
eR_1
->
isLeadingEdge
())
removeLeadingEdgeFromList
(
eR_1
);
removeLeadingEdgeFromList
(
eR_1
);
else
if
(
eR_2
->
IsLeadingEdge
()
)
else
if
(
eR_2
->
isLeadingEdge
())
removeLeadingEdgeFromList
(
eR_2
);
removeLeadingEdgeFromList
(
eR_2
);
addLeadingEdge
(
eL
);
addLeadingEdge
(
eL
);
addLeadingEdge
(
eR
);
addLeadingEdge
(
eR
);
}
}
////--------------------------------------------------------------------------
bool
TRIANGULATION
::
CheckDelaunay
()
const
//static void printEdge(const Dart& dart, ostream& ofile) {
{
//
// ???? outputs !!!!
// Dart d0 = dart;
// ofstream os("qweND.dat");
// d0.alpha0();
const
std
::
list
<
EDGE_PTR
>&
leadingEdges
=
GetLeadingEdges
();
//
// ofile << dart.x() << " " << dart.y() << endl;
std
::
list
<
EDGE_PTR
>::
const_iterator
it
;
// ofile << d0.x() << " " << d0.y() << endl;
bool
ok
=
true
;
//}
int
noNotDelaunay
=
0
;
for
(
it
=
leadingEdges
.
begin
();
it
!=
leadingEdges
.
end
();
++
it
)
//--------------------------------------------------------------------------
{
bool
Triangulation
::
checkDelaunay
()
const
{
EDGE_PTR
edge
=
*
it
;
// ???? outputs !!!!
for
(
int
i
=
0
;
i
<
3
;
++
i
)
// ofstream os("qweND.dat");
{
const
list
<
EdgePtr
>&
leadingEdges
=
getLeadingEdges
();
EDGE_PTR
twinedge
=
edge
->
GetTwinEdge
();
list
<
EdgePtr
>::
const_iterator
it
;
// only one of the half-edges
bool
ok
=
true
;
if
(
!
twinedge
||
(
size_t
)
edge
.
get
()
>
(
size_t
)
twinedge
.
get
()
)
int
noNotDelaunay
=
0
;
{
DART
dart
(
edge
);
for
(
it
=
leadingEdges
.
begin
();
it
!=
leadingEdges
.
end
();
++
it
)
{
if
(
m_helper
->
SwapTestDelaunay
<
TTLtraits
>
(
dart
)
)
EdgePtr
edge
=
*
it
;
{
noNotDelaunay
++
;
for
(
int
i
=
0
;
i
<
3
;
++
i
)
{
EdgePtr
twinedge
=
edge
->
getTwinEdge
();
//printEdge(dart,os); os << "\n";
ok
=
false
;
// only one of the half-edges
//cout << "............. not Delaunay .... " << endl;
if
(
!
twinedge
||
(
size_t
)
edge
.
get
()
>
(
size_t
)
twinedge
.
get
())
{
}
Dart
dart
(
edge
);
}
if
(
helper
->
swapTestDelaunay
<
TTLtraits
>
(
dart
))
{
noNotDelaunay
++
;
edge
=
edge
->
GetNextEdgeInFace
();
//printEdge(dart,os); os << "\n";
ok
=
false
;
//cout << "............. not Delaunay .... " << endl;
}
}
}
edge
=
edge
->
getNextEdgeInFace
();
}
}
}
#ifdef DEBUG_HE
#ifdef DEBUG_HE
cout
<<
"!!! Triangulation is NOT Delaunay: "
<<
noNotDelaunay
<<
" edges
\n
"
<<
endl
;
cout
<<
"!!! Triangulation is NOT Delaunay: "
<<
noNotDelaunay
<<
" edges
\n
"
<<
endl
;
#endif
#endif
return
ok
;
return
ok
;
}
}
//--------------------------------------------------------------------------------------------------
void
TRIANGULATION
::
OptimizeDelaunay
()
void
Triangulation
::
optimizeDelaunay
()
{
{
// This function is also present in ttl where it is implemented
// This function is also present in ttl where it is implemented
// generically.
// generically.
// The implementation below is tailored for the half-edge data structure,
// The implementation below is tailored for the half-edge data structure,
// and is thus more efficient
// and is thus more efficient
// Collect all interior edges (one half edge for each arc)
// Collect all interior edges (one half edge for each arc)
bool
skip_boundary_edges
=
true
;
bool
skip_boundary_edges
=
true
;
std
::
list
<
EDGE_PTR
>*
elist
=
GetEdges
(
skip_boundary_edges
);
list
<
EdgePtr
>*
elist
=
getEdges
(
skip_boundary_edges
);
// Assumes that elist has only one half-edge for each arc.
// Assumes that elist has only one half-edge for each arc.
bool
cycling_check
=
true
;
bool
cycling_check
=
true
;
bool
optimal
=
false
;
bool
optimal
=
false
;
std
::
list
<
EDGE_PTR
>::
const_iterator
it
;
list
<
EdgePtr
>::
const_iterator
it
;
while
(
!
optimal
)
{
while
(
!
optimal
)
optimal
=
true
;
{
for
(
it
=
elist
->
begin
();
it
!=
elist
->
end
();
++
it
)
{
optimal
=
true
;
EdgePtr
edge
=
*
it
;
for
(
it
=
elist
->
begin
();
it
!=
elist
->
end
();
++
it
)
Dart
dart
(
edge
);
{
// Constrained edges should not be swapped
EDGE_PTR
edge
=
*
it
;
if
(
helper
->
swapTestDelaunay
<
TTLtraits
>
(
dart
,
cycling_check
))
{
optimal
=
false
;
DART
dart
(
edge
);
swapEdge
(
edge
);
// Constrained edges should not be swapped
}
if
(
m_helper
->
SwapTestDelaunay
<
TTLtraits
>
(
dart
,
cycling_check
)
)
{
optimal
=
false
;
SwapEdge
(
edge
);
}
}
}
}
}
delete
elist
;
delete
elist
;
}
}
//--------------------------------------------------------------------------------------------------
EDGE_PTR
TRIANGULATION
::
GetInteriorNode
()
const
EdgePtr
Triangulation
::
getInteriorNode
()
const
{
{
const
std
::
list
<
EDGE_PTR
>&
leadingEdges
=
GetLeadingEdges
();
const
list
<
EdgePtr
>&
leadingEdges
=
getLeadingEdges
();
std
::
list
<
EDGE_PTR
>::
const_iterator
it
;
list
<
EdgePtr
>::
const_iterator
it
;
for
(
it
=
leadingEdges
.
begin
();
it
!=
leadingEdges
.
end
();
++
it
)
{
EdgePtr
edge
=
*
it
;
// multiple checks, but only until found
for
(
it
=
leadingEdges
.
begin
();
it
!=
leadingEdges
.
end
();
++
it
)
for
(
int
i
=
0
;
i
<
3
;
++
i
)
{
{
if
(
edge
->
getTwinEdge
())
{
EDGE_PTR
edge
=
*
it
;
if
(
!
helper
->
isBoundaryNode
(
Dart
(
edge
)))
// multiple checks, but only until found
return
edge
;
for
(
int
i
=
0
;
i
<
3
;
++
i
)
}
{
edge
=
edge
->
getNextEdgeInFace
();
if
(
edge
->
GetTwinEdge
()
)
{
if
(
!
m_helper
->
IsBoundaryNode
(
DART
(
edge
)
)
)
return
edge
;
}
edge
=
edge
->
GetNextEdgeInFace
();
}
}
}
}
return
EdgePtr
();
// no boundary nodes
return
EDGE_PTR
();
// no boundary nodes
}
}
//--------------------------------------------------------------------------------------------------
EDGE_PTR
TRIANGULATION
::
GetBoundaryEdgeInTriangle
(
const
EDGE_PTR
&
aEdge
)
const
EdgePtr
Triangulation
::
getBoundaryEdgeInTriangle
(
const
EdgePtr
&
e
)
const
{
{
EdgePtr
edge
=
e
;
EDGE_PTR
edge
=
aEdge
;
if
(
helper
->
isBoundaryEdge
(
Dart
(
edge
)))
return
edge
;
edge
=
edge
->
getNextEdgeInFace
();
if
(
m_helper
->
IsBoundaryEdge
(
DART
(
edge
)
)
)
if
(
helper
->
isBoundaryEdge
(
Dart
(
edge
)))
return
edge
;
return
edge
;
edge
=
edge
->
getNextEdgeInFace
();
edge
=
edge
->
GetNextEdgeInFace
();
if
(
helper
->
isBoundaryEdge
(
Dart
(
edge
)))
if
(
m_helper
->
IsBoundaryEdge
(
DART
(
edge
)
)
)
return
edge
;
return
edge
;
return
EdgePtr
();
edge
=
edge
->
GetNextEdgeInFace
();
if
(
m_helper
->
IsBoundaryEdge
(
DART
(
edge
)
)
)
return
edge
;
return
EDGE_PTR
();
}
}
//--------------------------------------------------------------------------------------------------
EDGE_PTR
TRIANGULATION
::
GetBoundaryEdge
()
const
EdgePtr
Triangulation
::
getBoundaryEdge
()
const
{
{
// Get an arbitrary (CCW) boundary edge
// If the triangulation is closed, NULL is returned
const
std
::
list
<
EDGE_PTR
>&
leadingEdges
=
GetLeadingEdges
();
std
::
list
<
EDGE_PTR
>::
const_iterator
it
;
EDGE_PTR
edge
;
// Get an arbitrary (CCW) boundary edge
for
(
it
=
leadingEdges
.
begin
();
it
!=
leadingEdges
.
end
();
++
it
)
// If the triangulation is closed, NULL is returned
{
edge
=
GetBoundaryEdgeInTriangle
(
*
it
);
const
list
<
EdgePtr
>&
leadingEdges
=
getLeadingEdges
();
if
(
edge
)
list
<
EdgePtr
>::
const_iterator
it
;
return
edge
;
EdgePtr
edge
;
}
return
EDGE_PTR
();
for
(
it
=
leadingEdges
.
begin
();
it
!=
leadingEdges
.
end
();
++
it
)
{
edge
=
getBoundaryEdgeInTriangle
(
*
it
);
if
(
edge
)
return
edge
;
}
return
EdgePtr
();
}
}
//--------------------------------------------------------------------------------------------------
void
TRIANGULATION
::
PrintEdges
(
std
::
ofstream
&
aOutput
)
const
void
Triangulation
::
printEdges
(
ofstream
&
os
)
const
{
{
// Print source node and target node for each edge face by face,
// Print source node and target node for each edge face by face,
// but only one of the half-edges.
// but only one of the half-edges.
const
std
::
list
<
EDGE_PTR
>&
leadingEdges
=
GetLeadingEdges
();
std
::
list
<
EDGE_PTR
>::
const_iterator
it
;
const
list
<
EdgePtr
>&
leadingEdges
=
getLeadingEdges
();
list
<
EdgePtr
>::
const_iterator
it
;
for
(
it
=
leadingEdges
.
begin
();
it
!=
leadingEdges
.
end
();
++
it
)
for
(
it
=
leadingEdges
.
begin
();
it
!=
leadingEdges
.
end
();
++
it
)
{
{
EdgePtr
edge
=
*
it
;
EDGE_PTR
edge
=
*
it
;
for
(
int
i
=
0
;
i
<
3
;
++
i
)
{
for
(
int
i
=
0
;
i
<
3
;
++
i
)
EdgePtr
twinedge
=
edge
->
getTwinEdge
();
{
EDGE_PTR
twinedge
=
edge
->
GetTwinEdge
();
// Print only one edge (the highest value of the pointer)
if
(
!
twinedge
||
(
size_t
)
edge
.
get
()
>
(
size_t
)
twinedge
.
get
())
{
// Print only one edge (the highest value of the pointer)
// Print source node and target node
if
(
!
twinedge
||
(
size_t
)
edge
.
get
()
>
(
size_t
)
twinedge
.
get
()
)
NodePtr
node
=
edge
->
getSourceNode
();
{
os
<<
node
->
GetX
()
<<
" "
<<
node
->
GetY
()
<<
endl
;
// Print source node and target node
node
=
edge
->
getTargetNode
();
NODE_PTR
node
=
edge
->
GetSourceNode
();
os
<<
node
->
GetX
()
<<
" "
<<
node
->
GetY
()
<<
endl
;
aOutput
<<
node
->
GetX
()
<<
" "
<<
node
->
GetY
()
<<
std
::
endl
;
os
<<
'\n'
;
// blank line
node
=
edge
->
GetTargetNode
();
}
aOutput
<<
node
->
GetX
()
<<
" "
<<
node
->
GetY
()
<<
std
::
endl
;
edge
=
edge
->
getNextEdgeInFace
();
aOutput
<<
'\n'
;
// blank line
}
edge
=
edge
->
GetNextEdgeInFace
();
}
}
}
}
}
}
include/ttl/halfedge/hedart.h
View file @
6fa2f060
...
@@ -40,111 +40,152 @@
...
@@ -40,111 +40,152 @@
#ifndef _HALF_EDGE_DART_
#ifndef _HALF_EDGE_DART_
#define _HALF_EDGE_DART_
#define _HALF_EDGE_DART_
#include <ttl/halfedge/hetriang.h>
#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
/// Default constructor
Dart
()
{
dir_
=
true
;
}
DART
()
{
m_dir
=
true
;
}
/// Constructor
/// 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
/// 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
/// Destructor
~
Dart
()
{}
~
DART
()
{
}
/// Assignment operator
/// Assignment operator
Dart
&
operator
=
(
const
Dart
&
dart
)
{
DART
&
operator
=
(
const
DART
&
aDart
)
if
(
this
==
&
dart
)
{
if
(
this
==
&
aDart
)
return
*
this
;
m_edge
=
aDart
.
m_edge
;
m_dir
=
aDart
.
m_dir
;
return
*
this
;
return
*
this
;
edge_
=
dart
.
edge_
;
dir_
=
dart
.
dir_
;
return
*
this
;
}
}
/// Comparing dart objects
/// Comparing dart objects
bool
operator
==
(
const
Dart
&
dart
)
const
{
bool
operator
==
(
const
DART
&
aDart
)
const
if
(
dart
.
edge_
==
edge_
&&
dart
.
dir_
==
dir_
)
{
return
true
;
return
(
aDart
.
m_edge
==
m_edge
&&
aDart
.
m_dir
==
m_dir
);
return
false
;
}
}
/// Comparing dart objects
/// Comparing dart objects
bool
operator
!=
(
const
Dart
&
dart
)
const
{
bool
operator
!=
(
const
DART
&
aDart
)
const
return
!
(
dart
==*
this
);
{
return
!
(
aDart
==
*
this
);
}
}
/// Maps the dart to a different node
/// 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
/// Maps the dart to a different edge
Dart
&
alpha1
()
{
DART
&
Alpha1
()
if
(
dir_
)
{
{
edge_
=
edge_
->
getNextEdgeInFace
()
->
getNextEdgeInFace
();
if
(
m_dir
)
dir_
=
false
;
{
}
m_edge
=
m_edge
->
GetNextEdgeInFace
()
->
GetNextEdgeInFace
();
else
{
m_dir
=
false
;
edge_
=
edge_
->
getNextEdgeInFace
();
}
dir_
=
true
;
else
}
{
return
*
this
;
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!
/// Maps the dart to a different triangle. \b Note: the dart is not changed if it is at the boundary!
Dart
&
alpha2
()
{
DART
&
Alpha2
()
if
(
edge_
->
getTwinEdge
())
{
{
edge_
=
edge_
->
getTwinEdge
();
if
(
m_edge
->
GetTwinEdge
()
)
dir_
=
!
dir_
;
{
}
m_edge
=
m_edge
->
GetTwinEdge
();
// else, the dart is at the boundary and should not be changed
m_dir
=
!
m_dir
;
return
*
this
;
}
// 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 */
/** @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
double
y
()
const
{
return
getNode
()
->
GetY
();
}
// y-coordinate of source node
{
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
NODE_PTR
&
GetNode
()
const
const
NodePtr
&
getOppositeNode
()
const
{
return
dir_
?
edge_
->
getTargetNode
()
:
edge_
->
getSourceNode
();
}
{
EdgePtr
&
getEdge
()
{
return
edge_
;
}
return
m_dir
?
m_edge
->
GetSourceNode
()
:
m_edge
->
GetTargetNode
();
}
//@} // End of Utilities not required by TTL
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
#endif
include/ttl/halfedge/hetraits.h
View file @
6fa2f060
...
@@ -40,136 +40,149 @@
...
@@ -40,136 +40,149 @@
#ifndef _HALF_EDGE_TRAITS_
#ifndef _HALF_EDGE_TRAITS_
#define _HALF_EDGE_TRAITS_
#define _HALF_EDGE_TRAITS_
#include <ttl/halfedge/hetriang.h>
#include <ttl/halfedge/hetriang.h>
#include <ttl/halfedge/hedart.h>
#include <ttl/halfedge/hedart.h>
namespace
hed
namespace
hed
{
{
/**
* \struct TTLtraits
//------------------------------------------------------------------------------------------------
* \brief \b Traits class (static struct) for the half-edge data structure.
// Traits class 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
/** \struct TTLtraits
* should be carried out on the actual data structure as required by the functions
* \brief \b Traits class (static struct) for the half-edge data structure.
* in the \ref ttl namespace.
*
*
* The member functions are those required by different function templates
* The source code of \c %HeTraits.h shows how the traits class is implemented for the
* in the TTL. Documentation is given here to explain what actions
* half-edge data structure.
* should be carried out on the actual data structure as required by the functions
*
* in the \ref ttl namespace.
* \see \ref api
*
*/
* The source code of \c %HeTraits.h shows how the traits class is implemented for the
struct
TTLtraits
* half-edge data structure.
{
*
/**
* \see \ref api
* The floating point type used in calculations involving scalar products and cross products.
*
*/
*/
typedef
double
REAL_TYPE
;
struct
TTLtraits
{
/** The floating point type used in calculations
* involving scalar products and cross products.
*/
typedef
double
real_type
;
//----------------------------------------------------------------------------------------------
// ------------------------------- Geometric Predicates Group ---------------------------------
//----------------------------------------------------------------------------------------------
/** @name Geometric Predicates */
/** @name Geometric Predicates */
//@{
//@{
/**
//----------------------------------------------------------------------------------------------
* Scalar product between two 2D vectors represented as darts.\n
/** Scalar product between two 2D vectors represented as darts.\n
*
*
* ttl_util::scalarProduct2d can be used.
* ttl_util::scalarProduct2d can be used.
*/
*/
static
REAL_TYPE
ScalarProduct2D
(
const
DART
&
aV1
,
const
DART
&
aV2
)
static
real_type
scalarProduct2d
(
const
Dart
&
v1
,
const
Dart
&
v2
)
{
{
Dart
v10
=
v1
;
v10
.
alpha0
();
DART
v10
=
aV1
;
Dart
v20
=
v2
;
v20
.
alpha0
();
v10
.
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.
/** Scalar product between two 2D vectors.
* The first vector is represented by a dart \e v, and the second
* 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
* vector has direction from the source node of \e v to the point \e p.\n
*
*
* ttl_util::ScalarProduct2D can be used.
* ttl_util::scalarProduct2d can be used.
*/
*/
static
REAL_TYPE
ScalarProduct2D
(
const
DART
&
aV
,
const
NODE_PTR
&
aP
)
static
real_type
scalarProduct2d
(
const
Dart
&
v
,
const
NodePtr
&
p
)
{
{
Dart
d0
=
v
;
d0
.
alpha0
();
DART
d0
=
aV
;
return
ttl_util
::
scalarProduct2d
(
d0
.
x
()
-
v
.
x
(),
d0
.
y
()
-
v
.
y
(),
d0
.
Alpha0
();
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.
/** Cross product between two vectors in the plane represented as darts.
* The z-component of the cross product is returned.\n
* The z-component of the cross product is returned.\n
*
*
* ttl_util::CrossProduct2D can be used.
* ttl_util::crossProduct2d can be used.
*/
*/
static
REAL_TYPE
CrossProduct2D
(
const
DART
&
aV1
,
const
DART
&
aV2
)
static
real_type
crossProduct2d
(
const
Dart
&
v1
,
const
Dart
&
v2
)
{
{
Dart
v10
=
v1
;
v10
.
alpha0
();
DART
v10
=
aV1
;
Dart
v20
=
v2
;
v20
.
alpha0
();
v10
.
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.
/** Cross product between two vectors in the plane.
* The first vector is represented by a dart \e v, and the second
* 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.
* 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
* The z-component of the cross product is returned.\n
*
*
* ttl_util::CrossProduct2d can be used.
* ttl_util::crossProduct2d can be used.
*/
*/
static
REAL_TYPE
CrossProduct2D
(
const
DART
&
aV
,
const
NODE_PTR
&
aP
)
static
real_type
crossProduct2d
(
const
Dart
&
v
,
const
NodePtr
&
p
)
{
{
Dart
d0
=
v
;
d0
.
alpha0
();
DART
d0
=
aV
;
return
ttl_util
::
crossProduct2d
(
d0
.
x
()
-
v
.
x
(),
d0
.
y
()
-
v
.
y
(),
d0
.
Alpha0
();
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
/** 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,
* 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
* and \e p occur in counterclockwise order; a negative value if they occur
* in clockwise order; and zero if they are collinear.
* in clockwise order; and zero if they are collinear.
*/
*/
static
REAL_TYPE
Orient2D
(
const
DART
&
aN1
,
const
DART
&
aN2
,
const
NODE_PTR
&
aP
)
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
];
REAL_TYPE
pa
[
2
];
pa
[
0
]
=
n1
.
x
();
pa
[
1
]
=
n1
.
y
();
REAL_TYPE
pb
[
2
];
pb
[
0
]
=
n2
.
x
();
pb
[
1
]
=
n2
.
y
();
REAL_TYPE
pc
[
2
];
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,
/** This is the same predicate as represented with the function above,
* but with a slighty different interface:
* but with a slighty different interface:
* The last parameter is given as a dart where the source node of the dart
* The last parameter is given as a dart where the source node of the dart
* represents a point in the plane.
* represents a point in the plane.
* This function is required for constrained triangulation.
* This function is required for constrained triangulation.
*/
*/
static
REAL_TYPE
Orient2D
(
const
DART
&
aN1
,
const
DART
&
aN2
,
const
DART
&
aP
)
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
];
REAL_TYPE
pa
[
2
];
pa
[
0
]
=
n1
.
x
();
pa
[
1
]
=
n1
.
y
();
REAL_TYPE
pb
[
2
];
pb
[
0
]
=
n2
.
x
();
pb
[
1
]
=
n2
.
y
();
REAL_TYPE
pc
[
2
];
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 Geometric Predicates Group
};
};
};
// End of hed namespace
};
// End of hed namespace
...
...
include/ttl/halfedge/hetriang.h
View file @
6fa2f060
...
@@ -42,11 +42,9 @@
...
@@ -42,11 +42,9 @@
#ifndef _HE_TRIANG_H_
#ifndef _HE_TRIANG_H_
#define _HE_TRIANG_H_
#define _HE_TRIANG_H_
#define TTL_USE_NODE_ID // Each node gets it's own unique id
#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)
#define TTL_USE_NODE_FLAG // Each node gets a flag (can be set to true or false)
#include <list>
#include <list>
#include <vector>
#include <vector>
#include <iostream>
#include <iostream>
...
@@ -55,43 +53,40 @@
...
@@ -55,43 +53,40 @@
#include <boost/shared_ptr.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/weak_ptr.hpp>
#include <boost/weak_ptr.hpp>
namespace
ttl
{
namespace
ttl
class
TriangulationHelper
;
{
class
TRIANGULATION_HELPER
;
};
};
//--------------------------------------------------------------------------------------------------
/**
// The half-edge data structure
* The half-edge data structure
//--------------------------------------------------------------------------------------------------
*/
namespace
hed
namespace
hed
{
{
// Helper typedefs
// Helper typedefs
class
Node
;
class
NODE
;
class
Edge
;
class
EDGE
;
typedef
boost
::
shared_ptr
<
Node
>
NodePtr
;
typedef
boost
::
shared_ptr
<
NODE
>
NODE_PTR
;
typedef
boost
::
shared_ptr
<
Edge
>
EdgePtr
;
typedef
boost
::
shared_ptr
<
EDGE
>
EDGE_PTR
;
typedef
boost
::
weak_ptr
<
Edge
>
EdgeWeakPtr
;
typedef
boost
::
weak_ptr
<
EDGE
>
EDGE_WEAK_PTR
;
typedef
std
::
vector
<
NodePtr
>
NodesContainer
;
typedef
std
::
vector
<
NODE_PTR
>
NODES_CONTAINER
;
//------------------------------------------------------------------------------------------------
/**
// Node class for data structures
* \class NODE
//------------------------------------------------------------------------------------------------
* \brief \b Node class for data structures (Inherits from HandleId)
*
/** \class Node
* \note
* \brief \b Node class for data structures (Inherits from HandleId)
* - To enable node IDs, TTL_USE_NODE_ID must be defined.
*
* - To enable node flags, TTL_USE_NODE_FLAG must be defined.
* \note
* - TTL_USE_NODE_ID and TTL_USE_NODE_FLAG should only be enabled if this functionality is
* - To enable node IDs, TTL_USE_NODE_ID must be defined.
* required by the application, because they increase the memory usage for each Node object.
* - 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
class
NODE
* required by the application, because they increase the memory usage for each Node object.
{
*/
class
Node
{
protected
:
protected
:
#ifdef TTL_USE_NODE_FLAG
#ifdef TTL_USE_NODE_FLAG
/// TTL_USE_NODE_FLAG must be defined
/// TTL_USE_NODE_FLAG must be defined
bool
flag_
;
bool
m_flag
;
#endif
#endif
#ifdef TTL_USE_NODE_ID
#ifdef TTL_USE_NODE_ID
...
@@ -99,303 +94,378 @@ protected:
...
@@ -99,303 +94,378 @@ protected:
static
int
id_count
;
static
int
id_count
;
/// A unique id for each node (TTL_USE_NODE_ID must be defined)
/// A unique id for each node (TTL_USE_NODE_ID must be defined)
int
id_
;
int
m_id
;
#endif
#endif
int
x_
,
y_
;
/// Node coordinates
int
m_x
,
m_y
;
unsigned
int
refCount_
;
/// Reference count
unsigned
int
m_refCount
;
public
:
public
:
/// Constructor
/// Constructor
N
ode
(
int
x
=
0
,
int
y
=
0
)
:
N
ODE
(
int
aX
=
0
,
int
aY
=
0
)
:
#ifdef TTL_USE_NODE_FLAG
#ifdef TTL_USE_NODE_FLAG
flag_
(
false
),
m_flag
(
false
),
#endif
#endif
#ifdef TTL_USE_NODE_ID
#ifdef TTL_USE_NODE_ID
id_
(
id_count
++
),
m_id
(
id_count
++
),
#endif
#endif
x_
(
x
),
y_
(
y
),
refCount_
(
0
)
{}
m_x
(
aX
),
m_y
(
aY
),
m_refCount
(
0
)
{
}
/// Destructor
/// Destructor
~
N
ode
()
{}
~
N
ODE
()
{}
/// Returns the x-coordinate
/// Returns the x-coordinate
int
GetX
()
const
{
return
x_
;
}
int
GetX
()
const
{
return
m_x
;
}
/// Returns the y-coordinate
/// Returns the y-coordinate
int
GetY
()
const
{
return
y_
;
}
int
GetY
()
const
{
return
m_y
;
}
#ifdef TTL_USE_NODE_ID
#ifdef TTL_USE_NODE_ID
/// Returns the id (TTL_USE_NODE_ID must be defined)
/// Returns the id (TTL_USE_NODE_ID must be defined)
int
Id
()
const
{
return
id_
;
}
int
Id
()
const
{
return
m_id
;
}
#endif
#endif
#ifdef TTL_USE_NODE_FLAG
#ifdef TTL_USE_NODE_FLAG
/// Sets the flag (TTL_USE_NODE_FLAG must be defined)
/// 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)
/// Returns the flag (TTL_USE_NODE_FLAG must be defined)
const
bool
&
GetFlag
()
const
{
return
flag_
;
}
const
bool
&
GetFlag
()
const
{
return
m_flag
;
}
#endif
#endif
void
IncRefCount
()
{
refCount_
++
;
}
void
IncRefCount
()
void
DecRefCount
()
{
refCount_
--
;
}
{
unsigned
int
GetRefCount
()
const
{
return
refCount_
;
}
m_refCount
++
;
};
// End of class Node
}
void
DecRefCount
()
//------------------------------------------------------------------------------------------------
{
// Edge class in the half-edge data structure
m_refCount
--
;
//------------------------------------------------------------------------------------------------
}
/** \class Edge
unsigned
int
GetRefCount
()
const
* \brief \b %Edge class in the in the half-edge data structure.
{
*/
return
m_refCount
;
}
};
class
Edge
{
public
:
/**
* \class EDGE
* \brief \b %Edge class in the in the half-edge data structure.
*/
class
EDGE
{
public
:
/// Constructor
/// Constructor
Edge
()
:
weight_
(
0
),
isLeadingEdge_
(
false
)
{}
EDGE
()
:
m_weight
(
0
),
m_isLeadingEdge
(
false
)
{
}
/// Destructor
/// Destructor
virtual
~
Edge
()
{}
virtual
~
EDGE
()
{
}
/// Sets the source node
/// 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
/// 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
/// 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
/// 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
/// Checks if an edge is a leading edge
bool
isLeadingEdge
()
const
{
return
isLeadingEdge_
;
}
bool
IsLeadingEdge
()
const
{
return
m_isLeadingEdge
;
}
/// Returns the twin edge
/// 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
/// Returns the next edge in face
const
EdgePtr
&
getNextEdgeInFace
()
const
{
return
nextEdgeInFace_
;
}
const
EDGE_PTR
&
GetNextEdgeInFace
()
const
{
return
m_nextEdgeInFace
;
}
/// Retuns the source node
/// Retuns the source node
const
NodePtr
&
getSourceNode
()
const
{
return
sourceNode_
;
}
const
NODE_PTR
&
GetSourceNode
()
const
{
return
m_sourceNode
;
}
/// Returns the target node
/// Returns the target node
virtual
const
NodePtr
&
getTargetNode
()
const
{
return
nextEdgeInFace_
->
getSourceNode
();
}
virtual
const
NODE_PTR
&
GetTargetNode
()
const
{
return
m_nextEdgeInFace
->
GetSourceNode
();
}
void
setWeight
(
unsigned
int
weight
)
{
weight_
=
weight
;
}
void
SetWeight
(
unsigned
int
weight
)
{
m_weight
=
weight
;
}
unsigned
int
getWeight
()
const
{
return
weight_
;
}
unsigned
int
GetWeight
()
const
{
return
m_weight
;
}
void
c
lear
()
void
C
lear
()
{
{
sourceNode_
.
reset
();
m_sourceNode
.
reset
();
nextEdgeInFace_
.
reset
();
m_nextEdgeInFace
.
reset
();
if
(
!
twinEdge_
.
expired
()
)
if
(
!
m_twinEdge
.
expired
()
)
{
{
twinEdge_
.
lock
()
->
c
learTwinEdge
();
m_twinEdge
.
lock
()
->
C
learTwinEdge
();
twinEdge_
.
reset
();
m_twinEdge
.
reset
();
}
}
}
}
protected
:
protected
:
N
odePtr
sourceNode_
;
N
ODE_PTR
m_sourceNode
;
E
dgeWeakPtr
twinEdge_
;
E
DGE_WEAK_PTR
m_twinEdge
;
E
dgePtr
nextEdgeInFace_
;
E
DGE_PTR
m_nextEdgeInFace
;
unsigned
int
weight_
;
unsigned
int
m_weight
;
bool
isLeadingEdge_
;
bool
m_isLeadingEdge
;
};
// End of class Edge
};
/** \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
class
EDGE_MST
:
public
EDGE
{
{
private
:
private
:
N
odePtr
target_
;
N
ODE_PTR
m_target
;
public
:
public
:
EdgeMST
(
const
NodePtr
&
source
,
const
NodePtr
&
target
,
unsigned
int
weight
=
0
)
:
EDGE_MST
(
const
NODE_PTR
&
aSource
,
const
NODE_PTR
&
aTarget
,
unsigned
int
aWeight
=
0
)
:
target_
(
target
)
m_target
(
aTarget
)
{
sourceNode_
=
source
;
weight_
=
weight
;
}
{
m_sourceNode
=
aSource
;
m_weight
=
aWeight
;
}
E
dgeMST
(
const
Edge
&
edge
)
E
DGE_MST
(
const
EDGE
&
edge
)
{
{
sourceNode_
=
edge
.
g
etSourceNode
();
m_sourceNode
=
edge
.
G
etSourceNode
();
target_
=
edge
.
g
etTargetNode
();
m_target
=
edge
.
G
etTargetNode
();
weight_
=
edge
.
g
etWeight
();
m_weight
=
edge
.
G
etWeight
();
}
}
~
EdgeMST
()
{};
~
EDGE_MST
()
{
}
/// @copydoc Edge::setSourceNode()
/// @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)
//------------------------------------------------------------------------------------------------
// Triangulation class in the half-edge data structure
//------------------------------------------------------------------------------------------------
/** \class Triangulation
* \brief \b %Triangulation class for the half-edge data structure with adaption to TTL.
*/
class
Triangulation
{
class
DART
;
// Forward declaration (class in this namespace)
protected
:
/**
std
::
list
<
EdgePtr
>
leadingEdges_
;
// one half-edge for each arc
* \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
;
ttl
::
T
riangulationHelper
*
helper
;
ttl
::
T
RIANGULATION_HELPER
*
m_
helper
;
void
addLeadingEdge
(
EdgePtr
&
edge
)
{
void
addLeadingEdge
(
EDGE_PTR
&
aEdge
)
edge
->
setAsLeadingEdge
();
{
leadingEdges_
.
push_front
(
edge
);
aEdge
->
SetAsLeadingEdge
();
m_leadingEdges
.
push_front
(
aEdge
);
}
}
bool
removeLeadingEdgeFromList
(
EdgePtr
&
leadingEdge
);
bool
removeLeadingEdgeFromList
(
EDGE_PTR
&
aLeadingEdge
);
void
cleanAll
();
void
cleanAll
();
/** Swaps the edge associated with \e dart in the actual data structure.
/** Swaps the edge associated with \e dart in the actual data structure.
*
*
* <center>
* <center>
* \image html swapEdge.gif
* \image html swapEdge.gif
* </center>
* </center>
*
*
* \param dart
* \param aDart
* Some of the functions require a dart as output.
* Some of the functions require a dart as output.
* If this is required by the actual function, the dart should be delivered
* 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)
* back in a position as seen if it was glued to the edge when swapping (rotating)
* the edge CCW; see the figure.
* the edge CCW; see the figure.
*
*
* \note
* \note
* - If the edge is \e constrained, or if it should not be swapped for
* - 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 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
* - Some functions in TTL require that \c swapEdge is implemented such that
* darts outside the quadrilateral are not affected by the swap.
* darts outside the quadrilateral are not affected by the swap.
*/
*/
void
swapEdge
(
Dart
&
dart
);
void
swapEdge
(
DART
&
aDart
);
/** Splits the triangle associated with \e dart in the actual data structure into
/**
* three new triangles joining at \e 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>
* </center>
* \image html splitTriangle.gif
*
* </center>
* \param dart
*
* Output: A CCW dart incident with the new node; see the figure.
* \param aDart
*/
* Output: A CCW dart incident with the new node; see the figure.
void
splitTriangle
(
Dart
&
dart
,
const
NodePtr
&
point
);
*/
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.
* The reverse operation of TTLtraits::splitTriangle.
*
* This function is only required for functions that involve
* <center>
* removal of interior nodes; see for example TrinagulationHelper::RemoveInteriorNode.
* \image html reverse_splitTriangle.gif
*
* </center>
* <center>
*/
* \image html reverse_splitTriangle.gif
void
reverse_splitTriangle
(
Dart
&
dart
);
* </center>
*/
/** Removes a triangle with an edge at the boundary of the triangulation
void
reverseSplitTriangle
(
DART
&
aDart
);
* 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
public
:
*/
void
removeBoundaryTriangle
(
DART
&
aDart
);
public
:
/// Default constructor
/// Default constructor
T
riangulation
();
T
RIANGULATION
();
/// Copy constructor
/// Copy constructor
T
riangulation
(
const
Triangulation
&
tr
);
T
RIANGULATION
(
const
TRIANGULATION
&
aTriangulation
);
/// Destructor
/// Destructor
~
T
riangulation
();
~
T
RIANGULATION
();
/// Creates a Delaunay triangulation from a set of points
/// Creates a Delaunay triangulation from a set of points
void
createDelaunay
(
NodesContainer
::
iterator
first
,
void
CreateDelaunay
(
NODES_CONTAINER
::
iterator
aFirst
,
NODES_CONTAINER
::
iterator
aLast
);
NodesContainer
::
iterator
last
);
/// Creates an initial Delaunay triangulation from two enclosing triangles
/// Creates an initial Delaunay triangulation from two enclosing triangles
// When using rectangular boundary - loop through all points and expand.
// When using rectangular boundary - loop through all points and expand.
// (Called from createDelaunay(...) when starting)
// (Called from createDelaunay(...) when starting)
EdgePtr
initTwoEnclosingTriangles
(
NodesContainer
::
iterator
first
,
EDGE_PTR
InitTwoEnclosingTriangles
(
NODES_CONTAINER
::
iterator
aFirst
,
NodesContainer
::
iterator
last
);
NODES_CONTAINER
::
iterator
aLast
);
// These two functions are required by TTL for Delaunay triangulation
// These two functions are required by TTL for Delaunay triangulation
/// Swaps the edge associated with diagonal
/// 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
/// 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
// Functions required by TTL for removing nodes in a Delaunay triangulation
/// Removes the boundary triangle associated with edge
/// 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
/// The reverse operation of removeTriangle
void
reverse_splitTriangle
(
EdgePtr
&
edge
);
void
ReverseSplitTriangle
(
EDGE_PTR
&
aEdge
);
/// Creates an arbitrary CCW dart
/// Creates an arbitrary CCW dart
D
art
c
reateDart
();
D
ART
C
reateDart
();
/// Returns a list of "triangles" (one leading half-edge for each triangle)
/// 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
/// 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)
/// Returns a list of half-edges (one half-edge for each arc)
std
::
list
<
E
dgePtr
>*
getEdges
(
bool
skip_boundary_edges
=
false
)
const
;
std
::
list
<
E
DGE_PTR
>*
GetEdges
(
bool
aSkipBoundaryEdges
=
false
)
const
;
#ifdef TTL_USE_NODE_FLAG
#ifdef TTL_USE_NODE_FLAG
/// Sets flag in all the nodes
/// 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.
/// Returns a list of nodes. This function requires TTL_USE_NODE_FLAG to be defined. \see Node.
std
::
list
<
N
odePtr
>*
g
etNodes
()
const
;
std
::
list
<
N
ODE_PTR
>*
G
etNodes
()
const
;
#endif
#endif
/// Swaps edges until the triangulation is Delaunay (constrained edges are not swapped)
/// Swaps edges until the triangulation is Delaunay (constrained edges are not swapped)
void
o
ptimizeDelaunay
();
void
O
ptimizeDelaunay
();
/// Checks if the triangulation is Delaunay
/// 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)
/// Returns an arbitrary interior node (as the source node of the returned edge)
E
dgePtr
g
etInteriorNode
()
const
;
E
DGE_PTR
G
etInteriorNode
()
const
;
E
dgePtr
getBoundaryEdgeInTriangle
(
const
EdgePtr
&
e
)
const
;
E
DGE_PTR
GetBoundaryEdgeInTriangle
(
const
EDGE_PTR
&
aEdge
)
const
;
/// Returns an arbitrary boundary edge
/// Returns an arbitrary boundary edge
E
dgePtr
g
etBoundaryEdge
()
const
;
E
DGE_PTR
G
etBoundaryEdge
()
const
;
/// Print edges for plotting with, e.g., gnuplot
/// Print edges for plotting with, e.g., gnuplot
void
printEdges
(
std
::
ofstream
&
os
)
const
;
void
PrintEdges
(
std
::
ofstream
&
aOutput
)
const
;
friend
class
ttl
::
TriangulationHelper
;
};
// End of class Triangulation
friend
class
ttl
::
TRIANGULATION_HELPER
;
};
};
// End of hed namespace
};
// End of hed namespace
#endif
#endif
include/ttl/ttl.h
View file @
6fa2f060
This source diff could not be displayed because it is too large. You can
view the blob
instead.
include/ttl/ttl_util.h
View file @
6fa2f060
...
@@ -3,11 +3,11 @@
...
@@ -3,11 +3,11 @@
* Applied Mathematics, Norway.
* Applied Mathematics, Norway.
*
*
* Contact information: E-mail: tor.dokken@sintef.no
* Contact information: E-mail: tor.dokken@sintef.no
* SINTEF ICT, De
partment of Applied Mathematics,
* SINTEF ICT, De
aPArtment of Applied Mathematics,
* P.O. Box 124 Blindern,
* P.O. Box 124 Blindern,
* 0314 Oslo, Norway.
* 0314 Oslo, Norway.
*
*
* This file is
pa
rt of TTL.
* This file is
aPA
rt of TTL.
*
*
* TTL is free software: you can redistribute it and/or modify
* TTL is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* it under the terms of the GNU Affero General Public License as
...
@@ -16,7 +16,7 @@
...
@@ -16,7 +16,7 @@
*
*
* TTL is distributed in the hope that it will be useful,
* TTL is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* 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.
* GNU Affero General Public License for more details.
*
*
* You should have received a copy of the GNU Affero General Public
* You should have received a copy of the GNU Affero General Public
...
@@ -40,28 +40,22 @@
...
@@ -40,28 +40,22 @@
#ifndef _TTL_UTIL_H_
#ifndef _TTL_UTIL_H_
#define _TTL_UTIL_H_
#define _TTL_UTIL_H_
#include <vector>
#include <vector>
#include <algorithm>
#include <algorithm>
#ifdef _MSC_VER
#ifdef _MSC_VER
# if _MSC_VER < 1300
# if _MSC_VER < 1300
# include <minmax.h>
# include <minmax.h>
# endif
# endif
#endif
#endif
//using namespace std;
/** \brief Utilities
/** \brief Utilities
*
*
* This name s
pa
ce contains utility functions for TTL.\n
* This name s
aPA
ce contains utility functions for TTL.\n
*
*
* Point and vector algebra such as scalar product and cross product
* Point and vector algebra such as scalar product and cross product
* between vectors are implemented here.
* between vectors are implemented here.
* These functions are required by functions in the \ref ttl names
pa
ce,
* These functions are required by functions in the \ref ttl names
aPA
ce,
* where they are assumed to be present in the \ref hed::TTLtraits "TTLtraits" class.
* 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.
* Thus, the user can call these functions from the traits class.
* For efficiency reasons, the user may consider implementing these
* For efficiency reasons, the user may consider implementing these
...
@@ -77,67 +71,59 @@
...
@@ -77,67 +71,59 @@
* ttl and \ref api
* ttl and \ref api
*
*
* \author
* \author
* Øyvind Hjelle, oyvindhj@ifi.uio.no
*
�
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
// ------------------------------ Computational Geometry Group ----------------------------------
* aDX1*aDY2 - aDY1*aDX2
//------------------------------------------------------------------------------------------------
* \endcode
*/
/** @name Computational geometry */
template
<
class
REAL_TYPE
>
//@{
REAL_TYPE
CrossProduct2D
(
REAL_TYPE
aDX1
,
REAL_TYPE
aDY1
,
REAL_TYPE
aDX2
,
REAL_TYPE
aDY2
)
{
//------------------------------------------------------------------------------------------------
return
aDX1
*
aDY2
-
aDY1
*
aDX2
;
/** Scalar product between two 2D vectors.
}
*
* \par Returns:
/** Returns a positive value if the 2D nodes/points \e aPA, \e aPB, and
* \code
* \e aPC occur in counterclockwise order; a negative value if they occur
* dx1*dx2 + dy1*dy2
* in clockwise order; and zero if they are collinear.
* \endcode
*
*/
* \note
template
<
class
real_type
>
* - This is a finite arithmetic fast version. It can be made more robust using
real_type
scalarProduct2d
(
real_type
dx1
,
real_type
dy1
,
real_type
dx2
,
real_type
dy2
)
{
* exact arithmetic schemes by Jonathan Richard Shewchuk. See
return
dx1
*
dx2
+
dy1
*
dy2
;
* 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
]
)
//------------------------------------------------------------------------------------------------
{
/** Cross product between two 2D vectors. (The z-component of the actual cross product.)
REAL_TYPE
acx
=
aPA
[
0
]
-
aPC
[
0
];
*
REAL_TYPE
bcx
=
aPB
[
0
]
-
aPC
[
0
];
* \par Returns:
REAL_TYPE
acy
=
aPA
[
1
]
-
aPC
[
1
];
* \code
REAL_TYPE
bcy
=
aPB
[
1
]
-
aPC
[
1
];
* 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
;
return
acx
*
bcy
-
acy
*
bcx
;
}
}
}
;
// End of ttl_util namespace scope
}
// namespace ttl_util
#endif // _TTL_UTIL_H_
#endif // _TTL_UTIL_H_
pcbnew/ratsnest_data.cpp
View file @
6fa2f060
...
@@ -68,7 +68,7 @@ bool sortDistance( const RN_NODE_PTR& aOrigin, const RN_NODE_PTR& aNode1,
...
@@ -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
)
bool
sortWeight
(
const
RN_EDGE_PTR
&
aEdge1
,
const
RN_EDGE_PTR
&
aEdge2
)
{
{
return
aEdge1
->
getWeight
()
<
aEdge2
->
g
etWeight
();
return
aEdge1
->
GetWeight
()
<
aEdge2
->
G
etWeight
();
}
}
...
@@ -92,7 +92,7 @@ bool operator!=( const RN_NODE_PTR& aFirst, const RN_NODE_PTR& aSecond )
...
@@ -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
)
bool
isEdgeConnectingNode
(
const
RN_EDGE_PTR
&
aEdge
,
const
RN_NODE_PTR
&
aNode
)
{
{
return
aEdge
->
getSourceNode
()
==
aNode
||
aEdge
->
g
etTargetNode
()
==
aNode
;
return
aEdge
->
GetSourceNode
()
==
aNode
||
aEdge
->
G
etTargetNode
()
==
aNode
;
}
}
...
@@ -125,8 +125,8 @@ std::vector<RN_EDGE_PTR>* kruskalMST( RN_LINKS::RN_EDGE_LIST& aEdges,
...
@@ -125,8 +125,8 @@ std::vector<RN_EDGE_PTR>* kruskalMST( RN_LINKS::RN_EDGE_LIST& aEdges,
{
{
RN_EDGE_PTR
&
dt
=
*
aEdges
.
begin
();
RN_EDGE_PTR
&
dt
=
*
aEdges
.
begin
();
int
srcTag
=
tags
[
dt
->
g
etSourceNode
()];
int
srcTag
=
tags
[
dt
->
G
etSourceNode
()];
int
trgTag
=
tags
[
dt
->
g
etTargetNode
()];
int
trgTag
=
tags
[
dt
->
G
etTargetNode
()];
// Check if by adding this edge we are going to join two different forests
// Check if by adding this edge we are going to join two different forests
if
(
srcTag
!=
trgTag
)
if
(
srcTag
!=
trgTag
)
...
@@ -139,7 +139,7 @@ std::vector<RN_EDGE_PTR>* kruskalMST( RN_LINKS::RN_EDGE_LIST& aEdges,
...
@@ -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
// Move nodes that were marked with old tag to the list marked with the new tag
cycles
[
srcTag
].
splice
(
cycles
[
srcTag
].
end
(),
cycles
[
trgTag
]
);
cycles
[
srcTag
].
splice
(
cycles
[
srcTag
].
end
(),
cycles
[
trgTag
]
);
if
(
dt
->
g
etWeight
()
==
0
)
// Skip already existing connections (weight == 0)
if
(
dt
->
G
etWeight
()
==
0
)
// Skip already existing connections (weight == 0)
{
{
mstExpectedSize
--
;
mstExpectedSize
--
;
}
}
...
@@ -148,9 +148,9 @@ std::vector<RN_EDGE_PTR>* kruskalMST( RN_LINKS::RN_EDGE_LIST& aEdges,
...
@@ -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,
// 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
// RN_EDGE_MST saves both source and target node and does not require any other
// edges to exist for getting source/target nodes
// edges to exist for getting source/target nodes
RN_EDGE_MST_PTR
newEdge
=
boost
::
make_shared
<
RN_EDGE_MST
>
(
dt
->
g
etSourceNode
(),
RN_EDGE_MST_PTR
newEdge
=
boost
::
make_shared
<
RN_EDGE_MST
>
(
dt
->
G
etSourceNode
(),
dt
->
g
etTargetNode
(),
dt
->
G
etTargetNode
(),
dt
->
g
etWeight
()
);
dt
->
G
etWeight
()
);
mst
->
push_back
(
newEdge
);
mst
->
push_back
(
newEdge
);
++
mstSize
;
++
mstSize
;
}
}
...
@@ -169,8 +169,8 @@ std::vector<RN_EDGE_PTR>* kruskalMST( RN_LINKS::RN_EDGE_LIST& aEdges,
...
@@ -169,8 +169,8 @@ std::vector<RN_EDGE_PTR>* kruskalMST( RN_LINKS::RN_EDGE_LIST& aEdges,
void
RN_NET
::
validateEdge
(
RN_EDGE_PTR
&
aEdge
)
void
RN_NET
::
validateEdge
(
RN_EDGE_PTR
&
aEdge
)
{
{
RN_NODE_PTR
source
=
aEdge
->
g
etSourceNode
();
RN_NODE_PTR
source
=
aEdge
->
G
etSourceNode
();
RN_NODE_PTR
target
=
aEdge
->
g
etTargetNode
();
RN_NODE_PTR
target
=
aEdge
->
G
etTargetNode
();
bool
valid
=
true
;
bool
valid
=
true
;
// If any of nodes belonging to the edge has the flag set,
// If any of nodes belonging to the edge has the flag set,
...
@@ -280,13 +280,13 @@ void RN_NET::compute()
...
@@ -280,13 +280,13 @@ void RN_NET::compute()
std
::
partial_sort_copy
(
boardNodes
.
begin
(),
boardNodes
.
end
(),
nodes
.
begin
(),
nodes
.
end
()
);
std
::
partial_sort_copy
(
boardNodes
.
begin
(),
boardNodes
.
end
(),
nodes
.
begin
(),
nodes
.
end
()
);
TRIANGULATOR
triangulator
;
TRIANGULATOR
triangulator
;
triangulator
.
c
reateDelaunay
(
nodes
.
begin
(),
nodes
.
end
()
);
triangulator
.
C
reateDelaunay
(
nodes
.
begin
(),
nodes
.
end
()
);
boost
::
scoped_ptr
<
RN_LINKS
::
RN_EDGE_LIST
>
triangEdges
(
triangulator
.
g
etEdges
()
);
boost
::
scoped_ptr
<
RN_LINKS
::
RN_EDGE_LIST
>
triangEdges
(
triangulator
.
G
etEdges
()
);
// Compute weight/distance for edges resulting from triangulation
// Compute weight/distance for edges resulting from triangulation
RN_LINKS
::
RN_EDGE_LIST
::
iterator
eit
,
eitEnd
;
RN_LINKS
::
RN_EDGE_LIST
::
iterator
eit
,
eitEnd
;
for
(
eit
=
(
*
triangEdges
).
begin
(),
eitEnd
=
(
*
triangEdges
).
end
();
eit
!=
eitEnd
;
++
eit
)
for
(
eit
=
(
*
triangEdges
).
begin
(),
eitEnd
=
(
*
triangEdges
).
end
();
eit
!=
eitEnd
;
++
eit
)
(
*
eit
)
->
setWeight
(
getDistance
(
(
*
eit
)
->
getSourceNode
(),
(
*
eit
)
->
g
etTargetNode
()
)
);
(
*
eit
)
->
SetWeight
(
getDistance
(
(
*
eit
)
->
GetSourceNode
(),
(
*
eit
)
->
G
etTargetNode
()
)
);
// Add the currently existing connections list to the results of triangulation
// Add the currently existing connections list to the results of triangulation
std
::
copy
(
boardEdges
.
begin
(),
boardEdges
.
end
(),
std
::
front_inserter
(
*
triangEdges
)
);
std
::
copy
(
boardEdges
.
begin
(),
boardEdges
.
end
(),
std
::
front_inserter
(
*
triangEdges
)
);
...
@@ -508,8 +508,8 @@ void RN_NET::RemoveItem( const TRACK* aTrack )
...
@@ -508,8 +508,8 @@ void RN_NET::RemoveItem( const TRACK* aTrack )
RN_EDGE_PTR
&
edge
=
m_tracks
.
at
(
aTrack
);
RN_EDGE_PTR
&
edge
=
m_tracks
.
at
(
aTrack
);
// Save nodes, so they can be cleared later
// Save nodes, so they can be cleared later
RN_NODE_PTR
aBegin
=
edge
->
g
etSourceNode
();
RN_NODE_PTR
aBegin
=
edge
->
G
etSourceNode
();
RN_NODE_PTR
aEnd
=
edge
->
g
etTargetNode
();
RN_NODE_PTR
aEnd
=
edge
->
G
etTargetNode
();
m_links
.
RemoveConnection
(
edge
);
m_links
.
RemoveConnection
(
edge
);
// Remove nodes associated with the edge. It is done in a safe way, there is a check
// 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
...
@@ -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
);
const
TRACK
*
track
=
static_cast
<
const
TRACK
*>
(
aItem
);
RN_EDGE_PTR
edge
=
m_tracks
.
at
(
track
);
RN_EDGE_PTR
edge
=
m_tracks
.
at
(
track
);
nodes
.
push_back
(
edge
->
g
etSourceNode
()
);
nodes
.
push_back
(
edge
->
G
etSourceNode
()
);
nodes
.
push_back
(
edge
->
g
etTargetNode
()
);
nodes
.
push_back
(
edge
->
G
etTargetNode
()
);
}
}
break
;
break
;
...
...
pcbnew/ratsnest_data.h
View file @
6fa2f060
...
@@ -50,13 +50,13 @@ class ZONE_CONTAINER;
...
@@ -50,13 +50,13 @@ class ZONE_CONTAINER;
class
CPolyPt
;
class
CPolyPt
;
// Preserve KiCad coding style policy
// Preserve KiCad coding style policy
typedef
hed
::
N
ode
RN_NODE
;
typedef
hed
::
N
ODE
RN_NODE
;
typedef
hed
::
N
odePtr
RN_NODE_PTR
;
typedef
hed
::
N
ODE_PTR
RN_NODE_PTR
;
typedef
hed
::
E
dge
RN_EDGE
;
typedef
hed
::
E
DGE
RN_EDGE
;
typedef
hed
::
E
dgePtr
RN_EDGE_PTR
;
typedef
hed
::
E
DGE_PTR
RN_EDGE_PTR
;
typedef
hed
::
E
dgeMST
RN_EDGE_MST
;
typedef
hed
::
E
DGE_MST
RN_EDGE_MST
;
typedef
boost
::
shared_ptr
<
hed
::
EdgeMST
>
RN_EDGE_MST_PT
R
;
typedef
hed
::
TRIANGULATION
TRIANGULATO
R
;
typedef
hed
::
Triangulation
TRIANGULATO
R
;
typedef
boost
::
shared_ptr
<
hed
::
EDGE_MST
>
RN_EDGE_MST_PT
R
;
bool
operator
==
(
const
RN_NODE_PTR
&
aFirst
,
const
RN_NODE_PTR
&
aSecond
);
bool
operator
==
(
const
RN_NODE_PTR
&
aFirst
,
const
RN_NODE_PTR
&
aSecond
);
bool
operator
!=
(
const
RN_NODE_PTR
&
aFirst
,
const
RN_NODE_PTR
&
aSecond
);
bool
operator
!=
(
const
RN_NODE_PTR
&
aFirst
,
const
RN_NODE_PTR
&
aSecond
);
...
...
pcbnew/ratsnest_viewitem.cpp
View file @
6fa2f060
...
@@ -97,8 +97,8 @@ void RATSNEST_VIEWITEM::ViewDraw( int aLayer, GAL* aGal ) const
...
@@ -97,8 +97,8 @@ void RATSNEST_VIEWITEM::ViewDraw( int aLayer, GAL* aGal ) const
BOOST_FOREACH
(
const
RN_EDGE_PTR
&
edge
,
*
edges
)
BOOST_FOREACH
(
const
RN_EDGE_PTR
&
edge
,
*
edges
)
{
{
const
RN_NODE_PTR
&
sourceNode
=
edge
->
g
etSourceNode
();
const
RN_NODE_PTR
&
sourceNode
=
edge
->
G
etSourceNode
();
const
RN_NODE_PTR
&
targetNode
=
edge
->
g
etTargetNode
();
const
RN_NODE_PTR
&
targetNode
=
edge
->
G
etTargetNode
();
VECTOR2D
source
(
sourceNode
->
GetX
(),
sourceNode
->
GetY
()
);
VECTOR2D
source
(
sourceNode
->
GetX
(),
sourceNode
->
GetY
()
);
VECTOR2D
target
(
targetNode
->
GetX
(),
targetNode
->
GetY
()
);
VECTOR2D
target
(
targetNode
->
GetX
(),
targetNode
->
GetY
()
);
...
...
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