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

add meshing examples.

parent 5068961f
Pipeline #72757 failed with stages
in 31 seconds
package org.vadere.meshing.examples;
import org.vadere.meshing.mesh.triangulation.IEdgeLengthFunction;
import org.vadere.util.geometry.GeometryUtils;
import org.vadere.meshing.mesh.gen.PFace;
import org.vadere.meshing.mesh.gen.PHalfEdge;
......@@ -11,6 +12,7 @@ import org.vadere.util.geometry.shapes.VPoint;
import org.vadere.util.geometry.shapes.VPolygon;
import org.vadere.util.geometry.shapes.VRectangle;
import org.vadere.util.geometry.shapes.VShape;
import org.vadere.util.math.IDistanceFunction;
import java.util.ArrayList;
import java.util.List;
......@@ -24,7 +26,20 @@ import javax.swing.*;
public class EikMeshExamples {
public static void main(String... args) {
uniformMeshDiscFunction();
uniformMeshRingFunction();
combineDistanceFunctions();
edgeLengthFunction();
edgeLengthAndDistanceFunction();
}
/**
* This examples shows how to mesh a geometry that is defined by shapes ({@link VShape}), i.e. the boundary is
* defined by a rectangle ({@link VPolygon}) and holes (areas which are excluded from the actual meshing region)
* are defined by shapes, here a {@link VRectangle}. The edgeLength is a measure for the approximate edge lengths
* of all edges since it is a uniform triangulation, i.e. the desired edge length function is a constant.
*/
public static void uniformMeshShapes() {
// define a bounding box
VPolygon boundary = GeometryUtils.polygonFromPoints2D(
new VPoint(0,0),
......@@ -39,9 +54,10 @@ public class EikMeshExamples {
obstacleShapes.add(rect);
// define the EikMesh-Improver
double edgeLength = 0.1;
PEikMesh meshImprover = new PEikMesh(
boundary,
0.1,
edgeLength,
obstacleShapes);
// (optional) define the gui to display the mesh
......@@ -53,6 +69,180 @@ public class EikMeshExamples {
meshImprover.generate();
// display the mesh
meshPanel.display();
meshPanel.display("Geometry defined by shapes");
}
/**
* This examples shows how to mesh a geometry that is defined by a {@link org.vadere.util.math.IDistanceFunction}.
* The distance function has to be negative for all points inside the meshing area and positive for all other points.
* Furthermore the distance function should be differentiable. Here the distance functions defines a disc at (1,1) with radius 1.
* Additionally, the meshing algorithm requires a bound {@link VRectangle}, which contains the whole meshing area.
* The edgeLength is a measure for the approximate edge lengths of all edges since it is a uniform triangulation,
* i.e. the desired edge length function is a constant.
*/
public static void uniformMeshDiscFunction() {
// define a bounding box
VRectangle bound = new VRectangle(-0.1, -0.1, 2.2, 2.2);
// distance function that defines a disc with radius 1 at (1,1).
IDistanceFunction discDistance = IDistanceFunction.createDisc(1, 1, 1.0);
// define the EikMesh-Improver
double edgeLength = 0.1;
PEikMesh meshImprover = new PEikMesh(
discDistance,
edgeLength,
bound);
// (optional) define the gui to display the mesh
MeshPanel<EikMeshPoint, PVertex<EikMeshPoint>, PHalfEdge<EikMeshPoint>, PFace<EikMeshPoint>> meshPanel = new MeshPanel<>(
meshImprover.getMesh(), 1000, 800,
bound);
// generate the mesh
meshImprover.generate();
// display the mesh
meshPanel.display("Geometry defined by a distance function (disc)");
}
/**
* This examples shows how to mesh a geometry that is defined by a {@link org.vadere.util.math.IDistanceFunction}.
* The distance function has to be negative for all points inside the meshing area and positive for all other points.
* Furthermore the distance function should be differentiable. Here the distance functions defines a ring at (1,1)
* with inner-radius 0.2, and outer-radius 1.0. Additionally, the meshing algorithm requires a bound {@link VRectangle},
* which contains the whole meshing area. The edgeLength is a measure for the approximate edge lengths of all edges
* since it is a uniform triangulation, i.e. the desired edge length function is a constant.
*/
public static void uniformMeshRingFunction() {
// define a bounding box
VRectangle bound = new VRectangle(-0.1, -0.1, 2.2, 2.2);
// distance function that defines a ring with inner-radius 0.2 and outer-radius 1 at (1,1).
IDistanceFunction ringDistance = IDistanceFunction.createRing(1, 1, 0.2, 1.0);
// define the EikMesh-Improver
double edgeLength = 0.1;
PEikMesh meshImprover = new PEikMesh(
ringDistance,
edgeLength,
bound);
// (optional) define the gui to display the mesh
MeshPanel<EikMeshPoint, PVertex<EikMeshPoint>, PHalfEdge<EikMeshPoint>, PFace<EikMeshPoint>> meshPanel = new MeshPanel<>(
meshImprover.getMesh(), 1000, 800,
bound);
// generate the mesh
meshImprover.generate();
// display the mesh
meshPanel.display("Geometry defined by a distance function (ring)");
}
/**
* This example illustrate how one can combine distance functions ({@link IDistanceFunction}). Here we subtract
* from a disc at (1, 1) with radius 1 another disc at (1, 1) with radius 0.2. The result is the a ring of
* example {@link EikMeshExamples#uniformMeshRingFunction}.
*/
public static void combineDistanceFunctions() {
// define a bounding box
VRectangle bound = new VRectangle(-0.1, -0.1, 2.2, 2.2);
// distance function that defines a ring with inner-radius 0.2 and outer-radius 1 at (1,1).
IDistanceFunction innerDisc = IDistanceFunction.createDisc(1, 1, 0.2);
IDistanceFunction outerDisc = IDistanceFunction.createDisc(1, 1, 1.0);
IDistanceFunction ringDistance = IDistanceFunction.substract(outerDisc, innerDisc);
// define the EikMesh-Improver
double edgeLength = 0.1;
PEikMesh meshImprover = new PEikMesh(
ringDistance,
edgeLength,
bound);
// (optional) define the gui to display the mesh
MeshPanel<EikMeshPoint, PVertex<EikMeshPoint>, PHalfEdge<EikMeshPoint>, PFace<EikMeshPoint>> meshPanel = new MeshPanel<>(
meshImprover.getMesh(), 1000, 800,
bound);
// generate the mesh
meshImprover.generate();
// display the mesh
meshPanel.display("Combination of distance functions");
}
/**
* This example is equal to {@link EikMeshExamples#uniformMeshRingFunction} but we use a so called
* desired relative edge length function. The minimum of the edge length function should be equals 1.0.
* The algorithm will produce edge length approximately as large as: edgeLength times edgeLengthFunction.apply(p),
* where p is the midpoint of the edge. Here the edge length depend on the x-coordinate, i.e. edges to the right
* will be larger.
*/
public static void edgeLengthFunction() {
// define a bounding box
VRectangle bound = new VRectangle(-0.1, -0.1, 2.2, 2.2);
// distance function that defines a ring with inner-radius 0.2 and outer-radius 1 at (1,1).
IDistanceFunction ringDistance = IDistanceFunction.createRing(1, 1, 0.2, 1.0);
IEdgeLengthFunction edgeLengthFunction = p -> 1.0 + p.getX();
// define the EikMesh-Improver
double edgeLength = 0.05;
PEikMesh meshImprover = new PEikMesh(
ringDistance,
edgeLengthFunction,
edgeLength,
bound);
// (optional) define the gui to display the mesh
MeshPanel<EikMeshPoint, PVertex<EikMeshPoint>, PHalfEdge<EikMeshPoint>, PFace<EikMeshPoint>> meshPanel = new MeshPanel<>(
meshImprover.getMesh(), 1000, 800,
bound);
// generate the mesh
meshImprover.generate();
// display the mesh
meshPanel.display("Edge length function");
}
/**
* This example is equal to {@link EikMeshExamples#edgeLengthFunction} but the desired relative edge length depends
* on the {@link IDistanceFunction}, i.e. we combine those two functions. Here we want the edges close to the boundary
* to be smaller. Since the distance function is negative inside the meshing area and the edge length function should never
* be smaller than 1 we add the absolute value of the distance. The factor variable controls how 'fast' the edge length
* will increase with the distance.
*/
public static void edgeLengthAndDistanceFunction() {
// define a bounding box
VRectangle bound = new VRectangle(-0.1, -0.1, 2.2, 2.2);
// distance function that defines a ring with inner-radius 0.2 and outer-radius 1 at (1,1).
IDistanceFunction ringDistance = IDistanceFunction.createRing(1, 1, 0.2, 1.0);
final double factor = 6.0;
IEdgeLengthFunction edgeLengthFunction = p -> 1.0 + factor * Math.abs(ringDistance.apply(p));
// define the EikMesh-Improver
double edgeLength = 0.05;
PEikMesh meshImprover = new PEikMesh(
ringDistance,
edgeLengthFunction,
edgeLength,
bound);
// (optional) define the gui to display the mesh
MeshPanel<EikMeshPoint, PVertex<EikMeshPoint>, PHalfEdge<EikMeshPoint>, PFace<EikMeshPoint>> meshPanel = new MeshPanel<>(
meshImprover.getMesh(), 1000, 800,
bound);
// generate the mesh
meshImprover.generate();
// display the mesh
meshPanel.display("Distance dependent edge lengths");
}
}
......@@ -204,10 +204,14 @@ public class MeshPanel<P extends IPoint, V extends IVertex<P>, E extends IHalfEd
}
public JFrame display() {
return display("Mesh");
}
public JFrame display(final String title) {
JFrame jFrame = new JFrame();
jFrame.setSize((int)width+10, (int)height+10);
jFrame.add(this);
jFrame.setTitle("Mesh");
jFrame.setTitle(title);
jFrame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
setVisible(true);
jFrame.setVisible(true);
......
......@@ -28,6 +28,7 @@ import org.vadere.meshing.mesh.triangulation.IEdgeLengthFunction;
import java.awt.geom.Rectangle2D;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
......@@ -56,7 +57,6 @@ public class EikMesh<P extends EikMeshPoint, V extends IVertex<P>, E extends IHa
private boolean profiling = false;
private double minDeltaTravelDistance = 0.0;
private double delta = Parameters.DELTAT;
private final Collection<? extends VShape> obstacleShapes;
private List<V> collapseVertices;
private List<E> splitEdges;
......@@ -76,7 +76,6 @@ public class EikMesh<P extends EikMeshPoint, V extends IVertex<P>, E extends IHa
this.edgeLengthFunc = edgeLengthFunc;
this.initialEdgeLen =initialEdgeLen;
this.deps = 0.00001 * initialEdgeLen;
this.obstacleShapes = obstacleShapes;
this.nSteps = 0;
this.collapseVertices = new ArrayList<>();
this.splitEdges = new ArrayList<>();
......@@ -95,6 +94,15 @@ public class EikMesh<P extends EikMeshPoint, V extends IVertex<P>, E extends IHa
log.info("##### (end) generate a triangulation #####");
}
public EikMesh(
final IDistanceFunction distanceFunc,
final IEdgeLengthFunction edgeLengthFunc,
final double initialEdgeLen,
final VRectangle bound,
final IMeshSupplier<P, V, E, F> meshSupplier) {
this(distanceFunc, edgeLengthFunc, initialEdgeLen, bound, Collections.EMPTY_LIST, meshSupplier);
}
public EikMesh(final VPolygon boundary,
final double initialEdgeLen,
final Collection<? extends VShape> obstacleShapes,
......@@ -107,7 +115,6 @@ public class EikMesh<P extends EikMeshPoint, V extends IVertex<P>, E extends IHa
this.edgeLengthFunc = p -> 1.0;
this.initialEdgeLen =initialEdgeLen;
this.deps = 0.00001 * initialEdgeLen;
this.obstacleShapes = obstacleShapes;
this.nSteps = 0;
this.collapseVertices = new ArrayList<>();
this.splitEdges = new ArrayList<>();
......
......@@ -29,6 +29,25 @@ public class PEikMesh extends EikMesh<EikMeshPoint, PVertex<EikMeshPoint>, PHalf
() -> new PMesh<>((x, y) -> new EikMeshPoint(x, y, false)));
}
public PEikMesh(
@NotNull IDistanceFunction distanceFunc,
@NotNull IEdgeLengthFunction edgeLengthFunc,
double initialEdgeLen,
@NotNull VRectangle bound) {
super(distanceFunc, edgeLengthFunc, initialEdgeLen, bound,
() -> new PMesh<>((x, y) -> new EikMeshPoint(x, y, false)));
}
public PEikMesh(
@NotNull IDistanceFunction distanceFunc,
double initialEdgeLen,
@NotNull VRectangle bound) {
super(distanceFunc, e -> 1.0, initialEdgeLen, bound,
() -> new PMesh<>((x, y) -> new EikMeshPoint(x, y, false)));
}
public PEikMesh(
@NotNull VPolygon polygon,
double initialEdgeLen,
......
......@@ -21,6 +21,25 @@ import java.util.function.Function;
@FunctionalInterface
public interface IDistanceFunction extends Function<IPoint, Double> {
static IDistanceFunction createRing(final double xCenter, final double yCenter, final double innerRadius, final double outerRadius) {
final double x1 = (outerRadius + innerRadius) / 2.0;
final double x2 = (outerRadius - innerRadius) / 2.0;
return p -> {
double dx = p.getX() - xCenter;
double dy = p.getY() - yCenter;
double len = Math.sqrt(dx * dx + dy * dy);
return Math.abs(len - x1) - x2;
};
}
static IDistanceFunction createDisc(final double xCenter, final double yCenter, final double radius) {
return p -> {
double dx = p.getX() - xCenter;
double dy = p.getY() - yCenter;
return Math.sqrt(dx * dx + dy * dy) - radius;
};
}
static IDistanceFunction create(final VRectangle regionBoundingBox, final Collection<? extends VShape> obstacles) {
return new DistanceFunction(regionBoundingBox, obstacles);
}
......@@ -41,6 +60,10 @@ public interface IDistanceFunction extends Function<IPoint, Double> {
return p -> Math.max(dist1.apply(p), dist2.apply(p));
}
static IDistanceFunction substract(final IDistanceFunction dist1, final IDistanceFunction dist2) {
return p -> Math.max(dist1.apply(p), -dist2.apply(p));
}
default double doDDiff(double d1, double d2)
{
return Math.max(d1, -d2);
......
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