public final class HalfEdgeUtils extends Object
Modifier and Type | Method and Description |
---|---|
static <V extends Vertex<V,E,F>,E extends Edge<V,E,F>,F extends Face<V,E,F>> |
addCube(HalfEdgeDataStructure<V,E,F> heds) |
static <V extends Vertex<V,E,F>,E extends Edge<V,E,F>,F extends Face<V,E,F>> |
addDodecahedron(HalfEdgeDataStructure<V,E,F> heds) |
static <V extends Vertex<V,E,F>,E extends Edge<V,E,F>,F extends Face<V,E,F>> |
addIcosahedron(HalfEdgeDataStructure<V,E,F> heds) |
static <V extends Vertex<V,E,F>,E extends Edge<V,E,F>,F extends Face<V,E,F>> |
addNGon(HalfEdgeDataStructure<V,E,F> heds,
int n)
Add a new n-gon.
|
static <V extends Vertex<V,E,F>,E extends Edge<V,E,F>,F extends Face<V,E,F>> |
addOctahedron(HalfEdgeDataStructure<V,E,F> heds) |
static <V extends Vertex<V,E,F>,E extends Edge<V,E,F>,F extends Face<V,E,F>> |
addTetrahedron(HalfEdgeDataStructure<V,E,F> heds) |
static <E extends Edge<?,E,?>> |
boundaryComponents(HalfEdgeDataStructure<?,E,?> hds)
Returns a list containing lists for all boundary components
of
hds with left face equal to null. |
static <E extends Edge<?,E,F>,F extends Face<?,E,F>> |
boundaryEdges(E e0)
Return a list of edges which belong to the boundary component
of e0
|
static <E extends Edge<?,E,F>,F extends Face<?,E,F>> |
boundaryEdges(F face)
Return a list of the edges which have a given face as left face.
|
static <E extends Edge<?,E,?>> |
boundaryEdges(HalfEdgeDataStructure<?,E,?> heds)
Returns a collection containing all edges of
heds with left face equal to null. |
static <E extends Edge<?,E,F>,F extends Face<?,E,F>> |
boundaryFaces(HalfEdgeDataStructure<?,E,F> heds)
Returns a collection containing all faces of
heds with at least one boundary edge. |
static <V extends Vertex<V,E,F>,E extends Edge<V,E,F>,F extends Face<V,E,F>> |
boundaryVertices(F face)
Returns a list containing all vertices that are
target vertices of the boundary of the given face
|
static <V extends Vertex<V,E,?>,E extends Edge<V,E,?>> |
boundaryVertices(HalfEdgeDataStructure<V,E,?> surf)
Returns a collection of all boundary vertices of
surf . |
static <V extends Vertex<V,E,F>,E extends Edge<V,E,F>,F extends Face<V,E,F>> |
constructFaceByVertices(HalfEdgeDataStructure<V,E,F> heds,
Vertex<?,?,?>... v)
Construct a new face by giving its vertices in cyclic order.
|
static <V extends Vertex<V,E,F>,E extends Edge<V,E,F>,F extends Face<V,E,F>,HDSSRC extends HalfEdgeDataStructure<V,E,F>,VV extends Vertex<VV,EE,FF>,EE extends Edge<VV,EE,FF>,FF extends Face<VV,EE,FF>,HDSDST extends HalfEdgeDataStructure<VV,EE,FF>> |
copy(HDSSRC src,
HDSDST dst)
Inserts the nodes of src into dst
|
static <V extends Vertex<V,E,F>,E extends Edge<V,E,F>,F extends Face<V,E,F>> |
facesIncidentWithVertex(V vertex)
Return a list of faces that are incident with a given vertex.
|
static <V extends Vertex<V,E,F>,E extends Edge<V,E,F>,F extends Face<V,E,F>> |
fillAllHoles(HalfEdgeDataStructure<V,E,F> heds)
Fill all holes by adding faces.
|
static <V extends Vertex<V,E,F>,E extends Edge<V,E,F>,F extends Face<V,E,F>> |
fillHole(E edge)
Insert a new face into an edge cycle with no left face.
|
static <E extends Edge<?,E,F>,F extends Face<?,E,F>> |
findEdgeBetweenFaces(F leftFace,
F rightFace)
Find an edge with given left and right faces.
|
static <V extends Vertex<V,E,?>,E extends Edge<V,E,?>> |
findEdgeBetweenVertices(V startVertex,
V targetVertex)
Find an edge with given start and target vertices.
|
static <E extends Edge<?,E,F>,F extends Face<?,E,F>> |
findEdgesBetweenFaces(F leftFace,
F rightFace)
Finds all edges with given left and right faces.
|
static int |
getGenus(HalfEdgeDataStructure<?,?,?> hds)
Calculates the genus of the 2-manifold represented
by the given HalfedgeDataDtructure by evaluating
X = hds.numVertices() - hds.numEdges() / 2 + hds.numFaces()
r = number of boundary components
g = (2 - X - r) / 2
|
static <V extends Vertex<V,E,?>,E extends Edge<V,E,?>> |
incomingBoundaryEdge(V vertex)
For a boundary vertex, the incoming edge with getRightFace() == null
is returned.
|
static <E extends Edge<V,E,?>,V extends Vertex<V,E,?>> |
incomingEdges(V vertex)
Return a list of the edges which have a given vertex as target vertex.
|
static <E extends Edge<?,E,?>> |
isBoundaryEdge(E e)
Test if a given edge is on the boundary.
|
static <V extends Vertex<V,E,?>,E extends Edge<V,E,?>> |
isBoundaryVertex(V vertex)
Test if a given vertex is on the boundary.
|
static boolean |
isInteriorEdge(Edge<?,?,?> e)
Test if a given edge is an interior edge (that is, not on the boundary).
|
static <F extends Face<?,E,F>,E extends Edge<?,E,F>> |
isInteriorFace(F face)
Test if a given face is an inerior face (that is, not on the boundary).
|
static <V extends Vertex<V,E,F>,E extends Edge<V,E,F>,F extends Face<V,E,F>> |
isManifoldVertex(V v)
Returns true if the neighborhood of this vertex is homeomorphic
either to R2 or to a half-space
|
static boolean |
isValidSurface(HalfEdgeDataStructure<?,?,?> heds)
Test whether the half-edge data structure represents a valid surface.
|
static boolean |
isValidSurface(HalfEdgeDataStructure<?,?,?> heds,
boolean printReasonForFailureToSystemErr)
Test whether the half-edge data structure represents a valid surface and, optionally, give a reason if it fails the test.
|
static <E extends Edge<V,E,?>,V extends Vertex<V,E,?>> |
neighboringVertices(V vertex)
Return a list of those vertices that are connected to a given
vertex by an edge. |
static <E extends Edge<V,E,?>,V extends Vertex<V,E,?>> |
outgoingEdges(V vertex)
Return a list of the edges which have a given vertex as start vertex.
|
public static <V extends Vertex<V,E,F>,E extends Edge<V,E,F>,F extends Face<V,E,F>> E addCube(HalfEdgeDataStructure<V,E,F> heds)
public static <V extends Vertex<V,E,F>,E extends Edge<V,E,F>,F extends Face<V,E,F>> E addDodecahedron(HalfEdgeDataStructure<V,E,F> heds)
public static <V extends Vertex<V,E,F>,E extends Edge<V,E,F>,F extends Face<V,E,F>> E addIcosahedron(HalfEdgeDataStructure<V,E,F> heds)
public static <V extends Vertex<V,E,F>,E extends Edge<V,E,F>,F extends Face<V,E,F>> F addNGon(HalfEdgeDataStructure<V,E,F> heds, int n)
Increases the number of faces by 1, the number of edges by 2*n, and the number of vertices by n.
V
- the vertex typeE
- the edge typeF
- the face typeheds
- the half-edge data structuren
- the number of verticespublic static <V extends Vertex<V,E,F>,E extends Edge<V,E,F>,F extends Face<V,E,F>> E addOctahedron(HalfEdgeDataStructure<V,E,F> heds)
public static <V extends Vertex<V,E,F>,E extends Edge<V,E,F>,F extends Face<V,E,F>> E addTetrahedron(HalfEdgeDataStructure<V,E,F> heds)
public static <E extends Edge<?,E,?>> List<List<E>> boundaryComponents(HalfEdgeDataStructure<?,E,?> hds)
hds
with left face equal to null.E
- the edge typehds
- the surfaceboundaryEdges
public static <E extends Edge<?,E,F>,F extends Face<?,E,F>> List<E> boundaryEdges(E e0)
E
- F
- e0
- public static <E extends Edge<?,E,F>,F extends Face<?,E,F>> List<E> boundaryEdges(F face)
This method expects that if there is at least one such edge e
, then all such edges, and only those, can be reached by repeatedly
executing e = e.
getNextEdge()
, and that in the process
e
never becomes null
.
The returned list contains the boundary edges in the correct cyclic order.
E
- the edge typeF
- the face typeface
- the facepublic static <E extends Edge<?,E,?>> List<E> boundaryEdges(HalfEdgeDataStructure<?,E,?> heds)
heds
with left face equal to null.E
- the edge typeheds
- the surfacepublic static <E extends Edge<?,E,F>,F extends Face<?,E,F>> Collection<F> boundaryFaces(HalfEdgeDataStructure<?,E,F> heds)
heds
with at least one boundary edge.E
- the edge typeheds
- the surfacepublic static <V extends Vertex<V,E,F>,E extends Edge<V,E,F>,F extends Face<V,E,F>> List<V> boundaryVertices(F face)
V
- E
- F
- face
- the faceHalfEdgeUtils#boundaryEdges(Face)}
public static <V extends Vertex<V,E,?>,E extends Edge<V,E,?>> Collection<V> boundaryVertices(HalfEdgeDataStructure<V,E,?> surf)
surf
. Assumes that surf
represents a valid surface.V
- the vertex typeE
- the edge typesurf
- public static <V extends Vertex<V,E,F>,E extends Edge<V,E,F>,F extends Face<V,E,F>> E constructFaceByVertices(HalfEdgeDataStructure<V,E,F> heds, Vertex<?,?,?>... v) throws RuntimeException
This method assumes:
HalfEdgeDataStructure
heds
.heds
is a valid surface or empty. More precisely: If all vertices v
with
v.
getIncomingEdge()
== null
were removed from heds
, and after executing fillAllHoles(heds)
, heds
would be empty or a
valid surface.heds
. More precisely: If v0
and v1
are vertices of heds
(where v0 == v1
is allowed) then there is at most one Edge
with start vertex v0
and target vertex v1
.HalfEdgeDataStructure
without loops or double edges, which is again valid surface except for isolated vertices and missing faces. Failure of this method is not atomic: If it throws an exception, the half-edge data structure may be left in some intermediate state.
V
- the vertex typeE
- the edge typeF
- the face typeheds
- the half-edge data structurev
- the verticesRuntimeException
- in some cases when something goes wrong. Of course, this should not happen if the above preconditions are fulfilled.public static <V extends Vertex<V,E,F>,E extends Edge<V,E,F>,F extends Face<V,E,F>,HDSSRC extends HalfEdgeDataStructure<V,E,F>,VV extends Vertex<VV,EE,FF>,EE extends Edge<VV,EE,FF>,FF extends Face<VV,EE,FF>,HDSDST extends HalfEdgeDataStructure<VV,EE,FF>> int copy(HDSSRC src, HDSDST dst)
src
- dst
- public static <V extends Vertex<V,E,F>,E extends Edge<V,E,F>,F extends Face<V,E,F>> List<F> facesIncidentWithVertex(V vertex)
Uses incomingEdges(Vertex)
, so the preconditions explained there apply.
The returned list contains the incident faces in clockwise order. It does not contain null
,
even if the vertex is on the boundary.
V
- the vertex typeE
- the edge typeF
- the face typevertex
- the vertexpublic static <V extends Vertex<V,E,F>,E extends Edge<V,E,F>,F extends Face<V,E,F>> void fillAllHoles(HalfEdgeDataStructure<V,E,F> heds)
Simply calls fillHole(Edge)
on edges with no left face until all edges have a left face.
Hence, the preconditions described there apply.
heds
- public static <V extends Vertex<V,E,F>,E extends Edge<V,E,F>,F extends Face<V,E,F>> F fillHole(E edge) throws RuntimeException
An edge cycle is a cycle of edges obtained by repeatedly applying Edge.getNextEdge()
.
This method expects that one does not encounter null
when doing so, and that all edges in the cycle
have null
as left face.
V
- the vertex typeE
- the edge typeF
- the face typeedge
- an edge of the edge cycleRuntimeException
- if it is called with null
as parameter, of if Edge.getNextEdge()
returns null
for some edge in the edge cycle, or if Edge.getLeftFace()
is not null
for some
edge in the cycle.public static <E extends Edge<?,E,F>,F extends Face<?,E,F>> E findEdgeBetweenFaces(F leftFace, F rightFace)
Uses boundaryEdges(Face)
, so the preconditions explained there apply.
E
- the edge typeF
- the face typeleftFace
- the left face (must not be null)rightFace
- the right face (can be null)null
if no such edge exists.public static <V extends Vertex<V,E,?>,E extends Edge<V,E,?>> E findEdgeBetweenVertices(V startVertex, V targetVertex)
Uses incomingEdges(Vertex)
, so the preconditions explained there apply.
V
- the vertex typeE
- the edge typestartVertex
- the start vertextargetVertex
- the target vertexnull
if no such edge exists.public static <E extends Edge<?,E,F>,F extends Face<?,E,F>> List<E> findEdgesBetweenFaces(F leftFace, F rightFace)
Uses boundaryEdges(Face)
, so the preconditions explained there apply.
E
- the edge typeF
- the face typeleftFace
- the left face (must not be null)rightFace
- the right face (can be null)public static int getGenus(HalfEdgeDataStructure<?,?,?> hds)
hds
- a 2-manifoldpublic static <V extends Vertex<V,E,?>,E extends Edge<V,E,?>> E incomingBoundaryEdge(V vertex)
Uses incomingEdges(Vertex)
, so the preconditions explained there apply.
vertex
- public static <E extends Edge<V,E,?>,V extends Vertex<V,E,?>> List<E> incomingEdges(V vertex)
This method expects that if there is one such edge e
, then all such edges, and only those, can be reached by repeatedly
executing e = e.
getNextEdge()
.
getOppositeEdge()
,
and that in the process e
never becomes null
.
The returned list contains the incoming edges in clockwise order.
E
- the edge typeV
- the vertex typevertex
- the vertexpublic static <E extends Edge<?,E,?>> boolean isBoundaryEdge(E e)
e
- true
if either e.getLeftFace() == null or e.getRightFace() == null.public static <V extends Vertex<V,E,?>,E extends Edge<V,E,?>> boolean isBoundaryVertex(V vertex)
Uses incomingEdges(Vertex)
, so the preconditions explained there apply.
vertex
- true
if there is an incoming edge with null
as left face, otherwise false
.public static boolean isInteriorEdge(Edge<?,?,?> e)
e
- the edgee.getLeftFace() != null && e.getRightFace() != null
public static <F extends Face<?,E,F>,E extends Edge<?,E,F>> boolean isInteriorFace(F face)
Uses boundaryEdges(Face)
, so the preconditions explained there apply.
E
- the edge typeF
- the face typeface
- the facefalse
if there is a boundary edge with null
as right face, otherwise true
public static <V extends Vertex<V,E,F>,E extends Edge<V,E,F>,F extends Face<V,E,F>> boolean isManifoldVertex(V v)
v
- the vertexpublic static boolean isValidSurface(HalfEdgeDataStructure<?,?,?> heds)
e
in the edge list: e.getNextEdge()
, nor e.getPreviousEdge()
,
nor e.getOppositeEdge()
returns null
.e.getTargetVertex()
does not return null
.e.getLeftFace()
and e.getRightFace()
do not both return null
. getLeftFace()
returns the same face for e
and e.
getNextEdge()
.getTargetVertex()
returns the same vertex for e
and
e.
getNextEdge().
getOppositeEdge()
.f
in the face list: e
in the edge list that has f
as left face. That is, there are no isolated faces.e = e.
getNextEdge()
, you can reach all edges with f
as left face.v
in the vertex list:e
in the edge list that has v
as target vertex. That is, there are no isolated vertices.e = e.
getNextEdge().
getOppositeEdge()
,
you can reach all edges with v
as target vertex. e
with v
as target vertex, there is at most one for which e.getLeftFace()
returns null
.
true
if the half-edge data structure represents a valid surface, false
otherwisepublic static boolean isValidSurface(HalfEdgeDataStructure<?,?,?> heds, boolean printReasonForFailureToSystemErr)
false
, this method behaves exatly as isValidSurface(HalfEdgeDataStructure)
. If the parameter is true
,
and the half-edge data structure fails to represent a valid surface, the method outputs a brief explanation to System.err
.
This feature is intended for debugging.printReasonForFailureToSystemErr
- true
if you want output to System.err
.true
if the half-edge data structure represents a valid surface, false
otherwisepublic static <E extends Edge<V,E,?>,V extends Vertex<V,E,?>> List<V> neighboringVertices(V vertex)
vertex
by an edge.
The i
th element of in this list is simply
vertex.
getIncomingEdges(vertex)
.get(i).
getStartVertex()
.
Thus, the preconditions of incomingEdges(Vertex)
apply.
The list contains the neighboring vertices in clockwise order, and it may contain the same vertex multiple times.
(It may also contain null
s.)
E
- the edge typeV
- the vertex typevertex
- the list of neighboring vertices.