Commit 0ce6b028 authored by Benedikt Zoennchen's avatar Benedikt Zoennchen

before introducing IVertex for the mesh

parent 38622449
package org.vadere.util.geometry.mesh.inter;
import org.vadere.util.geometry.shapes.IPoint;
/**
......
......@@ -241,7 +241,7 @@ public interface ITriConnectivity<P extends IPoint, E extends IHalfEdge<P>, F ex
* @param p the point which splits the triangle
* @param face the triangle face we split
*
* returns a half-edge which has p as its end vertex
* returns a list of all newly created face.
*/
default List<F> splitTriangle(@NotNull F face, P p, boolean legalize) {
assert isTriangle(face);
......@@ -552,7 +552,7 @@ public interface ITriConnectivity<P extends IPoint, E extends IHalfEdge<P>, F ex
P v2 = getMesh().getVertex(getMesh().getPrev(halfEdge));
// TODO: think about the epsilon, absolute value seems to be a really bad idea!
if(!getMesh().isBoundary(getMesh().getTwinFace(halfEdge)) && Math.abs(GeometryUtils.sign(x, y, v1.getX(), v1.getY(), v2.getX(), v2.getY())) == 0.0) {
if(!getMesh().isBoundary(getMesh().getTwinFace(halfEdge)) && Math.abs(GeometryUtils.ccw(x, y, v1.getX(), v1.getY(), v2.getX(), v2.getY())) == 0.0) {
faces.add(getMesh().getTwinFace(halfEdge));
break;
}
......
package org.vadere.util.geometry.mesh.triangulations;
import org.jetbrains.annotations.NotNull;
import org.vadere.util.geometry.mesh.inter.IFace;
import org.vadere.util.geometry.mesh.inter.IHalfEdge;
import org.vadere.util.geometry.mesh.inter.IMesh;
......@@ -9,7 +10,9 @@ import org.vadere.util.geometry.mesh.inter.ITriangulation;
import org.vadere.util.geometry.shapes.IPoint;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
......@@ -30,11 +33,14 @@ public class DelaunayHierarchy<P extends IPoint, E extends IHalfEdge<P>, F exten
private List<Map<E, E>> hierarchyConnector;
private ITriConnectivity<P, E, F> base;
private ITriangulation<P, E, F> base;
private Supplier<ITriangulation<P, E, F>> triangulationSupplier;
private double alpha;
// see delaunay-hierarchy paper!
private double alpha = 40;
private double epsilon = 0.00001;
private Random random;
......@@ -43,6 +49,8 @@ public class DelaunayHierarchy<P extends IPoint, E extends IHalfEdge<P>, F exten
this.hierarchyConnector = new ArrayList<>();
this.random = new Random();
this.triangulationSupplier = triangulationSupplier;
this.base = base;
this.base.init();
hierarchySets.add(base);
hierarchyConnector.add(new HashMap<>());
......@@ -55,15 +63,18 @@ public class DelaunayHierarchy<P extends IPoint, E extends IHalfEdge<P>, F exten
public void flipEdgeEvent(F f1, F f2) {}
@Override
public void insertEvent(final E halfEdge) {
public void insertEvent(@NotNull final E halfEdge) {
P vertex = base.getMesh().getVertex(halfEdge);
E lastEdge = halfEdge;
for(int i = 1; i < hierarchySets.size(); ++i) {
int limit = hierarchySets.size();
for(int i = 1; i <= limit; ++i) {
if(random.nextDouble() < alpha) {
if(hierarchySets.size() <= i) {
hierarchySets.add(triangulationSupplier.get());
ITriangulation<P, E, F> triangulation = triangulationSupplier.get();
triangulation.init();
hierarchySets.add(triangulation);
}
E edge = hierarchySets.get(i).insert(vertex);
......@@ -72,7 +83,7 @@ public class DelaunayHierarchy<P extends IPoint, E extends IHalfEdge<P>, F exten
hierarchyConnector.add(new HashMap<>());
}
hierarchyConnector.get(i-1).put(lastEdge, edge);
hierarchyConnector.get(i-1).put(edge, lastEdge);
lastEdge = edge;
}
......@@ -89,24 +100,56 @@ public class DelaunayHierarchy<P extends IPoint, E extends IHalfEdge<P>, F exten
@Override
public Collection<F> locatePoint(P point, boolean insertion) {
return null;
Optional<F> optFace = locate(point);
if(optFace.isPresent()) {
F face = optFace.get();
if(!insertion) {
return Collections.singleton(face);
}
else {
Optional<E> optEdge = base.getMesh().getMemberEdge(face, point.getX(), point.getY(), epsilon);
// ignore point
if(optEdge.isPresent()) {
return Collections.emptyList();
}
else {
optEdge = base.getMesh().getEdgeCloseToVertex(face, point.getX(), point.getY(), epsilon);
if(optEdge.isPresent()) {
return Arrays.asList(base.getMesh().getFace(optEdge.get()), base.getMesh().getTwinFace(optEdge.get()));
}
else {
return Collections.singleton(face);
}
}
}
}
else {
return Collections.emptyList();
}
}
@Override
public Optional<F> locate(final P point) {
Optional<F> optStartFace = Optional.empty();
for(int i = hierarchySets.size()-1; i >= 0; --i) {
if(!optStartFace.isPresent()) {
if(i == hierarchySets.size()-1) {
optStartFace = hierarchySets.get(i).locate(point.getX(), point.getY());
}
else {
E edge = getNearestPoint(hierarchySets.get(i-1), optStartFace.get(), point);
E newEdge = hierarchyConnector.get(i-1).get(edge);
optStartFace = hierarchySets.get(i).locate(point.getX(), point.getY(), hierarchySets.get(i).getMesh().getFace(newEdge));
if(!optStartFace.isPresent()) {
return Optional.empty();
if(i > 0) {
E edge = getNearestPoint(hierarchySets.get(i+1), optStartFace.get(), point);
E newEdge = hierarchyConnector.get(i).get(edge);
optStartFace = hierarchySets.get(i).locate(point.getX(), point.getY(), hierarchySets.get(i).getMesh().getFace(newEdge));
}
else {
E edge = getNearestPoint(hierarchySets.get(i+1), optStartFace.get(), point);
E newEdge = hierarchyConnector.get(i).get(edge);
return base.locate(point.getX(), point.getY(), base.getMesh().getFace(newEdge));
}
}
}
......
......@@ -44,8 +44,7 @@ public class DelaunayTree<P extends IPoint, E extends IHalfEdge<P>, F extends IF
@Override
public Collection<F> locatePoint(final P point, final boolean insertion) {
checkRoot();
Set<DAG<DAGElement<P, F>>> leafs = new HashSet<>();
LinkedList<DAG<DAGElement<P, F>>> nodesToVisit = new LinkedList<>();
nodesToVisit.add(dag);
......
......@@ -3,6 +3,7 @@ package org.vadere.util.geometry.mesh.triangulations;
import org.apache.commons.collections.IteratorUtils;
import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;
import org.jetbrains.annotations.NotNull;
import org.vadere.util.geometry.GeometryUtils;
import org.vadere.util.geometry.mesh.impl.PFace;
import org.vadere.util.geometry.mesh.iterators.FaceIterator;
......@@ -71,6 +72,7 @@ public class IncrementalTriangulation<P extends IPoint, E extends IHalfEdge<P>,
this.points = points;
this.illegalPredicate = illegalPredicate;
this.bound = GeometryUtils.bound(points);
this.finalized = false;
}
public IncrementalTriangulation(final Set<P> points) {
......@@ -83,6 +85,7 @@ public class IncrementalTriangulation<P extends IPoint, E extends IHalfEdge<P>,
this.points = new HashSet<>();
this.illegalPredicate = illegalPredicate;
this.bound = bound;
this.finalized = false;
}
public IncrementalTriangulation(final VRectangle bound) {
......@@ -97,10 +100,6 @@ public class IncrementalTriangulation<P extends IPoint, E extends IHalfEdge<P>,
this.mesh = mesh;
}
public F getSuperTriangle() {
return superTriangle;
}
@Override
public void init() {
double gap = 1.0;
......@@ -117,7 +116,6 @@ public class IncrementalTriangulation<P extends IPoint, E extends IHalfEdge<P>,
he1 = borderEdges.get(1);
he2 = borderEdges.get(2);
this.finalized = false;
this.initialized = true;
}
......@@ -138,6 +136,10 @@ public class IncrementalTriangulation<P extends IPoint, E extends IHalfEdge<P>,
@Override
public E insert(P point) {
if(!initialized) {
init();
}
Collection<F> faces = this.pointLocator.locatePoint(point, true);
int numberOfFaces = faces.size();
......@@ -151,8 +153,8 @@ public class IncrementalTriangulation<P extends IPoint, E extends IHalfEdge<P>,
else if(faces.size() == 1) {
log.info("splitTriangle:" + point);
F face = faces.iterator().next();
splitTriangle(face, point, true);
insertedEdge = mesh.getEdge(point);
List<F> createdFaces = splitTriangle(face, point, true);
insertedEdge = mesh.getMemberEdge(createdFaces.get(0), point.getX(), point.getY()).get();
insertEvent(insertedEdge);
} // point lies on an edge of 2 triangles
......@@ -389,7 +391,7 @@ public class IncrementalTriangulation<P extends IPoint, E extends IHalfEdge<P>,
}
@Override
public void insertEvent(final E halfEdge) {
public void insertEvent(@NotNull final E halfEdge) {
pointLocator.insertEvent(halfEdge);
}
......
......@@ -79,6 +79,12 @@ public class UniformRefinementTriangulation<P extends IPoint> {
}
}
removeTrianglesInsideObstacles();
logger.info("end computation");
}
private void removeTrianglesInsideObstacles() {
for(VShape shape : boundary) {
// 1. find a triangle inside the boundary
VPoint centroid = shape.getCentroid();
......@@ -102,7 +108,6 @@ public class UniformRefinementTriangulation<P extends IPoint> {
logger.warn("no face found");
}
}
logger.info("end computation");
}
public Set<VLine> getEdges() {
......
......@@ -137,7 +137,7 @@ public class TestBoyerWatson {
long ms = System.currentTimeMillis();
ITriangulation<VPoint, PHalfEdge<VPoint>, PFace<VPoint>> delaunayTriangulation = ITriangulation.createPTriangulation(IPointLocator.Type.DELAUNAY_TREE, points, (x, y) -> new VPoint(x, y));
delaunayTriangulation.finalize();
log.info("runtime of the BowyerWatson for " + numberOfPoints + " vertices =" + (System.currentTimeMillis() - ms));
log.info("runtime of the BowyerWatson for " + numberOfPoints + " vertices =" + (System.currentTimeMillis() - ms) + " using the delaunay-tree");
log.info("start checking the delaunay property, this can take some time");
Collection<VTriangle> triangles = delaunayTriangulation.streamTriangles().collect(Collectors.toList());
......@@ -151,6 +151,24 @@ public class TestBoyerWatson {
}
}
log.info("end checking the delaunay property");
ms = System.currentTimeMillis();
delaunayTriangulation = ITriangulation.createPTriangulation(IPointLocator.Type.DELAUNAY_HIERARCHY, points, (x, y) -> new VPoint(x, y));
delaunayTriangulation.finalize();
log.info("runtime of the BowyerWatson for " + numberOfPoints + " vertices =" + (System.currentTimeMillis() - ms) + " using the delaunay-hierarchy");
log.info("start checking the delaunay property, this can take some time");
triangles = delaunayTriangulation.streamTriangles().collect(Collectors.toList());
for(VTriangle triangle : triangles) {
List<VPoint> trianglePoints = triangle.getPoints();
for(VTriangle t : triangles) {
assertTrue(t.getPoints().stream().noneMatch(p -> !trianglePoints.contains(p) && triangle.isInCircumscribedCycle(p)));
}
}
log.info("end checking the delaunay property");
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment