Commit bdf7df5a authored by Benedikt Kleinmeier's avatar Benedikt Kleinmeier

Merge branch 'master' into psychology

parents 21329876 9c467b36
Pipeline #272677 passed with stages
in 136 minutes and 16 seconds
...@@ -50,9 +50,9 @@ import java.util.stream.Collectors; ...@@ -50,9 +50,9 @@ import java.util.stream.Collectors;
public class MeshQuantityPrinting { public class MeshQuantityPrinting {
public static void main(String... args) throws InterruptedException, IOException { public static void main(String... args) throws InterruptedException, IOException {
spaceFillingCurve2(); //spaceFillingCurve2();
//uniformMeshDiscFunction(0.10); //uniformMeshDiscFunction(0.10);
//uniformMeshDiscFunctionDistMesh(0.05); uniformMeshDiscFunctionDistMesh(0.05);
//distMeshFail(0.05); //distMeshFail(0.05);
//delaunyTri("/poly/a.poly"); //delaunyTri("/poly/a.poly");
} }
...@@ -192,7 +192,7 @@ public class MeshQuantityPrinting { ...@@ -192,7 +192,7 @@ public class MeshQuantityPrinting {
bufferedWriterQualities2.write("iteration quality\n"); bufferedWriterQualities2.write("iteration quality\n");
BufferedWriter bufferedWriterAngles = IOUtils.getWriter("angles_eik.csv", dir); BufferedWriter bufferedWriterAngles = IOUtils.getWriter("angles_eik.csv", dir);
bufferedWriterAngles.write("iteration angle3D\n"); bufferedWriterAngles.write("iteration angle\n");
int init = 1; int init = 1;
while (!meshImprover.isInitialized()) { while (!meshImprover.isInitialized()) {
...@@ -255,14 +255,14 @@ public class MeshQuantityPrinting { ...@@ -255,14 +255,14 @@ public class MeshQuantityPrinting {
bufferedWriterQualities2.write("iteration quality\n"); bufferedWriterQualities2.write("iteration quality\n");
BufferedWriter bufferedWriterAngles = IOUtils.getWriter("angles_dist.csv", dir); BufferedWriter bufferedWriterAngles = IOUtils.getWriter("angles_dist.csv", dir);
bufferedWriterAngles.write("iteration angle3D\n"); bufferedWriterAngles.write("iteration angle\n");
int iteration = 1; int iteration = 1;
while (iteration < maxIteration+1) { while (iteration < maxIteration+1) {
distmesh.improve(); distmesh.improve();
if(iteration + 1 == maxIteration+1) { /*if(iteration + 1 == maxIteration+1) {
distmesh.reTriangulate(true); distmesh.reTriangulate(true);
} }*/
bufferedWriterIllegalEdges.write(iteration + " " + distmesh.getNumberOfIllegalTriangles() + "\n"); bufferedWriterIllegalEdges.write(iteration + " " + distmesh.getNumberOfIllegalTriangles() + "\n");
bufferedWriterQualities1.write(printQualities(iteration, distmesh, f -> GeometryUtils.qualityOf(f))); bufferedWriterQualities1.write(printQualities(iteration, distmesh, f -> GeometryUtils.qualityOf(f)));
bufferedWriterQualities2.write(printQualities(iteration, distmesh, f -> GeometryUtils.qualityLongestEdgeInCircle(f.p1, f.p2, f.p3))); bufferedWriterQualities2.write(printQualities(iteration, distmesh, f -> GeometryUtils.qualityLongestEdgeInCircle(f.p1, f.p2, f.p3)));
......
...@@ -321,7 +321,7 @@ public class IncrementalTriangulation<V extends IVertex, E extends IHalfEdge, F ...@@ -321,7 +321,7 @@ public class IncrementalTriangulation<V extends IVertex, E extends IHalfEdge, F
// remove all faces outside the hole // remove all faces outside the hole
VPolygon polygon = getMesh().toPolygon(hole); VPolygon polygon = getMesh().toPolygon(hole);
Predicate<F> removePredicate = face -> !polygon.contains(getMesh().toTriangle(face).midPoint()); Predicate<F> removePredicate = face -> !polygon.contains(getMesh().toMidpoint(face));
cdt.getTriangulation().shrinkBorder(removePredicate, true); cdt.getTriangulation().shrinkBorder(removePredicate, true);
IMesh<V, E, F> holeMesh = incrementalTriangulation.getMesh(); IMesh<V, E, F> holeMesh = incrementalTriangulation.getMesh();
......
...@@ -545,6 +545,9 @@ public interface IMesh<V extends IVertex, E extends IHalfEdge, F extends IFace> ...@@ -545,6 +545,9 @@ public interface IMesh<V extends IVertex, E extends IHalfEdge, F extends IFace>
* @return (optional) a boundary edge * @return (optional) a boundary edge
*/ */
default Optional<E> getBoundaryEdge(@NotNull final V vertex) { default Optional<E> getBoundaryEdge(@NotNull final V vertex) {
if(isBoundary(getEdge(vertex))) {
return Optional.of(getEdge(vertex));
}
return streamEdges(vertex).filter(e -> isBoundary(e)).findAny(); return streamEdges(vertex).filter(e -> isBoundary(e)).findAny();
} }
...@@ -1360,6 +1363,24 @@ public interface IMesh<V extends IVertex, E extends IHalfEdge, F extends IFace> ...@@ -1360,6 +1363,24 @@ public interface IMesh<V extends IVertex, E extends IHalfEdge, F extends IFace>
return new VTriangle(new VPoint(vertices.get(0)), new VPoint(vertices.get(1)), new VPoint(vertices.get(2))); return new VTriangle(new VPoint(vertices.get(0)), new VPoint(vertices.get(1)), new VPoint(vertices.get(2)));
} }
default VPoint toMidpoint(@NotNull final F face) {
assert getVertices(face).size() == 3 : "number of vertices of " + face + " is " + getVertices(face).size();
E edge = getEdge(face);
V v1 = getVertex(edge);
V v2 = getVertex(getNext(edge));
V v3 = getVertex(getPrev(edge));
return GeometryUtils.getTriangleMidpoint(getX(v1), getY(v1), getX(v2), getY(v2), getX(v3), getY(v3));
}
default VPoint toCircumcenter(@NotNull final F face) {
assert getVertices(face).size() == 3 : "number of vertices of " + face + " is " + getVertices(face).size();
E edge = getEdge(face);
V v1 = getVertex(edge);
V v2 = getVertex(getNext(edge));
V v3 = getVertex(getPrev(edge));
return GeometryUtils.getCircumcenter(getX(v1), getY(v1), getX(v2), getY(v2), getX(v3), getY(v3));
}
/** /**
* Returns the midpoint {@link VPoint} of a triangle defined by the face. * Returns the midpoint {@link VPoint} of a triangle defined by the face.
* Assumption: The face represents a triangle, i.e. it has exactly 3 distinct points. This * Assumption: The face represents a triangle, i.e. it has exactly 3 distinct points. This
...@@ -2362,6 +2383,17 @@ public interface IMesh<V extends IVertex, E extends IHalfEdge, F extends IFace> ...@@ -2362,6 +2383,17 @@ public interface IMesh<V extends IVertex, E extends IHalfEdge, F extends IFace>
} }
default String toPythonValues(@NotNull final Function<V, Double> evalPoint) {
StringBuilder builder = new StringBuilder();
List<V> vertices = getVertices();
for(V v : vertices) {
builder.append(evalPoint.apply(v) + ",");
}
builder.delete(builder.length()-1, builder.length());
builder.append("\n");
return builder.toString();
}
/** /**
* Constructs and returns a string which can be used to construct a matplotlib Triangulation * Constructs and returns a string which can be used to construct a matplotlib Triangulation
* which is helpful to plot the mesh. * which is helpful to plot the mesh.
......
...@@ -116,7 +116,7 @@ public interface IPolyConnectivity<V extends IVertex, E extends IHalfEdge, F ext ...@@ -116,7 +116,7 @@ public interface IPolyConnectivity<V extends IVertex, E extends IHalfEdge, F ext
* @param vertex v * @param vertex v
*/ */
default void adjustVertex(@NotNull final V vertex) { default void adjustVertex(@NotNull final V vertex) {
getMesh().streamEdges(vertex).filter(edge -> isAtBoundary(edge)).findAny().ifPresent(edge -> getMesh().setEdge(vertex, edge)); getMesh().streamEdges(vertex).filter(edge -> getMesh().isBoundary(edge)).findAny().ifPresent(edge -> getMesh().setEdge(vertex, edge));
} }
/** /**
...@@ -632,14 +632,15 @@ public interface IPolyConnectivity<V extends IVertex, E extends IHalfEdge, F ext ...@@ -632,14 +632,15 @@ public interface IPolyConnectivity<V extends IVertex, E extends IHalfEdge, F ext
* @param face they face which will be transformed into a hole * @param face they face which will be transformed into a hole
* @param mergeCondition the merge condition * @param mergeCondition the merge condition
* @param deleteIsoletedVertices if true isolated vertices, i.e. vertices without any edges, will be removed from the mesh * @param deleteIsoletedVertices if true isolated vertices, i.e. vertices without any edges, will be removed from the mesh
* @param vertexAdjust true means that boundary vertices will get their boundary edge as edge, false means there is no guarantee that this adjustment is made
* @return (optional) the hole or face itself it the face does not fulfill the merge condition * @return (optional) the hole or face itself it the face does not fulfill the merge condition
* or empty if due to the creation of the hole all faces will be removed! * or empty if due to the creation of the hole all faces will be removed!
*/ */
default Optional<F> createHole(@NotNull final F face, @NotNull final Predicate<F> mergeCondition, final boolean deleteIsoletedVertices) { default Optional<F> createHole(@NotNull final F face, @NotNull final Predicate<F> mergeCondition, final boolean deleteIsoletedVertices, final boolean vertexAdjust) {
if(mergeCondition.test(face)) { if(mergeCondition.test(face)) {
getMesh().toHole(face); getMesh().toHole(face);
shrinkBoundary(face, mergeCondition, deleteIsoletedVertices); shrinkBoundary(face, mergeCondition, deleteIsoletedVertices, vertexAdjust);
return Optional.of(face); return Optional.of(face);
} }
else { else {
...@@ -665,6 +666,10 @@ public interface IPolyConnectivity<V extends IVertex, E extends IHalfEdge, F ext ...@@ -665,6 +666,10 @@ public interface IPolyConnectivity<V extends IVertex, E extends IHalfEdge, F ext
}*/ }*/
} }
default Optional<F> createHole(@NotNull final F face, @NotNull final Predicate<F> mergeCondition, final boolean deleteIsoletedVertices) {
return createHole(face, mergeCondition, deleteIsoletedVertices, true);
}
/** /**
* Shrinks the border as long as the removeCondition is satisfied i.e. a face will be removed if * Shrinks the border as long as the removeCondition is satisfied i.e. a face will be removed if
* it is at the border (during the shrinking process) and satisfies the condition. Like a virus this * it is at the border (during the shrinking process) and satisfies the condition. Like a virus this
...@@ -675,9 +680,14 @@ public interface IPolyConnectivity<V extends IVertex, E extends IHalfEdge, F ext ...@@ -675,9 +680,14 @@ public interface IPolyConnectivity<V extends IVertex, E extends IHalfEdge, F ext
* *
* @param removeCondition the remove condition * @param removeCondition the remove condition
* @param deleteIsolatedVertices true then isolated vertices (they are not connected to an edge) will be removed. * @param deleteIsolatedVertices true then isolated vertices (they are not connected to an edge) will be removed.
* @param vertexAdjust true means that boundary vertices will get their boundary edge as edge, false means there is no guarantee that this adjustment is made
*/ */
default void shrinkBorder(final Predicate<F> removeCondition, final boolean deleteIsolatedVertices, final boolean vertexAdjust) {
shrinkBoundary(getMesh().getBorder(), removeCondition, deleteIsolatedVertices, vertexAdjust);
}
default void shrinkBorder(final Predicate<F> removeCondition, final boolean deleteIsolatedVertices) { default void shrinkBorder(final Predicate<F> removeCondition, final boolean deleteIsolatedVertices) {
shrinkBoundary(getMesh().getBorder(), removeCondition, deleteIsolatedVertices); shrinkBorder(removeCondition, deleteIsolatedVertices, true);
} }
default void shrinkBoundary(final Predicate<F> removeCondition, final boolean deleteIsolatedVertices) { default void shrinkBoundary(final Predicate<F> removeCondition, final boolean deleteIsolatedVertices) {
...@@ -697,8 +707,9 @@ public interface IPolyConnectivity<V extends IVertex, E extends IHalfEdge, F ext ...@@ -697,8 +707,9 @@ public interface IPolyConnectivity<V extends IVertex, E extends IHalfEdge, F ext
* *
* @param removeCondition the remove condition * @param removeCondition the remove condition
* @param deleteIsolatedVertices true then isolated vertices (they are not connected to an edge) will be removed. * @param deleteIsolatedVertices true then isolated vertices (they are not connected to an edge) will be removed.
* @param adjustVertices true means that boundary vertices will get their boundary edge as edge, false means there is no guarantee that this adjustment is made
*/ */
default void shrinkBoundary(@NotNull final F boundary, final Predicate<F> removeCondition, final boolean deleteIsolatedVertices) { default void shrinkBoundary(@NotNull final F boundary, final Predicate<F> removeCondition, final boolean deleteIsolatedVertices, final boolean adjustVertices) {
assert getMesh().isBoundary(boundary); assert getMesh().isBoundary(boundary);
List<F> boundaryFaces = getMesh().getFaces(boundary); List<F> boundaryFaces = getMesh().getFaces(boundary);
...@@ -715,13 +726,17 @@ public interface IPolyConnectivity<V extends IVertex, E extends IHalfEdge, F ext ...@@ -715,13 +726,17 @@ public interface IPolyConnectivity<V extends IVertex, E extends IHalfEdge, F ext
nextNeighbouringFaces.add(face); nextNeighbouringFaces.add(face);
} }
} }
removeFaceAtBoundary(neighbouringFace, boundary, deleteIsolatedVertices); removeFaceAtBoundary(neighbouringFace, boundary, deleteIsolatedVertices, adjustVertices);
} }
} }
neighbouringFaces = nextNeighbouringFaces; neighbouringFaces = nextNeighbouringFaces;
} while (!neighbouringFaces.isEmpty()); } while (!neighbouringFaces.isEmpty());
} }
default void shrinkBoundary(@NotNull final F boundary, final Predicate<F> removeCondition, final boolean deleteIsolatedVertices) {
shrinkBoundary(boundary, removeCondition, deleteIsolatedVertices, true);
}
default void removeFacesAtBoundary(@NotNull final Predicate<F> mergePredicate, @NotNull final Predicate<F> errorPredicate) throws IllegalMeshException { default void removeFacesAtBoundary(@NotNull final Predicate<F> mergePredicate, @NotNull final Predicate<F> errorPredicate) throws IllegalMeshException {
mergeFaces(getMesh().getBorder(), mergePredicate, errorPredicate, true, 1); mergeFaces(getMesh().getBorder(), mergePredicate, errorPredicate, true, 1);
for(F face : getMesh().getHoles()) { for(F face : getMesh().getHoles()) {
...@@ -1215,8 +1230,9 @@ public interface IPolyConnectivity<V extends IVertex, E extends IHalfEdge, F ext ...@@ -1215,8 +1230,9 @@ public interface IPolyConnectivity<V extends IVertex, E extends IHalfEdge, F ext
* @param face the face that will be removed from the mesh * @param face the face that will be removed from the mesh
* @param boundary the boundary which has to be a neighbouring boundary of the face * @param boundary the boundary which has to be a neighbouring boundary of the face
* @param deleteIsolatedVertices true means that all vertices with degree smaller equals 1 will be removed as well * @param deleteIsolatedVertices true means that all vertices with degree smaller equals 1 will be removed as well
* @param adjustVertices true means that boundary vertices will get their boundary edge as edge, false means there is no guarantee that this adjustment is made
*/ */
default void removeFaceAtBoundary(@NotNull final F face, @NotNull final F boundary, final boolean deleteIsolatedVertices) { default void removeFaceAtBoundary(@NotNull final F face, @NotNull final F boundary, final boolean deleteIsolatedVertices, final boolean adjustVertices) {
if(!getMesh().isDestroyed(face)) { if(!getMesh().isDestroyed(face)) {
assert getMesh().streamFaces(face).filter(neighbour -> neighbour.equals(boundary)).count() > 0; assert getMesh().streamFaces(face).filter(neighbour -> neighbour.equals(boundary)).count() > 0;
...@@ -1357,7 +1373,9 @@ public interface IPolyConnectivity<V extends IVertex, E extends IHalfEdge, F ext ...@@ -1357,7 +1373,9 @@ public interface IPolyConnectivity<V extends IVertex, E extends IHalfEdge, F ext
getMesh().destroyEdge(h1); getMesh().destroyEdge(h1);
// adjust vertices such that we speed up the querry isBoundary(vertex). // adjust vertices such that we speed up the querry isBoundary(vertex).
vertices.stream().filter(getMesh()::isAlive).forEach(v -> adjustVertex(v)); if(adjustVertices) {
vertices.stream().filter(getMesh()::isAlive).forEach(v -> adjustVertex(v));
}
} }
} }
...@@ -1371,6 +1389,9 @@ public interface IPolyConnectivity<V extends IVertex, E extends IHalfEdge, F ext ...@@ -1371,6 +1389,9 @@ public interface IPolyConnectivity<V extends IVertex, E extends IHalfEdge, F ext
} }
} }
default void removeFaceAtBoundary(@NotNull final F face, @NotNull final F boundary, final boolean deleteIsolatedVertices) {
removeFaceAtBoundary(face, boundary, deleteIsolatedVertices, true);
}
/** /**
* Removes a face from the mesh by removing all boundary edges of the face. * Removes a face from the mesh by removing all boundary edges of the face.
......
...@@ -1953,7 +1953,7 @@ public interface ITriConnectivity<V extends IVertex, E extends IHalfEdge, F exte ...@@ -1953,7 +1953,7 @@ public interface ITriConnectivity<V extends IVertex, E extends IHalfEdge, F exte
* @return all visited faces in a first visited first in ordered queue, i.e. <tt>LinkedList</tt>. * @return all visited faces in a first visited first in ordered queue, i.e. <tt>LinkedList</tt>.
*/ */
default LinkedList<E> straightWalk2DGatherDirectional(@NotNull final F face, @NotNull final VPoint direction, @NotNull final Predicate<E> additionalStopCondition) { default LinkedList<E> straightWalk2DGatherDirectional(@NotNull final F face, @NotNull final VPoint direction, @NotNull final Predicate<E> additionalStopCondition) {
VPoint q = getMesh().toTriangle(face).midPoint(); VPoint q = getMesh().toMidpoint(face);
assert getMesh().toTriangle(face).contains(q); assert getMesh().toTriangle(face).contains(q);
Predicate<E> defaultStopCondion = e -> isRightOf(q.x, q.y, e); Predicate<E> defaultStopCondion = e -> isRightOf(q.x, q.y, e);
...@@ -2734,7 +2734,8 @@ public interface ITriConnectivity<V extends IVertex, E extends IHalfEdge, F exte ...@@ -2734,7 +2734,8 @@ public interface ITriConnectivity<V extends IVertex, E extends IHalfEdge, F exte
* this might happen if the line intersects a point, in this case both neighbouring edges are feasible * this might happen if the line intersects a point, in this case both neighbouring edges are feasible
*/ */
if(inEdge == null) { if(inEdge == null) {
inEdge = getMesh().streamEdges(startFace).filter(e -> isLeftOf(p.getX(), p.getY(), e)).findAny().get(); Optional<E> optEdge = getMesh().streamEdges(startFace).filter(e -> isLeftOf(p.getX(), p.getY(), e)).findAny();
inEdge = optEdge.get();
} }
} }
......
...@@ -112,7 +112,7 @@ public class Distmesh { ...@@ -112,7 +112,7 @@ public class Distmesh {
} }
public void reTriangulate(boolean force) { public void reTriangulate(boolean force) {
if(true || force || firstStep || maxMovementLen / initialEdgeLen > Parameters.TOL) { if(force || firstStep || maxMovementLen / initialEdgeLen > Parameters.TOL) {
firstStep = false; firstStep = false;
nTriangulations++; nTriangulations++;
......
...@@ -17,7 +17,7 @@ public class Parameters { ...@@ -17,7 +17,7 @@ public class Parameters {
public final static boolean uniform = false; public final static boolean uniform = false;
public final static String method = "Distmesh"; // "Distmesh" or "Density" public final static String method = "Distmesh"; // "Distmesh" or "Density"
public final static double qualityMeasurement = 0.95; public final static double qualityMeasurement = 0.95;
public final static double qualityConvergence = 0.001; public final static double qualityConvergence = 0.0;
public final static double MINIMUM = 0.25; public final static double MINIMUM = 0.25;
public final static double DENSITYWEIGHT = 2; public final static double DENSITYWEIGHT = 2;
public final static int NPOINTS = 100000; public final static int NPOINTS = 100000;
...@@ -25,5 +25,6 @@ public class Parameters { ...@@ -25,5 +25,6 @@ public class Parameters {
public final static int SAMPLEDIVISION = 10; public final static int SAMPLEDIVISION = 10;
public final static int SEGMENTDIVISION = 0; public final static int SEGMENTDIVISION = 0;
//TODO increase this //TODO increase this
public final static int MAX_NUMBER_OF_STEPS = 100; public final static int MAX_NUMBER_OF_STEPS = 200;
public final static int HIGHEST_LEGAL_TEST = Integer.MAX_VALUE;
} }
...@@ -3,12 +3,15 @@ package org.vadere.meshing.mesh.triangulation.improver.eikmesh.gen; ...@@ -3,12 +3,15 @@ package org.vadere.meshing.mesh.triangulation.improver.eikmesh.gen;
import org.apache.commons.lang3.tuple.Pair; import org.apache.commons.lang3.tuple.Pair;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.vadere.meshing.mesh.IllegalMeshException; import org.vadere.meshing.mesh.IllegalMeshException;
import org.vadere.meshing.mesh.inter.IEdgeContainerBoolean;
import org.vadere.meshing.mesh.inter.IFace; import org.vadere.meshing.mesh.inter.IFace;
import org.vadere.meshing.mesh.inter.IHalfEdge; import org.vadere.meshing.mesh.inter.IHalfEdge;
import org.vadere.meshing.mesh.inter.IMesh; import org.vadere.meshing.mesh.inter.IMesh;
import org.vadere.meshing.mesh.inter.IMeshSupplier; import org.vadere.meshing.mesh.inter.IMeshSupplier;
import org.vadere.meshing.mesh.inter.IIncrementalTriangulation; import org.vadere.meshing.mesh.inter.IIncrementalTriangulation;
import org.vadere.meshing.mesh.inter.IVertex; import org.vadere.meshing.mesh.inter.IVertex;
import org.vadere.meshing.mesh.inter.IVertexContainerBoolean;
import org.vadere.meshing.mesh.inter.IVertexContainerDouble;
import org.vadere.meshing.mesh.iterators.EdgeIterator; import org.vadere.meshing.mesh.iterators.EdgeIterator;
import org.vadere.meshing.mesh.iterators.EdgeIteratorReverse; import org.vadere.meshing.mesh.iterators.EdgeIteratorReverse;
import org.vadere.meshing.mesh.triangulation.improver.IMeshImprover; import org.vadere.meshing.mesh.triangulation.improver.IMeshImprover;
...@@ -129,6 +132,12 @@ public class GenEikMesh<V extends IVertex, E extends IHalfEdge, F extends IFace> ...@@ -129,6 +132,12 @@ public class GenEikMesh<V extends IVertex, E extends IHalfEdge, F extends IFace>
private static final String propVelocityY = "velocityY"; private static final String propVelocityY = "velocityY";
private static final String propAbsVelocity = "absVelocity"; private static final String propAbsVelocity = "absVelocity";
private final IVertexContainerBoolean<V, E, F> fixpointC;
private final IEdgeContainerBoolean<V, E, F> constraintC;
private final IVertexContainerDouble<V, E, F> velocityXC;
private final IVertexContainerDouble<V, E, F> velocityYC;
private final IVertexContainerDouble<V, E, F> absVelocityC;
/** /**
* Constructor to use EikMesh on an existing {@link org.vadere.meshing.mesh.inter.ITriangulation}, that is * Constructor to use EikMesh on an existing {@link org.vadere.meshing.mesh.inter.ITriangulation}, that is
* EikMesh uses this triangulation as a bases. It will refineSimplex2D the triangulation by using a longest edge * EikMesh uses this triangulation as a bases. It will refineSimplex2D the triangulation by using a longest edge
...@@ -177,6 +186,12 @@ public class GenEikMesh<V extends IVertex, E extends IHalfEdge, F extends IFace> ...@@ -177,6 +186,12 @@ public class GenEikMesh<V extends IVertex, E extends IHalfEdge, F extends IFace>
} }
this.useSlidingLines = true; this.useSlidingLines = true;
this.smoothBorder = false; this.smoothBorder = false;
this.fixpointC = triangulation.getMesh().getBooleanVertexContainer(propFixPoint);
this.constraintC = triangulation.getMesh().getBooleanEdgeContainer(propConstrained);
this.velocityXC = triangulation.getMesh().getDoubleVertexContainer(propVelocityX);
this.velocityYC = triangulation.getMesh().getDoubleVertexContainer(propVelocityY);
this.absVelocityC = triangulation.getMesh().getDoubleVertexContainer(propAbsVelocity);
} }
/** /**
...@@ -244,6 +259,12 @@ public class GenEikMesh<V extends IVertex, E extends IHalfEdge, F extends IFace> ...@@ -244,6 +259,12 @@ public class GenEikMesh<V extends IVertex, E extends IHalfEdge, F extends IFace>
this.useSlidingLines = false; this.useSlidingLines = false;
this.smoothBorder = true; this.smoothBorder = true;
this.fixpointC = triangulation.getMesh().getBooleanVertexContainer(propFixPoint);
this.constraintC = triangulation.getMesh().getBooleanEdgeContainer(propConstrained);
this.velocityXC = triangulation.getMesh().getDoubleVertexContainer(propVelocityX);
this.velocityYC = triangulation.getMesh().getDoubleVertexContainer(propVelocityY);
this.absVelocityC = triangulation.getMesh().getDoubleVertexContainer(propAbsVelocity);
} }
/** /**
...@@ -288,6 +309,12 @@ public class GenEikMesh<V extends IVertex, E extends IHalfEdge, F extends IFace> ...@@ -288,6 +309,12 @@ public class GenEikMesh<V extends IVertex, E extends IHalfEdge, F extends IFace>
initialEdgeLen, initialEdgeLen,
distanceFunc, distanceFunc,
generateFixPoints()); generateFixPoints());
this.fixpointC = refiner.getMesh().getBooleanVertexContainer(propFixPoint);
this.constraintC = refiner.getMesh().getBooleanEdgeContainer(propConstrained);
this.velocityXC = refiner.getMesh().getDoubleVertexContainer(propVelocityX);
this.velocityYC = refiner.getMesh().getDoubleVertexContainer(propVelocityY);
this.absVelocityC = refiner.getMesh().getDoubleVertexContainer(propAbsVelocity);
} }
public GenEikMesh( public GenEikMesh(
...@@ -337,6 +364,7 @@ public class GenEikMesh<V extends IVertex, E extends IHalfEdge, F extends IFace> ...@@ -337,6 +364,7 @@ public class GenEikMesh<V extends IVertex, E extends IHalfEdge, F extends IFace>
deps = 0.0001 * initialEdgeLen; deps = 0.0001 * initialEdgeLen;
computeFixPoints(); computeFixPoints();
refiner.getConstrains().forEach(e -> setConstraint(e, true));
if(useSlidingLines) { if(useSlidingLines) {
computeSlidingLines(); computeSlidingLines();
...@@ -549,7 +577,7 @@ public class GenEikMesh<V extends IVertex, E extends IHalfEdge, F extends IFace> ...@@ -549,7 +577,7 @@ public class GenEikMesh<V extends IVertex, E extends IHalfEdge, F extends IFace>
private void computeForce(final V vertex) { private void computeForce(final V vertex) {
// TODO: Get rid of IPoint // TODO: Get rid of IPoint
IPoint p1 = getMesh().getPoint(vertex); IPoint p1 = getMesh().getPoint(vertex);
boolean isAtBoundary = getMesh().isAtBoundary(vertex); boolean isAtBoundary = isBoundary(vertex);
for(E edge : getMesh().getEdgeIt(vertex)) { for(E edge : getMesh().getEdgeIt(vertex)) {
...@@ -623,6 +651,9 @@ public class GenEikMesh<V extends IVertex, E extends IHalfEdge, F extends IFace> ...@@ -623,6 +651,9 @@ public class GenEikMesh<V extends IVertex, E extends IHalfEdge, F extends IFace>
// TODO: Get rid of VPoint // TODO: Get rid of VPoint
VPoint p1p2 = p1.subtract(p2); VPoint p1p2 = p1.subtract(p2);
double len = p1p2.distanceToOrigin(); double len = p1p2.distanceToOrigin();
if(len <= GeometryUtils.DOUBLE_EPS) {
return new VPoint(0, 0);
}
double desiredLen = 0.9 * Math.sqrt(3) * getDesiredEdgeLength(p1, p2); double desiredLen = 0.9 * Math.sqrt(3) * getDesiredEdgeLength(p1, p2);
double ratio = len / desiredLen; double ratio = len / desiredLen;
double absForce = f.apply(ratio); double absForce = f.apply(ratio);
...@@ -765,6 +796,11 @@ public class GenEikMesh<V extends IVertex, E extends IHalfEdge, F extends IFace> ...@@ -765,6 +796,11 @@ public class GenEikMesh<V extends IVertex, E extends IHalfEdge, F extends IFace>
* @return true if the movement is legal, false otherwise * @return true if the movement is legal, false otherwise
*/ */
private boolean isLegalMove(@NotNull final V vertex, double newX, double newY) { private boolean isLegalMove(@NotNull final V vertex, double newX, double newY) {
// only test for early iterations!
if(nSteps > Parameters.HIGHEST_LEGAL_TEST) {
return true;
}
//if(vertex.distance(newX, newY) > GeometryUtils.DOUBLE_EPS) { //if(vertex.distance(newX, newY) > GeometryUtils.DOUBLE_EPS) {
// TODO: at the boundary vertices can still overtake each other. // TODO: at the boundary vertices can still overtake each other.
...@@ -810,7 +846,7 @@ public class GenEikMesh<V extends IVertex, E extends IHalfEdge, F extends IFace> ...@@ -810,7 +846,7 @@ public class GenEikMesh<V extends IVertex, E extends IHalfEdge, F extends IFace>
*/ */
private void updateFace(@NotNull F face) { private void updateFace(@NotNull F face) {
if(canBreak(face) && isBreaking(face)) { if(canBreak(face) && isBreaking(face)) {
VPoint circumcenter = getMesh().toTriangle(face).getCircumcenter(); VPoint circumcenter = getMesh().toCircumcenter(face);
getTriangulation().splitTriangle(face, getMesh().createPoint(circumcenter.getX(), circumcenter.getY()), false); getTriangulation().splitTriangle(face, getMesh().createPoint(circumcenter.getX(), circumcenter.getY()), false);
} }
} }
...@@ -854,9 +890,9 @@ public class GenEikMesh<V extends IVertex, E extends IHalfEdge, F extends IFace> ...@@ -854,9 +890,9 @@ public class GenEikMesh<V extends IVertex, E extends IHalfEdge, F extends IFace>
newPosition = new VPoint(v1.getX(), v1.getY()); newPosition = new VPoint(v1.getX(), v1.getY());
} else if(isFixPoint(v2)) { } else if(isFixPoint(v2)) {
newPosition = new VPoint(v2.getX(), v2.getY()); newPosition = new VPoint(v2.getX(), v2.getY());
} else if(getMesh().isAtBoundary(v1) || (isSlidePoint(v1) && !isSlidePoint(v2))) { } else if(isBoundary(v1) || (isSlidePoint(v1) && !isSlidePoint(v2))) {
newPosition = new VPoint(v1.getX(), v1.getY()); newPosition = new VPoint(v1.getX(), v1.getY());
} else if(getMesh().isAtBoundary(v2) || (isSlidePoint(v2) && !isSlidePoint(v1))) { } else if(isBoundary(v2) || (isSlidePoint(v2) && !isSlidePoint(v1))) {
newPosition = new VPoint(v2.getX(), v2.getY()); newPosition = new VPoint(v2.getX(), v2.getY());
} else { } else {
newPosition = new VPoint((v1.getX() + v2.getX()) * 0.5, (v1.getY() + v2.getY()) * 0.5); newPosition = new VPoint((v1.getX() + v2.getX()) * 0.5, (v1.getY() + v2.getY()) * 0.5);
...@@ -953,8 +989,9 @@ public class GenEikMesh<V extends IVertex, E extends IHalfEdge, F extends IFace> ...@@ -953,8 +989,9 @@ public class GenEikMesh<V extends IVertex, E extends IHalfEdge, F extends IFace>
if(faceToQuality(face) > 0.95) { if(faceToQuality(face) > 0.95) {
E edge = getMesh().getEdge(face); E edge = getMesh().getEdge(face);
if(edgeLengthFunc.apply(getMesh().toLine(edge).midPoint()) * 2.1 <= getMesh().toLine(edge).length()) { if(edgeLengthFunc.apply(getMesh().toLine(edge).midPoint()) * 2.1 <= getMesh().toLine(edge).length()) {
VPoint circumcenter = getMesh().toTriangle(face).getCircumcenter(); VPoint circumcenter = getMesh().toCircumcenter(face);
return getMesh().toTriangle(face).contains(circumcenter); return triangulation.contains(circumcenter.getX(), circumcenter.getY(), face);
//getMesh().toTriangle(face).contains(circumcenter);
} }
} }