Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
vadere
vadere
Commits
69a6b798
Commit
69a6b798
authored
Jan 30, 2017
by
Benedikt Zoennchen
Browse files
refactoring of the triangulation code
parent
5bf617f9
Changes
19
Hide whitespace changes
Inline
Side-by-side
VadereUtils/src/org/vadere/util/delaunay/BowyerWatson.java
View file @
69a6b798
...
...
@@ -7,6 +7,7 @@ import org.vadere.util.geometry.data.DAG;
import
org.vadere.util.geometry.data.Face
;
import
org.vadere.util.geometry.data.HalfEdge
;
import
org.vadere.util.geometry.GeometryUtils
;
import
org.vadere.util.geometry.data.Triangulation
;
import
org.vadere.util.geometry.shapes.IPoint
;
import
org.vadere.util.geometry.shapes.VCircle
;
import
org.vadere.util.geometry.shapes.VLine
;
...
...
@@ -24,12 +25,13 @@ import java.util.List;
import
java.util.Random
;
import
java.util.Set
;
import
java.util.stream.Collectors
;
import
java.util.stream.Stream
;
import
javax.swing.*
;
public
class
BowyerWatson
<
P
extends
IPoint
>
{
public
class
BowyerWatson
<
P
extends
IPoint
>
implements
Triangulation
<
P
>
{
private
final
Collection
<
P
>
points
;
private
final
Set
<
P
>
points
;
private
final
PointConstructor
<
P
>
pointConstructor
;
private
final
TriangleConstructor
<
VPoint
>
triangleConstructor
;
private
P
p0
;
...
...
@@ -37,17 +39,17 @@ public class BowyerWatson<P extends IPoint> {
private
P
p2
;
private
DAG
<
DAGElement
<
P
>>
dag
;
private
final
HashMap
<
Face
<
P
>,
DAG
<
DAGElement
<
P
>>>
map
;
private
Set
<
DAG
<
DAGElement
<
P
>>>
triangles
;
private
int
count
;
public
BowyerWatson
(
final
Collection
<
P
>
points
,
final
Set
<
P
>
points
,
final
PointConstructor
<
P
>
pointConstructor
,
final
TriangleConstructor
<
VPoint
>
triangleConstructor
)
{
this
.
points
=
points
;
this
.
pointConstructor
=
pointConstructor
;
this
.
triangleConstructor
=
triangleConstructor
;
this
.
map
=
new
HashMap
<>();
this
.
triangles
=
new
HashSet
<>()
;
this
.
count
=
0
;
}
public
void
init
()
{
...
...
@@ -72,45 +74,86 @@ public class BowyerWatson<P extends IPoint> {
int
count
=
0
;
// 2. insert points
for
(
P
p
:
points
)
{
// find triangle containing p using the DAG.
Set
<
DAG
<
DAGElement
<
P
>>>
leafs
=
locatePoint
(
p
);
assert
leafs
.
size
()
==
2
||
leafs
.
size
()
==
1
;
insert
(
p
);
count
++;
// point is inside a triangle
if
(
leafs
.
size
()
==
1
)
{
split
(
p
,
leafs
.
stream
().
findAny
().
get
());
}
// point lies on an edge of 2 triangles
else
if
(
leafs
.
size
()
==
2
)
{
Iterator
<
DAG
<
DAGElement
<
P
>>>
it
=
leafs
.
iterator
();
splitBoth
(
p
,
it
.
next
(),
it
.
next
());
}
else
if
(
leafs
.
size
()
==
0
)
{
// problem due numerical calculation.
System
.
out
.
println
(
"numerical error!"
);
}
else
{
Set
<
DAG
<
DAGElement
<
P
>>>
leafs2
=
locatePoint
(
p
);
System
.
out
.
println
(
leafs2
+
" contains "
+
p
);
throw
new
IllegalArgumentException
(
"something is wrong here, this should never happen "
+
leafs
.
size
()
+
" / "
+
p
+
" / "
+
count
);
}
}
}
// 3. remove initial points
triangles
=
map
.
values
().
stream
().
filter
(
dagElement
->
{
@Override
public
Face
<
P
>
locate
(
P
point
)
{
return
locatePoint
(
point
).
stream
().
findAny
().
get
().
getElement
().
getFace
();
}
@Override
public
Set
<
Face
<
P
>>
getFaces
()
{
return
streamFaces
().
collect
(
Collectors
.
toSet
());
}
@Override
public
Stream
<
Face
<
P
>>
streamFaces
()
{
return
map
.
values
().
stream
()
.
filter
(
dagElement
->
{
Triple
<
P
,
P
,
P
>
triple
=
dagElement
.
getElement
().
getVertices
();
Set
<
P
>
pointset
=
new
HashSet
<
P
>();
Set
<
P
>
pointset
=
new
HashSet
<>();
pointset
.
add
(
triple
.
getLeft
());
pointset
.
add
(
triple
.
getMiddle
());
pointset
.
add
(
triple
.
getRight
());
return
!
pointset
.
contains
(
p0
)
&&
!
pointset
.
contains
(
p1
)
&&
!
pointset
.
contains
(
p2
);
}
).
collect
(
Collectors
.
toSet
());
})
.
map
(
dagElementDAG
->
dagElementDAG
.
getElement
().
getFace
());
}
@Override
public
void
insert
(
P
point
)
{
Set
<
DAG
<
DAGElement
<
P
>>>
leafs
=
locatePoint
(
point
);
assert
leafs
.
size
()
==
2
||
leafs
.
size
()
==
1
;
count
++;
// point is inside a triangle
if
(
leafs
.
size
()
==
1
)
{
split
(
point
,
leafs
.
stream
().
findAny
().
get
());
}
// point lies on an edge of 2 triangles
else
if
(
leafs
.
size
()
==
2
)
{
Iterator
<
DAG
<
DAGElement
<
P
>>>
it
=
leafs
.
iterator
();
splitBoth
(
point
,
it
.
next
(),
it
.
next
());
}
else
if
(
leafs
.
size
()
==
0
)
{
// problem due numerical calculation.
System
.
out
.
println
(
"numerical error!"
);
}
else
{
Set
<
DAG
<
DAGElement
<
P
>>>
leafs2
=
locatePoint
(
point
);
System
.
out
.
println
(
leafs2
+
" contains "
+
point
);
throw
new
IllegalArgumentException
(
"something is wrong here, this should never happen "
+
leafs
.
size
()
+
" / "
+
point
+
" / "
+
count
);
}
}
@Override
public
void
remove
(
P
point
)
{
throw
new
UnsupportedOperationException
(
"not jet implemented."
);
}
public
Collection
<
VTriangle
>
getTriangles
()
{
return
getFaces
().
stream
().
map
(
face
->
faceToTriangle
(
face
)).
collect
(
Collectors
.
toSet
());
}
/*public Collection<Triple<P, P, P>> getTrianglePoints() {
return triangles.stream().map(dagElement -> dagElement.getElement().getVertices()).collect(Collectors.toList());
}*/
public
Set
<
VLine
>
getEdges
()
{
return
getTriangles
().
stream
().
flatMap
(
triangle
->
triangle
.
getLineStream
()).
collect
(
Collectors
.
toSet
());
}
private
VTriangle
faceToTriangle
(
final
Face
<
P
>
face
)
{
List
<
P
>
points
=
face
.
getPoints
();
P
p1
=
points
.
get
(
0
);
P
p2
=
points
.
get
(
1
);
P
p3
=
points
.
get
(
2
);
return
new
VTriangle
(
new
VPoint
(
p1
.
getX
(),
p1
.
getY
()),
new
VPoint
(
p2
.
getX
(),
p2
.
getY
()),
new
VPoint
(
p3
.
getX
(),
p3
.
getY
()));
}
p
ublic
Set
<
DAG
<
DAGElement
<
P
>>>
locatePoint
(
final
P
point
)
{
p
rivate
Set
<
DAG
<
DAGElement
<
P
>>>
locatePoint
(
final
P
point
)
{
Set
<
DAG
<
DAGElement
<
P
>>>
leafs
=
new
HashSet
<>();
LinkedList
<
DAG
<
DAGElement
<
P
>>>
nodesToVisit
=
new
LinkedList
<>();
...
...
@@ -154,19 +197,9 @@ public class BowyerWatson<P extends IPoint> {
return
leafs
;
}
public
Collection
<
VTriangle
>
getTriangles
()
{
return
triangles
.
stream
().
map
(
dagElement
->
dagElement
.
getElement
().
getTriangle
()).
collect
(
Collectors
.
toList
());
}
public
Collection
<
Triple
<
P
,
P
,
P
>>
getTrianglePoints
()
{
return
triangles
.
stream
().
map
(
dagElement
->
dagElement
.
getElement
().
getVertices
()).
collect
(
Collectors
.
toList
());
}
public
Set
<
VLine
>
getEdges
()
{
return
triangles
.
stream
().
flatMap
(
dagElement
->
dagElement
.
getElement
().
getTriangle
().
getLineStream
()).
collect
(
Collectors
.
toSet
());
}
public
Pair
<
DAG
<
DAGElement
<
P
>>,
DAG
<
DAGElement
<
P
>>>
splitBoth
(
@NotNull
P
p
,
@NotNull
DAG
<
DAGElement
<
P
>>
xyzDag
,
@NotNull
DAG
<
DAGElement
<
P
>>
xwzDag
)
{
System
.
out
.
println
(
"split both"
);
VTriangle
xyzTriangle
=
xyzDag
.
getElement
().
getTriangle
();
Face
<
P
>
xyzFace
=
xyzDag
.
getElement
().
getFace
();
List
<
HalfEdge
<
P
>>
edges
=
xyzFace
.
getEdges
();
...
...
@@ -307,16 +340,16 @@ public class BowyerWatson<P extends IPoint> {
P
y
=
xy
.
getEnd
();
P
z
=
yz
.
getEnd
();
HalfEdge
<
P
>
yp
=
new
HalfEdge
<
P
>(
p
,
xyp
);
HalfEdge
<
P
>
py
=
new
HalfEdge
<
P
>(
y
,
yzp
);
HalfEdge
<
P
>
yp
=
new
HalfEdge
<>(
p
,
xyp
);
HalfEdge
<
P
>
py
=
new
HalfEdge
<>(
y
,
yzp
);
yp
.
setTwin
(
py
);
HalfEdge
<
P
>
xp
=
new
HalfEdge
<
P
>(
p
,
zxp
);
HalfEdge
<
P
>
px
=
new
HalfEdge
<
P
>(
x
,
xyp
);
HalfEdge
<
P
>
xp
=
new
HalfEdge
<>(
p
,
zxp
);
HalfEdge
<
P
>
px
=
new
HalfEdge
<>(
x
,
xyp
);
xp
.
setTwin
(
px
);
HalfEdge
<
P
>
zp
=
new
HalfEdge
<
P
>(
p
,
yzp
);
HalfEdge
<
P
>
pz
=
new
HalfEdge
<
P
>(
z
,
zxp
);
HalfEdge
<
P
>
zp
=
new
HalfEdge
<>(
p
,
yzp
);
HalfEdge
<
P
>
pz
=
new
HalfEdge
<>(
z
,
zxp
);
zp
.
setTwin
(
pz
);
zx
.
setNext
(
xp
);
...
...
@@ -434,6 +467,10 @@ public class BowyerWatson<P extends IPoint> {
zy
.
setFace
(
f1
);
yp
.
setFace
(
f1
);
if
(
y
.
equals
(
p
))
{
System
.
out
.
println
(
""
+
y
+
p
);
}
// update DAG
DAG
<
DAGElement
<
P
>>
yzpDag
=
new
DAG
<>(
new
DAGElement
(
f1
,
Triple
.
of
(
y
,
z
,
p
),
triangleConstructor
));
DAG
<
DAGElement
<
P
>>
xypDag
=
new
DAG
<>(
new
DAGElement
(
f2
,
Triple
.
of
(
x
,
y
,
p
),
triangleConstructor
));
...
...
@@ -452,30 +489,6 @@ public class BowyerWatson<P extends IPoint> {
}
}
/*public class DAGElement {
private Face<P> face;
private Triple<P, P, P> vertices;
private T triangle;
public DAGElement(final Face<P> face, final Triple<P, P, P> vertices) {
this.face = face;
this.vertices = vertices;
this.triangle = triangleConstructor.create(vertices.getLeft(), vertices.getMiddle(), vertices.getRight());
}
public Face<P> getFace() {
return face;
}
public T getTriangle() {
return triangle;
}
public Triple<P, P, P> getVertices() {
return vertices;
}
}*/
// TODO: the following code can be deleted, this is only for visual checks
public
static
void
main
(
String
[]
args
)
{
// TODO Auto-generated method stub
...
...
VadereUtils/src/org/vadere/util/delaunay/GuibasDAC.java
0 → 100644
View file @
69a6b798
package
org.vadere.util.delaunay
;
public
class
GuibasDAC
{
}
VadereUtils/src/org/vadere/util/geometry/DataPoint.java
View file @
69a6b798
...
...
@@ -2,10 +2,11 @@ package org.vadere.util.geometry;
import
java.util.Comparator
;
import
org.vadere.util.geometry.shapes.MPoint
;
import
org.vadere.util.geometry.shapes.VPoint
;
/**
* Point class representing one {@link
V
Point} in 2D space with an additional
* Point class representing one {@link
M
Point} in 2D space with an additional
* double-valued data store.
*
* An order can be applied with the isGreaterThan method.
...
...
@@ -13,30 +14,38 @@ import org.vadere.util.geometry.shapes.VPoint;
*/
public
class
DataPoint
extends
VPoint
implements
Comparable
<
VPoint
>
{
private
static
final
long
serialVersionUID
=
4631007066694627415L
;
private
static
Comparator
<
DataPoint
>
comparator
=
(
d1
,
d2
)
->
{
if
(
Math
.
abs
(
d1
.
data
-
d2
.
data
)
<
GeometryUtils
.
DOUBLE_EPS
)
{
return
0
;
// do not compare coordinates
}
else
if
(
d1
.
data
<
d2
.
data
)
{
return
-
1
;
}
return
1
;
};
private
static
Comparator
<
DataPoint
>
pointComparator
=
(
d1
,
d2
)
->
{
if
(
Math
.
abs
(
d1
.
data
-
d2
.
data
)
<
GeometryUtils
.
DOUBLE_EPS
)
{
// compare coordinates
return
d1
.
compareTo
(
d2
);
}
else
if
(
d1
.
data
<
d2
.
data
)
{
return
-
1
;
}
return
1
;
};
private
double
data
;
public
DataPoint
(
double
x
,
double
y
,
double
data
)
{
public
DataPoint
(
final
double
x
,
final
double
y
,
final
double
data
)
{
super
(
x
,
y
);
this
.
data
=
data
;
}
public
DataPoint
(
double
x
,
double
y
)
{
public
DataPoint
(
final
double
x
,
final
double
y
)
{
this
(
x
,
y
,
0
);
}
public
DataPoint
(
VPoint
p
,
double
data
)
{
this
(
p
.
x
,
p
.
y
,
data
);
}
public
DataPoint
(
VPoint
p1
)
{
super
(
p1
.
x
,
p1
.
y
);
if
(
p1
.
getClass
().
equals
(
DataPoint
.
class
))
{
this
.
data
=
((
DataPoint
)
p1
).
data
;
}
else
{
this
.
data
=
0.0
;
}
public
DataPoint
(
final
VPoint
p
,
final
double
data
)
{
this
(
p
.
getX
(),
p
.
getY
(),
data
);
}
/**
...
...
@@ -50,13 +59,13 @@ public class DataPoint extends VPoint implements Comparable<VPoint> {
* @param data
* the data to set
*/
public
void
setData
(
double
data
)
{
public
void
setData
(
final
double
data
)
{
this
.
data
=
data
;
}
@Override
public
String
toString
()
{
return
"("
+
this
.
x
+
","
+
this
.
y
+
"&"
+
this
.
data
+
")"
;
return
"("
+
this
.
getX
()
+
","
+
this
.
getY
()
+
"&"
+
this
.
data
+
")"
;
}
/**
...
...
@@ -64,19 +73,8 @@ public class DataPoint extends VPoint implements Comparable<VPoint> {
*
* @return
*/
public
static
Comparator
<
DataPoint
>
getComparator
()
{
return
new
Comparator
<
DataPoint
>()
{
@Override
public
int
compare
(
DataPoint
d1
,
DataPoint
d2
)
{
if
(
Math
.
abs
(
d1
.
data
-
d2
.
data
)
<
GeometryUtils
.
DOUBLE_EPS
)
{
return
0
;
// do not compare coordinates
}
else
if
(
d1
.
data
<
d2
.
data
)
{
return
-
1
;
}
return
1
;
}
};
public
static
Comparator
<?
super
DataPoint
>
getComparator
()
{
return
comparator
;
}
/**
...
...
@@ -86,35 +84,24 @@ public class DataPoint extends VPoint implements Comparable<VPoint> {
* @return
*/
public
static
Comparator
<?
super
DataPoint
>
getPointComparator
()
{
return
new
Comparator
<
DataPoint
>()
{
@Override
public
int
compare
(
DataPoint
d1
,
DataPoint
d2
)
{
if
(
Math
.
abs
(
d1
.
data
-
d2
.
data
)
<
GeometryUtils
.
DOUBLE_EPS
)
{
// compare coordinates
return
d1
.
compareTo
(
d2
);
}
else
if
(
d1
.
data
<
d2
.
data
)
{
return
-
1
;
}
return
1
;
}
};
return
pointComparator
;
}
/**
* Compares the points without using the data value of this point.
*/
@Override
public
int
compareTo
(
VPoint
other
)
{
if
(
Math
.
abs
(
this
.
x
-
other
.
x
)
<
GeometryUtils
.
DOUBLE_EPS
)
{
if
(
Math
.
abs
(
this
.
y
-
other
.
y
)
<
GeometryUtils
.
DOUBLE_EPS
)
{
public
int
compareTo
(
final
VPoint
other
)
{
if
(
Math
.
abs
(
getX
()
-
other
.
getX
()
)
<
GeometryUtils
.
DOUBLE_EPS
)
{
if
(
Math
.
abs
(
getY
()
-
other
.
getY
()
)
<
GeometryUtils
.
DOUBLE_EPS
)
{
return
0
;
}
else
{
if
(
this
.
y
>
other
.
y
)
{
if
(
getY
()
>
other
.
getY
()
)
{
return
1
;
}
}
}
else
{
if
(
this
.
x
>
other
.
x
)
{
if
(
this
.
getX
()
>
other
.
getX
()
)
{
return
1
;
}
else
{
return
-
1
;
...
...
VadereUtils/src/org/vadere/util/geometry/LineIterator.java
0 → 100644
View file @
69a6b798
package
org.vadere.util.geometry
;
import
org.vadere.util.geometry.shapes.IPoint
;
import
org.vadere.util.geometry.shapes.VLine
;
import
org.vadere.util.geometry.shapes.VPoint
;
import
java.awt.geom.Line2D
;
import
java.util.Iterator
;
public
class
LineIterator
implements
Iterator
<
IPoint
>
{
private
final
Line2D
.
Double
line
;
private
final
double
delta
;
private
VPoint
startPoint
;
private
VPoint
currentPoint
;
private
VPoint
endPoint
;
private
VPoint
deltaPoint
;
private
double
slope
;
private
double
lineLength
;
private
double
dx
;
private
double
dy
;
private
int
counter
;
private
int
numberOfSegments
;
public
LineIterator
(
final
Line2D
.
Double
line
,
final
double
delta
)
{
this
.
line
=
line
;
if
(
line
.
getX1
()
<
line
.
getX2
())
{
startPoint
=
new
VPoint
(
line
.
getX1
(),
line
.
getY1
());
endPoint
=
new
VPoint
(
line
.
getX2
(),
line
.
getY2
());
}
else
if
(
line
.
getX1
()
==
line
.
getX2
())
{
if
(
line
.
getY1
()
<
line
.
getY2
())
{
startPoint
=
new
VPoint
(
line
.
getX1
(),
line
.
getY1
());
endPoint
=
new
VPoint
(
line
.
getX2
(),
line
.
getY2
());
}
else
if
(
line
.
getY1
()
>
line
.
getY2
())
{
startPoint
=
new
VPoint
(
line
.
getX2
(),
line
.
getY2
());
endPoint
=
new
VPoint
(
line
.
getX1
(),
line
.
getY1
());
}
else
{
throw
new
IllegalArgumentException
(
line
+
" is not a feasible line."
);
}
}
else
{
startPoint
=
new
VPoint
(
line
.
getX2
(),
line
.
getY2
());
endPoint
=
new
VPoint
(
line
.
getX1
(),
line
.
getY1
());
}
lineLength
=
startPoint
.
distance
(
endPoint
);
numberOfSegments
=
(
int
)
Math
.
floor
(
lineLength
/
delta
)
-
3
;
this
.
delta
=
lineLength
/
numberOfSegments
;
if
(
line
.
getX1
()
==
line
.
getX2
())
{
dx
=
0
;
dy
=
this
.
delta
;
slope
=
0
;
}
if
(
line
.
getY1
()
==
line
.
getY2
())
{
dx
=
this
.
delta
;
dy
=
0
;
slope
=
0
;
}
if
(
line
.
getX1
()
!=
line
.
getX2
()
&&
line
.
getY1
()
!=
line
.
getY2
())
{
double
len
=
startPoint
.
distance
(
endPoint
);
slope
=
new
VLine
(
startPoint
,
endPoint
).
slope
();
dx
=
Math
.
sqrt
((
this
.
delta
*
this
.
delta
)
/
(
1
+
slope
*
slope
));
dy
=
dx
*
slope
;
}
deltaPoint
=
new
VPoint
(
dx
,
dy
);
currentPoint
=
null
;
}
@Override
public
boolean
hasNext
()
{
return
currentPoint
==
null
||
!
currentPoint
.
equals
(
endPoint
);
}
@Override
public
IPoint
next
()
{
// first point
if
(
currentPoint
==
null
)
{
counter
++;
currentPoint
=
startPoint
;
}
else
if
(
counter
<
numberOfSegments
)
{
counter
++;
currentPoint
=
currentPoint
.
add
(
deltaPoint
);
}
// last point
else
{
currentPoint
=
endPoint
;
}
if
(
slope
!=
0
)
{
// this is more accurate for slope != 0.
return
new
VPoint
(
currentPoint
.
getX
(),
startPoint
.
getY
()
+
slope
*
(
currentPoint
.
getX
()
-
startPoint
.
getX
()));
}
else
{
return
currentPoint
;
}
}
}
VadereUtils/src/org/vadere/util/geometry/data/Face.java
View file @
69a6b798
...
...
@@ -3,11 +3,16 @@ package org.vadere.util.geometry.data;
import
org.jetbrains.annotations.NotNull
;
import
org.vadere.util.geometry.GeometryUtils
;
import
org.vadere.util.geometry.shapes.IPoint
;
import
org.vadere.util.geometry.shapes.MLine
;
import
org.vadere.util.geometry.shapes.VLine
;
import
org.vadere.util.geometry.shapes.VPoint
;
import
org.vadere.util.geometry.shapes.VPolygon
;
import
org.vadere.util.geometry.shapes.VTriangle
;
import
java.awt.geom.Path2D
;
import
java.util.Iterator
;
import
java.util.List
;
import
java.util.function.Function
;
import
java.util.stream.Collectors
;
import
java.util.stream.Stream
;
import
java.util.stream.StreamSupport
;
...
...
@@ -19,6 +24,23 @@ import java.util.stream.StreamSupport;
*/
public
class
Face
<
P
extends
IPoint
>
implements
Iterable
<
HalfEdge
<
P
>>
{
public
static
<
P
extends
IPoint
>
Face
<
P
>
of
(
P
p1
,
P
p2
,
P
p3
)
{
Face
superTriangle
=
new
Face
();
HalfEdge
edge1
=
new
HalfEdge
(
p1
,
superTriangle
);
HalfEdge
edge2
=
new
HalfEdge
(
p2
,
superTriangle
);
HalfEdge
edge3
=
new
HalfEdge
(
p3
,
superTriangle
);
edge1
.
setNext
(
edge2
);
edge2
.
setNext
(
edge3
);
edge3
.
setNext
(
edge1
);
superTriangle
.
setEdge
(
edge1
);
return
superTriangle
;
}
public
static
<
P
extends
IPoint
>
Face
<
P
>
getBorder
(
Class
<
P
>
p
)
{
return
new
Face
<>();
}
/**
* One of the half-edges bordering this face.
*/
...
...
@@ -40,18 +62,6 @@ public class Face<P extends IPoint> implements Iterable<HalfEdge<P>> {
*/
public
Face
()
{}
public
static
<
P
extends
IPoint
>
Face
<
P
>
of
(
P
p1
,
P
p2
,
P
p3
)
{
Face
superTriangle
=
new
Face
();
HalfEdge
edge1
=
new
HalfEdge
(
p1
,
superTriangle
);
HalfEdge
edge2
=
new
HalfEdge
(
p2
,
superTriangle
);
HalfEdge
edge3
=
new
HalfEdge
(
p3
,
superTriangle
);
edge1
.
setNext
(
edge2
);
edge2
.
setNext
(
edge3
);
edge3
.
setNext
(
edge1
);
superTriangle
.
setEdge
(
edge1
);
return
superTriangle
;
}
/**
* Sets one of the half-edges bordering this face.
* @param edge half-edge bordering this face
...
...
@@ -60,6 +70,10 @@ public class Face<P extends IPoint> implements Iterable<HalfEdge<P>> {
this
.
edge
=
edge
;
}
public
HalfEdge
<
P
>
getEdge
()
{
return
edge
;
}
/**
* Computes the area of this face.
* @return the area of this face
...
...
@@ -89,6 +103,19 @@ public class Face<P extends IPoint> implements Iterable<HalfEdge<P>> {
return
new
VPolygon
(
path2D
);
}
public
VTriangle
toTriangle
()
{
List
<
HalfEdge
<
P
>>
edges
=
getEdges
();
if
(
edges
.
size
()
!=
3
)
{
throw
new
IllegalArgumentException
(
"this face is not a feasible triangle."
);