Commit 0fb76bd7 authored by Benedikt Zoennchen's avatar Benedikt Zoennchen
Browse files

before refactoring of the mesh ds

parent d89bd0ef
package org.vadere.util.geometry.data; package org.vadere.util.geometry.mesh;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
......
package org.vadere.util.geometry.data; package org.vadere.util.geometry.mesh;
import org.apache.commons.lang3.tuple.Triple; import org.apache.commons.lang3.tuple.Triple;
import org.vadere.util.geometry.data.Face;
import org.vadere.util.geometry.shapes.IPoint; import org.vadere.util.geometry.shapes.IPoint;
import org.vadere.util.geometry.shapes.VPoint; import org.vadere.util.geometry.shapes.VPoint;
import org.vadere.util.geometry.shapes.VTriangle; import org.vadere.util.geometry.shapes.VTriangle;
......
package org.vadere.util.geometry.mesh;
import org.vadere.util.geometry.shapes.IPoint;
import java.util.Iterator;
/**
* @author Benedikt Zoennchen
*/
public class EdgeIterator<P extends IPoint, E extends IHalfEdge<P>, F extends IFace<P>> implements Iterator<E> {
private E currentHalfEdge;
private E edge;
private boolean started = false;
private IMesh<P, E, F> mesh;
public EdgeIterator(final IMesh<P, E, F> mesh, final F face){
this.edge = mesh.getEdge(face);
this.currentHalfEdge = edge;
this.mesh = mesh;
}
@Override
public boolean hasNext() {
return currentHalfEdge != null && (!started || !currentHalfEdge.equals(edge));
}
@Override
public E next() {
started = true;
E result = currentHalfEdge;
currentHalfEdge = mesh.getNext(currentHalfEdge);
return result;
}
}
\ No newline at end of file
package org.vadere.util.geometry.data; package org.vadere.util.geometry.mesh;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.vadere.util.geometry.GeometryUtils; import org.vadere.util.geometry.GeometryUtils;
import org.vadere.util.geometry.shapes.IPoint; import org.vadere.util.geometry.shapes.IPoint;
import org.vadere.util.geometry.shapes.MLine; 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.VPoint;
import org.vadere.util.geometry.shapes.VPolygon; import org.vadere.util.geometry.shapes.VPolygon;
import org.vadere.util.geometry.shapes.VTriangle; import org.vadere.util.geometry.shapes.VTriangle;
...@@ -12,7 +11,6 @@ import org.vadere.util.geometry.shapes.VTriangle; ...@@ -12,7 +11,6 @@ import org.vadere.util.geometry.shapes.VTriangle;
import java.awt.geom.Path2D; import java.awt.geom.Path2D;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.function.Function;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import java.util.stream.Stream; import java.util.stream.Stream;
import java.util.stream.StreamSupport; import java.util.stream.StreamSupport;
...@@ -20,24 +18,25 @@ import java.util.stream.StreamSupport; ...@@ -20,24 +18,25 @@ import java.util.stream.StreamSupport;
/** /**
* A Face is a region of a planar separation of the 2-D space, e.g. the region of a Polygon/Triangle and so on. * A Face is a region of a planar separation of the 2-D space, e.g. the region of a Polygon/Triangle and so on.
* *
* @author Benedikt Zoennchen
* @param <P> the type of the coordinates the face uses. * @param <P> the type of the coordinates the face uses.
*/ */
public class Face<P extends IPoint> implements Iterable<HalfEdge<P>> { public class Face<P extends IPoint> implements Iterable<PHalfEdge<P>>, IFace<P> {
public static <P extends IPoint> Face<P> of(P x, P y, P z) { public static <P extends IPoint> Face<P> of(P x, P y, P z) {
Face superTriangle = new Face(); Face superTriangle = new Face();
Face borderFace = new Face(true); Face borderFace = new Face(true);
HalfEdge xy = new HalfEdge(y, superTriangle); PHalfEdge xy = new PHalfEdge(y, superTriangle);
HalfEdge yz = new HalfEdge(z, superTriangle); PHalfEdge yz = new PHalfEdge(z, superTriangle);
HalfEdge zx = new HalfEdge(x, superTriangle); PHalfEdge zx = new PHalfEdge(x, superTriangle);
xy.setNext(yz); xy.setNext(yz);
yz.setNext(zx); yz.setNext(zx);
zx.setNext(xy); zx.setNext(xy);
HalfEdge yx = new HalfEdge(x, borderFace); PHalfEdge yx = new PHalfEdge(x, borderFace);
HalfEdge zy = new HalfEdge(y, borderFace); PHalfEdge zy = new PHalfEdge(y, borderFace);
HalfEdge xz = new HalfEdge(z, borderFace); PHalfEdge xz = new PHalfEdge(z, borderFace);
yx.setNext(xz); yx.setNext(xz);
xz.setNext(zy); xz.setNext(zy);
...@@ -60,7 +59,7 @@ public class Face<P extends IPoint> implements Iterable<HalfEdge<P>> { ...@@ -60,7 +59,7 @@ public class Face<P extends IPoint> implements Iterable<HalfEdge<P>> {
/** /**
* One of the half-edges bordering this face. * One of the half-edges bordering this face.
*/ */
private HalfEdge<P> edge; private PHalfEdge<P> edge;
private boolean border; private boolean border;
...@@ -72,11 +71,11 @@ public class Face<P extends IPoint> implements Iterable<HalfEdge<P>> { ...@@ -72,11 +71,11 @@ public class Face<P extends IPoint> implements Iterable<HalfEdge<P>> {
* *
* @param edge one of the half-edges bordering this face. * @param edge one of the half-edges bordering this face.
*/ */
public Face(@NotNull final HalfEdge<P> edge) { public Face(@NotNull final PHalfEdge<P> edge) {
this(edge, false); this(edge, false);
} }
public Face(@NotNull final HalfEdge<P> edge, boolean border) { public Face(@NotNull final PHalfEdge<P> edge, boolean border) {
this.border = border; this.border = border;
this.edge = edge; this.edge = edge;
} }
...@@ -111,11 +110,11 @@ public class Face<P extends IPoint> implements Iterable<HalfEdge<P>> { ...@@ -111,11 +110,11 @@ public class Face<P extends IPoint> implements Iterable<HalfEdge<P>> {
* *
* @param edge half-edge bordering this face * @param edge half-edge bordering this face
*/ */
public void setEdge(final HalfEdge<P> edge) { public void setEdge(final PHalfEdge<P> edge) {
this.edge = edge; this.edge = edge;
} }
public HalfEdge<P> getEdge() { public PHalfEdge<P> getEdge() {
return edge; return edge;
} }
...@@ -158,7 +157,7 @@ public class Face<P extends IPoint> implements Iterable<HalfEdge<P>> { ...@@ -158,7 +157,7 @@ public class Face<P extends IPoint> implements Iterable<HalfEdge<P>> {
public VPolygon toPolygon() { public VPolygon toPolygon() {
Path2D path2D = new Path2D.Double(); Path2D path2D = new Path2D.Double();
path2D.moveTo(edge.getPrevious().getEnd().getX(), edge.getPrevious().getEnd().getY()); path2D.moveTo(edge.getPrevious().getEnd().getX(), edge.getPrevious().getEnd().getY());
for(HalfEdge edge : this) { for(PHalfEdge edge : this) {
path2D.lineTo(edge.getEnd().getX(), edge.getEnd().getY()); path2D.lineTo(edge.getEnd().getX(), edge.getEnd().getY());
} }
return new VPolygon(path2D); return new VPolygon(path2D);
...@@ -171,7 +170,7 @@ public class Face<P extends IPoint> implements Iterable<HalfEdge<P>> { ...@@ -171,7 +170,7 @@ public class Face<P extends IPoint> implements Iterable<HalfEdge<P>> {
* @return a triangle which is defined by this face * @return a triangle which is defined by this face
*/ */
public VTriangle toTriangle() { public VTriangle toTriangle() {
List<HalfEdge<P>> edges = getEdges(); List<PHalfEdge<P>> edges = getEdges();
if(edges.size() != 3) { if(edges.size() != 3) {
throw new IllegalArgumentException("this face is not a feasible triangle."); throw new IllegalArgumentException("this face is not a feasible triangle.");
} }
...@@ -184,16 +183,16 @@ public class Face<P extends IPoint> implements Iterable<HalfEdge<P>> { ...@@ -184,16 +183,16 @@ public class Face<P extends IPoint> implements Iterable<HalfEdge<P>> {
} }
@Override @Override
public Iterator<HalfEdge<P>> iterator() { public Iterator<PHalfEdge<P>> iterator() {
return new HalfEdgeIterator(); return new HalfEdgeIterator();
} }
public Stream<HalfEdge<P>> stream () { public Stream<PHalfEdge<P>> stream () {
Iterable<HalfEdge<P>> iterable = () -> iterator(); Iterable<PHalfEdge<P>> iterable = () -> iterator();
return StreamSupport.stream(iterable.spliterator(), false); return StreamSupport.stream(iterable.spliterator(), false);
} }
public List<HalfEdge<P>> getEdges() { public List<PHalfEdge<P>> getEdges() {
return stream().collect(Collectors.toList()); return stream().collect(Collectors.toList());
} }
...@@ -205,8 +204,13 @@ public class Face<P extends IPoint> implements Iterable<HalfEdge<P>> { ...@@ -205,8 +204,13 @@ public class Face<P extends IPoint> implements Iterable<HalfEdge<P>> {
return stream().map(edge -> edge.getEnd()); return stream().map(edge -> edge.getEnd());
} }
private class HalfEdgeIterator implements Iterator<HalfEdge<P>> { @Override
private HalfEdge<P> currentHalfEdge; public String toString() {
return stream().map(edge -> edge.getEnd().toString()).reduce("", (s1, s2) -> s1 + " " + s2);
}
private class HalfEdgeIterator implements Iterator<PHalfEdge<P>> {
private PHalfEdge<P> currentHalfEdge;
private boolean started = false; private boolean started = false;
private HalfEdgeIterator(){ private HalfEdgeIterator(){
...@@ -215,13 +219,13 @@ public class Face<P extends IPoint> implements Iterable<HalfEdge<P>> { ...@@ -215,13 +219,13 @@ public class Face<P extends IPoint> implements Iterable<HalfEdge<P>> {
@Override @Override
public boolean hasNext() { public boolean hasNext() {
return !started || !currentHalfEdge.equals(edge); return currentHalfEdge != null && (!started || !currentHalfEdge.equals(edge));
} }
@Override @Override
public HalfEdge<P> next() { public PHalfEdge<P> next() {
started = true; started = true;
HalfEdge result = currentHalfEdge; PHalfEdge result = currentHalfEdge;
currentHalfEdge = currentHalfEdge.getNext(); currentHalfEdge = currentHalfEdge.getNext();
return result; return result;
} }
......
package org.vadere.util.geometry.data; package org.vadere.util.geometry.mesh;
import org.vadere.util.geometry.data.Face;
import org.vadere.util.geometry.data.HalfEdge;
import org.vadere.util.geometry.shapes.IPoint; import org.vadere.util.geometry.shapes.IPoint;
import java.util.HashSet; import java.util.HashSet;
...@@ -48,7 +46,7 @@ public class FaceIterator<P extends IPoint> implements Iterator<Face<P>> { ...@@ -48,7 +46,7 @@ public class FaceIterator<P extends IPoint> implements Iterator<Face<P>> {
Face<P> nextFace = facesToVisit.removeFirst(); Face<P> nextFace = facesToVisit.removeFirst();
visitedFaces.add(nextFace); visitedFaces.add(nextFace);
for(HalfEdge<P> he : nextFace) { for(PHalfEdge<P> he : nextFace) {
Face<P> twinFace = he.getTwin().getFace(); Face<P> twinFace = he.getTwin().getFace();
if(twinFace.isBorder() || twinFace.isDestroyed() || !facePredicate.test(twinFace)) { if(twinFace.isBorder() || twinFace.isDestroyed() || !facePredicate.test(twinFace)) {
......
package org.vadere.util.geometry.mesh;
import org.vadere.util.geometry.shapes.IPoint;
import org.vadere.util.geometry.shapes.VPolygon;
import java.awt.geom.Path2D;
/**
* @author Benedikt Zoennchen
* @param <P>
*/
public interface IFace<P extends IPoint> {
}
package org.vadere.util.geometry.mesh;
import org.vadere.util.geometry.shapes.IPoint;
public interface IHalfEdge<P extends IPoint> {}
package org.vadere.util.geometry.mesh;
import org.apache.commons.collections.IteratorUtils;
import org.jetbrains.annotations.NotNull;
import org.vadere.util.geometry.shapes.IPoint;
import org.vadere.util.geometry.shapes.VPoint;
import org.vadere.util.geometry.shapes.VPolygon;
import java.awt.geom.Path2D;
import java.util.Iterator;
import java.util.List;
import java.util.Optional;
/**
* @author Benedikt Zoennchen
* @param <P>
*/
public interface IMesh<P extends IPoint, E extends IHalfEdge<P>, F extends IFace<P>> extends Iterable<F> {
E getNext(@NotNull E halfEdge);
E getPrev(@NotNull E halfEdge);
E getTwin(@NotNull E halfEdge);
F getFace(@NotNull E halfEdge);
E getEdge(@NotNull P vertex);
E getEdge(@NotNull F face);
P getVertex(@NotNull E halfEdge);
default F getTwinFace(@NotNull E halfEdge) {
return getFace(getTwin(halfEdge));
}
boolean isBoundary(@NotNull F face);
boolean isBoundary(@NotNull E halfEdge);
boolean isDestroyed(@NotNull F face);
void setTwin(@NotNull E halfEdge, @NotNull E twin);
void setNext(@NotNull E halfEdge, @NotNull E next);
void setPrev(@NotNull E halfEdge, @NotNull E prev);
void setFace(@NotNull E halfEdge, @NotNull F face);
void setEdge(@NotNull F face, @NotNull E edge);
void setEdge(@NotNull P vertex, @NotNull E edge);
void setVertex(@NotNull E halfEdge, @NotNull P vertex);
List<E> getEdges(@NotNull P vertex);
default List<E> getEdges(@NotNull F face) {
return IteratorUtils.toList(new EdgeIterator(this, face));
}
default List<F> getFaces(@NotNull E edge) { return IteratorUtils.toList(new NeighbourFaceIterator(this, edge)); }
default List<E> getNeighbours(@NotNull E edge) { return IteratorUtils.toList(new NeighbourIterator(this, edge)); }
default Iterable<E> getNeighbourIt(E edge) {
return () -> new NeighbourIterator(this, edge);
}
default Iterable<E> getEdgeIt(F face) {
return () -> new EdgeIterator(this, face);
}
default Iterable<F> getIncidentFacesIt(@NotNull E edge) { return () -> new NeighbourFaceIterator<>(this, edge); }
E createEdge(@NotNull P vertex);
E createEdge(@NotNull P vertex, @NotNull F face);
F createFace();
void destroyFace(@NotNull F face);
void destroyEdge(@NotNull E edge);
List<F> getFaces();
@Override
default Iterator<F> iterator() {
return getFaces().iterator();
}
default VPolygon toPolygon(F face) {
Path2D path2D = new Path2D.Double();
E edge = getEdge(face);
E prev = getPrev(edge);
path2D.moveTo(getVertex(prev).getX(), getVertex(prev).getY());
path2D.lineTo(getVertex(edge).getX(), getVertex(edge).getY());
while (!edge.equals(prev)) {
edge = getNext(edge);
P p = getVertex(edge);
path2D.lineTo(p.getX(), p.getY());
}
return new VPolygon(path2D);
}
default Optional<F> locate(final double x, final double y) {
for(F face : getFaces()) {
VPolygon polygon = toPolygon(face);
if(polygon.contains(new VPoint(x, y))) {
return Optional.of(face);
}
}
return Optional.empty();
}
}
package org.vadere.util.geometry.mesh;
import org.vadere.util.geometry.shapes.IPoint;
import org.vadere.util.geometry.shapes.VPoint;
import org.vadere.util.geometry.shapes.VPolygon;
import java.util.HashSet;
import java.util.List;
import java.util.Optional;
import java.util.Set;
/**
* @author Benedikt Zoennchen
*/
public interface IPolyConnectivity<P extends IPoint, E extends IHalfEdge<P>, F extends IFace<P>> extends Iterable<F>{
IMesh<P, E, F> getMesh();
default boolean isBoundary(E halfEdge) {
IMesh<P, E, F> mesh = getMesh();
return mesh.isBoundary(halfEdge) || mesh.isBoundary(mesh.getTwin(halfEdge));
}
default Optional<F> locate(final double x, final double y) {
for(F face : getMesh().getFaces()) {
VPolygon polygon = getMesh().toPolygon(face);
if(polygon.contains(new VPoint(x, y))) {
return Optional.of(face);
}
}
return Optional.empty();
}
default Optional<F> locate(final P point) {
return locate(point.getX(), point.getY());
}
default boolean isBoundary(F face) {
return getMesh().getEdges(face).stream().anyMatch(edge -> isBoundary(edge));
}
default void adjustVertex(P vertex){
List<E> edges = getMesh().getEdges(vertex);
edges.stream().filter(edge -> isBoundary(edge)).findAny().ifPresent(edge -> getMesh().setEdge(vertex, edge));
}
default Optional<E> findEdge(P begin, P end) {
IMesh<P, E, F> mesh = getMesh();
return mesh.getNeighbours(mesh.getEdge(begin)).stream().filter(edge -> mesh.getPrev(edge).equals(end)).map(edge -> mesh.getTwin(edge)).findAny();
}
default boolean isSimpleLink(E halfEdge) {
E edge = halfEdge;
E twin = getMesh().getTwin(halfEdge);
F twinFace = getMesh().getFace(twin);
E next = getMesh().getNext(edge);
while (!edge.equals(next)) {
if (twinFace.equals(getMesh().getTwinFace(next))) {
return false;
}
next = getMesh().getNext(next);
}
return true;
}
default boolean isSimpleConnected(F face) {
Set<F> faceSet = new HashSet<>();
E edge = getMesh().getEdge(face);
E next = getMesh().getNext(edge);
faceSet.add(getMesh().getTwinFace(edge));
while (!edge.equals(next)) {
if(faceSet.contains(getMesh().getTwinFace(next))) {
return false;
}
else {
faceSet.add(getMesh().getTwinFace(next));
}
next = getMesh().getNext(next);
}
return true;
}
default void split(F face, P vertex) {
E hend = getMesh().getEdge(face);
E hh = getMesh().getNext(hend);
E hold = getMesh().createEdge(vertex);
E twin = getMesh().createEdge(getMesh().getVertex(hend));
getMesh().setTwin(hold, twin);
getMesh().setNext(hend, hold);
getMesh().setFace(hold, face);
hold = getMesh().getTwin(hold);
while (!hh.equals(hend)) {
E hnext = getMesh().getNext(hh);
F newFace = getMesh().createFace();
getMesh().setEdge(newFace, hh);
E hnew = getMesh().createEdge(vertex);
getMesh().setNext(hnew, hold);
getMesh().setNext(hold, hh);
getMesh().setNext(hh, hnew);
getMesh().setFace(hnew, newFace);
getMesh().setFace(hold, newFace);
getMesh().setFace(hh, newFace);
E hnewTwin = getMesh().createEdge(getMesh().getVertex(hh));
getMesh().setTwin(hnew, hnewTwin);
hold = hnewTwin;
hh = hnext;
}
getMesh().setNext(hold, hend);
getMesh().setNext(getMesh().getNext(hend), hold);
getMesh().setFace(hold, face);
}
}
package org.vadere.util.geometry.mesh;
import org.apache.commons.lang3.tuple.Pair;
import org.apache.commons.lang3.tuple.Triple;
import org.jetbrains.annotations.NotNull;
import org.vadere.util.geometry.shapes.IPoint;
import java.util.ArrayList;
import java.util.List;
/**
* @author Benedikt Zoennchen