Commit 839bf075 authored by Benedikt Zoennchen's avatar Benedikt Zoennchen

update triangulation algorithm, implementation of the delaunay-hierarchy

parent 0ce6b028
...@@ -11,7 +11,7 @@ public class PHalfEdge<P extends IPoint> implements IHalfEdge<P> { ...@@ -11,7 +11,7 @@ public class PHalfEdge<P extends IPoint> implements IHalfEdge<P> {
/** /**
* point at the end of the half edge. * point at the end of the half edge.
*/ */
private P end; private PVertex<P> end;
/** /**
* next half-edge around the face. * next half-edge around the face.
...@@ -35,12 +35,12 @@ public class PHalfEdge<P extends IPoint> implements IHalfEdge<P> { ...@@ -35,12 +35,12 @@ public class PHalfEdge<P extends IPoint> implements IHalfEdge<P> {
private PFace<P> face; private PFace<P> face;
PHalfEdge(@NotNull final P end, @NotNull final PFace<P> face) { PHalfEdge(@NotNull final PVertex<P> end, @NotNull final PFace<P> face) {
this.end = end; this.end = end;
this.face = face; this.face = face;
} }
PHalfEdge(@NotNull final P end) { PHalfEdge(@NotNull final PVertex<P> end) {
this.end = end; this.end = end;
this.face = null; this.face = null;
} }
...@@ -53,7 +53,7 @@ public class PHalfEdge<P extends IPoint> implements IHalfEdge<P> { ...@@ -53,7 +53,7 @@ public class PHalfEdge<P extends IPoint> implements IHalfEdge<P> {
this.face = face; this.face = face;
} }
P getEnd() { PVertex<P> getEnd() {
return end; return end;
} }
...@@ -116,7 +116,7 @@ public class PHalfEdge<P extends IPoint> implements IHalfEdge<P> { ...@@ -116,7 +116,7 @@ public class PHalfEdge<P extends IPoint> implements IHalfEdge<P> {
} }
} }
void setEnd(P end) { void setEnd(PVertex<P> end) {
this.end = end; this.end = end;
} }
......
...@@ -11,17 +11,18 @@ import java.util.HashSet; ...@@ -11,17 +11,18 @@ import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import java.util.stream.Stream;
/** /**
* @author Benedikt Zoennchen * @author Benedikt Zoennchen
*/ */
public class PMesh<P extends IPoint> implements IMesh<P, PHalfEdge<P>, PFace<P>> { public class PMesh<P extends IPoint> implements IMesh<P, PVertex<P>, PHalfEdge<P>, PFace<P>> {
private List<PFace<P>> faces; private List<PFace<P>> faces;
private PFace<P> boundary; private PFace<P> boundary;
private List<PHalfEdge<P>> edges; private List<PHalfEdge<P>> edges;
private IPointConstructor<P> pointConstructor; private IPointConstructor<P> pointConstructor;
private Set<P> vertices; private Set<PVertex<P>> vertices;
public PMesh(final IPointConstructor<P> pointConstructor) { public PMesh(final IPointConstructor<P> pointConstructor) {
this.faces = new ArrayList<>(); this.faces = new ArrayList<>();
...@@ -48,13 +49,13 @@ public class PMesh<P extends IPoint> implements IMesh<P, PHalfEdge<P>, PFace<P>> ...@@ -48,13 +49,13 @@ public class PMesh<P extends IPoint> implements IMesh<P, PHalfEdge<P>, PFace<P>>
} }
@Override @Override
public PFace<P> getFace(final PHalfEdge<P> halfEdge) { public PFace<P> getFace(@NotNull final PHalfEdge<P> halfEdge) {
return halfEdge.getFace(); return halfEdge.getFace();
} }
@Override @Override
public PHalfEdge<P> getEdge(@NotNull P vertex) { public PHalfEdge<P> getEdge(@NotNull PVertex<P> vertex) {
return null; return vertex.getEdge();
} }
@Override @Override
...@@ -63,10 +64,20 @@ public class PMesh<P extends IPoint> implements IMesh<P, PHalfEdge<P>, PFace<P>> ...@@ -63,10 +64,20 @@ public class PMesh<P extends IPoint> implements IMesh<P, PHalfEdge<P>, PFace<P>>
} }
@Override @Override
public P getVertex(@NotNull PHalfEdge<P> halfEdge) { public P getPoint(@NotNull PHalfEdge<P> halfEdge) {
return getVertex(halfEdge).getPoint();
}
@Override
public PVertex<P> getVertex(@NotNull PHalfEdge<P> halfEdge) {
return halfEdge.getEnd(); return halfEdge.getEnd();
} }
@Override
public P getPoint(@NotNull PVertex<P> vertex) {
return vertex.getPoint();
}
@Override @Override
public PFace<P> getFace() { public PFace<P> getFace() {
return faces.stream().filter(face -> !face.isDestroyed()).findAny().get(); return faces.stream().filter(face -> !face.isDestroyed()).findAny().get();
...@@ -118,22 +129,22 @@ public class PMesh<P extends IPoint> implements IMesh<P, PHalfEdge<P>, PFace<P>> ...@@ -118,22 +129,22 @@ public class PMesh<P extends IPoint> implements IMesh<P, PHalfEdge<P>, PFace<P>>
} }
@Override @Override
public void setEdge(@NotNull P vertex, @NotNull PHalfEdge<P> edge) { public void setEdge(@NotNull PVertex<P> vertex, @NotNull PHalfEdge<P> edge) {
throw new UnsupportedOperationException("not jet implemented."); vertex.setEdge(edge);
} }
@Override @Override
public void setVertex(@NotNull PHalfEdge<P> halfEdge, @NotNull P vertex) { public void setVertex(@NotNull PHalfEdge<P> halfEdge, @NotNull PVertex<P> vertex) {
halfEdge.setEnd(vertex); halfEdge.setEnd(vertex);
} }
@Override @Override
public List<PHalfEdge<P>> getEdges(@NotNull P vertex) { public List<PHalfEdge<P>> getEdges(@NotNull final PVertex<P> vertex) {
return edges.stream().filter(edge -> !edge.isValid()).filter(edge -> getVertex(edge).equals(vertex)).collect(Collectors.toList()); return edges.stream().filter(edge -> !edge.isValid()).filter(edge -> getVertex(edge).equals(vertex)).collect(Collectors.toList());
} }
@Override @Override
public Collection<P> getVertices() { public Collection<PVertex<P>> getVertices() {
return vertices; return vertices;
} }
...@@ -148,14 +159,14 @@ public class PMesh<P extends IPoint> implements IMesh<P, PHalfEdge<P>, PFace<P>> ...@@ -148,14 +159,14 @@ public class PMesh<P extends IPoint> implements IMesh<P, PHalfEdge<P>, PFace<P>>
} }
@Override @Override
public PHalfEdge<P> createEdge(@NotNull P vertex) { public PHalfEdge<P> createEdge(@NotNull PVertex<P> vertex) {
PHalfEdge<P> edge = new PHalfEdge<>(vertex); PHalfEdge<P> edge = new PHalfEdge<>(vertex);
edges.add(edge); edges.add(edge);
return edge; return edge;
} }
@Override @Override
public PHalfEdge<P> createEdge(@NotNull P vertex, @NotNull PFace<P> face) { public PHalfEdge<P> createEdge(@NotNull PVertex<P> vertex, @NotNull PFace<P> face) {
PHalfEdge<P> edge = new PHalfEdge<>(vertex, face); PHalfEdge<P> edge = new PHalfEdge<>(vertex, face);
edges.add(edge); edges.add(edge);
return edge; return edge;
...@@ -179,10 +190,20 @@ public class PMesh<P extends IPoint> implements IMesh<P, PHalfEdge<P>, PFace<P>> ...@@ -179,10 +190,20 @@ public class PMesh<P extends IPoint> implements IMesh<P, PHalfEdge<P>, PFace<P>>
} }
@Override @Override
public P createVertex(double x, double y) { public P createPoint(double x, double y) {
P vertex = pointConstructor.create(x, y); return pointConstructor.create(x, y);
//vertices.add(vertex); }
return vertex;
// TODO: maybe remove insertVertex!
@Override
public PVertex<P> createVertex(double x, double y) {
return createVertex(pointConstructor.create(x, y));
}
@Override
public PVertex<P> createVertex(P point) {
return new PVertex<>(point);
} }
@Override @Override
...@@ -191,12 +212,12 @@ public class PMesh<P extends IPoint> implements IMesh<P, PHalfEdge<P>, PFace<P>> ...@@ -191,12 +212,12 @@ public class PMesh<P extends IPoint> implements IMesh<P, PHalfEdge<P>, PFace<P>>
} }
@Override @Override
public void insert(P vertex) { public void insert(final PVertex<P> vertex) {
vertices.add(vertex); vertices.add(vertex);
} }
@Override @Override
public void insertVertex(P vertex) { public void insertVertex(final PVertex<P> vertex) {
vertices.add(vertex); vertices.add(vertex);
} }
...@@ -213,12 +234,32 @@ public class PMesh<P extends IPoint> implements IMesh<P, PHalfEdge<P>, PFace<P>> ...@@ -213,12 +234,32 @@ public class PMesh<P extends IPoint> implements IMesh<P, PHalfEdge<P>, PFace<P>>
} }
@Override @Override
public void destroyVertex(@NotNull P vertex) { public void setDown(@NotNull PVertex<P> up, @NotNull PVertex<P> down) {
up.setDown(down);
}
@Override
public PVertex<P> getDown(@NotNull PVertex<P> vertex) {
return vertex.getDown();
}
@Override
public void destroyVertex(@NotNull PVertex<P> vertex) {
vertices.remove(vertex); vertices.remove(vertex);
} }
@Override
public Stream<PFace<P>> streamFaces() {
return faces.stream();
}
@Override
public Stream<PHalfEdge<P>> streamEdges() {
return streamFaces().flatMap(face -> streamEdges(face));
}
@Override @Override
public List<PFace<P>> getFaces() { public List<PFace<P>> getFaces() {
return faces.stream().filter(face -> !face.isDestroyed()).collect(Collectors.toList()); return streamFaces().filter(face -> !face.isDestroyed()).collect(Collectors.toList());
} }
} }
package org.vadere.util.geometry.mesh.impl;
import org.vadere.util.geometry.mesh.inter.IVertex;
import org.vadere.util.geometry.shapes.IPoint;
/**
* @author Benedikt Zoennchen
* @param <P>
*/
public class PVertex<P extends IPoint> implements IVertex<P> {
private final P point;
private PVertex<P> down;
private PHalfEdge<P> halfEdge;
public PVertex(final P point) {
this.point = point;
this.down = null;
}
@Override
public P getPoint() {
return point;
}
public PHalfEdge<P> getEdge() {
return halfEdge;
}
public void setEdge(final PHalfEdge<P> halfEdge) {
this.halfEdge = halfEdge;
}
public PVertex<P> getDown() {
return down;
}
public void setDown(final PVertex<P> down) {
this.down = down;
}
@Override
public boolean equals(Object obj) {
if(obj == null) {
return false;
}
if(obj.getClass() != this.getClass()) {
return false;
}
return point.equals(((PVertex<P>)obj).getPoint());
}
@Override
public int hashCode() {
return point.hashCode();
}
@Override
public String toString() {
return point.toString();
}
}
package org.vadere.util.geometry.mesh.inter;
import java.util.ArrayList;
import java.util.List;
/**
* Created by bzoennchen on 04.04.17.
*/
public interface ITriangulationHierarchy<
P extends IHierarchyPoint,
E extends IHalfEdge<P>,
F extends IFace<P>,
T extends ITriangulation> {
enum LOCATE_TYPE {}
default P insert(final double x, final double y, LOCATE_TYPE locateType, F face, int li) {
int vertexLevel = randomLevel();
List<F> faces = locateInAll(x ,y);
ITriangulation<P, E, F> triangulation = getLevel(0);
P vertex = triangulation.getMesh().insertVertex(x, y);
triangulation.insert(faces.get(0), vertex);
P prev = vertex;
P first = vertex;
int level = 1;
while(level <= vertexLevel) {
triangulation = getLevel(level);
vertex = triangulation.getMesh().insertVertex(x, y);
vertex.setDown(prev);// link with level above
prev.setUp(vertex);
prev = vertex;
level++;
}
return first;
}
int randomLevel();
int getMaxLevel();
int getMinSize();
IHierarchyPoint create(P vertex);
ITriangulation<P, E, F> getLevel(int level);
default List<F> locateInAll(double x, double y) {
int level = getMaxLevel();
F face;
List<F> faces = new ArrayList<>(getMaxLevel());
while(level > 0 && (getLevel(level).getMesh().getNumberOfVertices() < getMinSize() || getLevel(level).getDimension() < 2)) {
level--;
}
for(int i = level+1; i < getMaxLevel(); i++) {
//pos[i] = 0???
}
while(level > 0) {
//getLevel(level).lo
//faces.add(face);
}
return null;
}
}
...@@ -3,6 +3,7 @@ package org.vadere.util.geometry.mesh.iterators; ...@@ -3,6 +3,7 @@ package org.vadere.util.geometry.mesh.iterators;
import org.vadere.util.geometry.mesh.inter.IFace; import org.vadere.util.geometry.mesh.inter.IFace;
import org.vadere.util.geometry.mesh.inter.IHalfEdge; import org.vadere.util.geometry.mesh.inter.IHalfEdge;
import org.vadere.util.geometry.mesh.inter.IMesh; import org.vadere.util.geometry.mesh.inter.IMesh;
import org.vadere.util.geometry.mesh.inter.IVertex;
import org.vadere.util.geometry.shapes.IPoint; import org.vadere.util.geometry.shapes.IPoint;
import java.util.Iterator; import java.util.Iterator;
...@@ -15,13 +16,13 @@ import java.util.Iterator; ...@@ -15,13 +16,13 @@ import java.util.Iterator;
* @param <E> the type of the half-edge * @param <E> the type of the half-edge
* @param <F> the type of the face * @param <F> the type of the face
*/ */
public class EdgeIterator<P extends IPoint, E extends IHalfEdge<P>, F extends IFace<P>> implements Iterator<E> { public class EdgeIterator<P extends IPoint, V extends IVertex<P>, E extends IHalfEdge<P>, F extends IFace<P>> implements Iterator<E> {
private E currentHalfEdge; private E currentHalfEdge;
private E edge; private E edge;
private boolean started = false; private boolean started = false;
private IMesh<P, E, F> mesh; private IMesh<P, V, E, F> mesh;
public EdgeIterator(final IMesh<P, E, F> mesh, final F face){ public EdgeIterator(final IMesh<P, V, E, F> mesh, final F face){
this.edge = mesh.getEdge(face); this.edge = mesh.getEdge(face);
this.currentHalfEdge = edge; this.currentHalfEdge = edge;
this.mesh = mesh; this.mesh = mesh;
......
...@@ -2,13 +2,11 @@ package org.vadere.util.geometry.mesh.triangulations; ...@@ -2,13 +2,11 @@ package org.vadere.util.geometry.mesh.triangulations;
import org.vadere.util.geometry.mesh.inter.IFace; import org.vadere.util.geometry.mesh.inter.IFace;
import org.vadere.util.geometry.mesh.inter.IHalfEdge; import org.vadere.util.geometry.mesh.inter.IHalfEdge;
import org.vadere.util.geometry.mesh.inter.IMesh;
import org.vadere.util.geometry.mesh.inter.IPointLocator; import org.vadere.util.geometry.mesh.inter.IPointLocator;
import org.vadere.util.geometry.mesh.inter.ITriConnectivity; import org.vadere.util.geometry.mesh.inter.ITriConnectivity;
import org.vadere.util.geometry.mesh.inter.IVertex;
import org.vadere.util.geometry.shapes.IPoint; import org.vadere.util.geometry.shapes.IPoint;
import java.util.Collection;
import java.util.Collections;
import java.util.Optional; import java.util.Optional;
/** /**
...@@ -16,47 +14,53 @@ import java.util.Optional; ...@@ -16,47 +14,53 @@ import java.util.Optional;
* *
* The BasePointLocatetor only uses the mesh itself and does not use any additional data structure * The BasePointLocatetor only uses the mesh itself and does not use any additional data structure
* to find the face for a given point. It runs a march starting from some (not known) face of the * to find the face for a given point. It runs a march starting from some (not known) face of the
* mesh and end up at the face that contains the point. In worst case this is not faster than * mesh and end up at the face that triangleContains the point. In worst case this is not faster than
* checking each each face of the mesh but it is more clever and faste in the most cases. * checking each each face of the mesh but it is more clever and faste in the most cases.
* *
* *
* @param <P> * @param <P>
* @param <V>
* @param <E> * @param <E>
* @param <F> * @param <F>
*/ */
public class BasePointLocator<P extends IPoint, E extends IHalfEdge<P>, F extends IFace<P>> implements IPointLocator<P, E, F> { public class BasePointLocator<P extends IPoint, V extends IVertex<P>, E extends IHalfEdge<P>, F extends IFace<P>> implements IPointLocator<P, V, E, F> {
private ITriConnectivity<P, E, F> triConnectivity; private ITriConnectivity<P, V, E, F> triConnectivity;
public BasePointLocator(final ITriConnectivity<P, E, F> triConnectivity) { public BasePointLocator(final ITriConnectivity<P, V, E, F> triConnectivity) {
this.triConnectivity = triConnectivity; this.triConnectivity = triConnectivity;
} }
@Override @Override
public void splitFaceEvent(final F original, final F[] faces) {} public void splitTriangleEvent(F original, F f1, F f2, F f3) {}
@Override
public void splitEdgeEvent(F original, F f1, F f2) {}
@Override @Override
public void flipEdgeEvent(final F f1, final F f2) {} public void flipEdgeEvent(final F f1, final F f2) {}
@Override @Override
public void insertEvent(E vertex) {} public void insertEvent(V vertex) {}
@Override @Override
public void deleteBoundaryFace(final F face) {} public void deleteBoundaryFace(final F face) {}
@Override @Override
public Collection<F> locatePoint(final IPoint point, boolean insertion) { public F locatePoint(final P point, boolean insertion) {
if(insertion) { //return triConnectivity.getMesh().getFace(triConnectivity.locateNearestNeighbour(point));
return triConnectivity.getAdjacentFaces(point.getX(), point.getY()); return triConnectivity.locateFace(point.getX(), point.getY()).get();
/*if(insertion) {
return triConnectivity.getClosestEdge(point.getX(), point.getY());
} }
else { else {
Optional<F> optFace = triConnectivity.locate(point.getX(), point.getY()); Optional<F> optFace = triConnectivity.locateFace(point.getX(), point.getY());
return optFace.isPresent() ? Collections.singleton(optFace.get()) : Collections.emptyList(); return optFace.isPresent() ? Collections.singleton(optFace.get()) : Collections.emptyList();
} }*/
} }
@Override @Override
public Optional<F> locate(final IPoint point) { public Optional<F> locate(final IPoint point) {
return triConnectivity.locate(point.getX(), point.getY()); return triConnectivity.locateFace(point.getX(), point.getY());
} }
} }