Notice to GitKraken users: A vulnerability has been found in the SSH key generation of GitKraken versions 7.6.0 to 8.0.0 (https://www.gitkraken.com/blog/weak-ssh-key-fix). If you use GitKraken and have generated a SSH key using one of these versions, please remove it both from your local workstation and from your LRZ GitLab profile.

21.10.2021, 9:00 - 11:00: Due to updates GitLab may be unavailable for some minutes between 09:00 and 11:00.

Commit 1c5e5874 authored by Benedikt Zoennchen's avatar Benedikt Zoennchen
Browse files

construct a new module called geometry and extracting the classes from the utils module.

parent 35ebbaa9
package org.vadere.util.geometry.mesh.impl;
package org.vadere.geometry.mesh.impl;
import org.jetbrains.annotations.NotNull;
import org.vadere.util.geometry.mesh.gen.PHalfEdge;
import org.vadere.util.geometry.shapes.VPoint;
import org.vadere.geometry.mesh.gen.PHalfEdge;
import org.vadere.geometry.shapes.VPoint;
/**
* @author Benedikt Zoennchen
......
package org.vadere.util.geometry.mesh.impl;
package org.vadere.geometry.mesh.impl;
import org.vadere.util.geometry.mesh.gen.PMesh;
import org.vadere.util.geometry.shapes.VPoint;
import org.vadere.geometry.mesh.gen.PMesh;
import org.vadere.geometry.shapes.VPoint;
/**
* @author Benedikt Zoennchen
......
package org.vadere.util.geometry.mesh.impl;
package org.vadere.geometry.mesh.impl;
import org.jetbrains.annotations.NotNull;
import org.vadere.util.geometry.mesh.inter.IPointLocator;
import org.vadere.util.geometry.mesh.gen.IncrementalTriangulation;
import org.vadere.util.geometry.mesh.gen.PFace;
import org.vadere.util.geometry.mesh.gen.PHalfEdge;
import org.vadere.util.geometry.mesh.gen.PVertex;
import org.vadere.util.geometry.shapes.VPoint;
import org.vadere.util.geometry.shapes.VRectangle;
import org.vadere.geometry.mesh.inter.IPointLocator;
import org.vadere.geometry.mesh.gen.IncrementalTriangulation;
import org.vadere.geometry.mesh.gen.PFace;
import org.vadere.geometry.mesh.gen.PHalfEdge;
import org.vadere.geometry.mesh.gen.PVertex;
import org.vadere.geometry.shapes.VPoint;
import org.vadere.geometry.shapes.VRectangle;
import java.util.Collection;
import java.util.Set;
......
package org.vadere.util.geometry.mesh.impl;
package org.vadere.geometry.mesh.impl;
import org.vadere.util.geometry.mesh.gen.PFace;
import org.vadere.util.geometry.mesh.gen.PHalfEdge;
import org.vadere.util.geometry.mesh.gen.PVertex;
import org.vadere.util.geometry.mesh.inter.ITriangulationSupplier;
import org.vadere.util.geometry.mesh.triangulation.triangulator.UniformRefinementTriangulator;
import org.vadere.util.geometry.shapes.VPoint;
import org.vadere.util.geometry.shapes.VRectangle;
import org.vadere.util.geometry.shapes.VShape;
import org.vadere.util.geometry.mesh.triangulation.adaptive.IEdgeLengthFunction;
import org.vadere.geometry.mesh.gen.PFace;
import org.vadere.geometry.mesh.gen.PHalfEdge;
import org.vadere.geometry.mesh.gen.PVertex;
import org.vadere.geometry.mesh.inter.ITriangulationSupplier;
import org.vadere.geometry.mesh.triangulation.triangulator.UniformRefinementTriangulator;
import org.vadere.geometry.shapes.VPoint;
import org.vadere.geometry.shapes.VRectangle;
import org.vadere.geometry.shapes.VShape;
import org.vadere.geometry.mesh.triangulation.adaptive.IEdgeLengthFunction;
import java.util.Collection;
......
package org.vadere.util.geometry.mesh.impl;
package org.vadere.geometry.mesh.impl;
import org.vadere.util.geometry.mesh.gen.PVertex;
import org.vadere.util.geometry.shapes.VPoint;
import org.vadere.geometry.mesh.gen.PVertex;
import org.vadere.geometry.shapes.VPoint;
/**
* @author Benedikt Zoennchen
......
package org.vadere.util.geometry.mesh.inter;
package org.vadere.geometry.mesh.inter;
import org.vadere.util.geometry.shapes.IPoint;
import org.vadere.geometry.shapes.IPoint;
/**
* A face {@link IFace} is a generic 2D-face i.e. a polygon consisting of points of type {@link P}
* and is part of the half-edge data structure. A 2D-face is defined by its half-edges {@link IHalfEdge}
* and their twins {@link IHalfEdge}. Half-edges are counter-clockwise oriented.
* and their twins {@link IHalfEdge}. Half-edges have to be counter-clockwise oriented.
*
* The face might be a boundary face i.e. border or hole.
*
......
package org.vadere.util.geometry.mesh.inter;
package org.vadere.geometry.mesh.inter;
import org.vadere.util.geometry.shapes.IPoint;
import org.vadere.geometry.shapes.IPoint;
/**
* A half-edge {@link IHalfEdge} is part of a specific face and one part of a full-edge the other
......
package org.vadere.util.geometry.mesh.inter;
package org.vadere.geometry.mesh.inter;
import com.google.common.collect.Iterators;
import com.google.common.collect.Lists;
import org.apache.commons.lang3.tuple.Triple;
import org.jetbrains.annotations.NotNull;
import org.vadere.util.geometry.GeometryUtils;
import org.vadere.util.geometry.mesh.gen.PFace;
import org.vadere.util.geometry.mesh.gen.PHalfEdge;
import org.vadere.util.geometry.mesh.gen.PMesh;
import org.vadere.util.geometry.mesh.gen.PVertex;
import org.vadere.util.geometry.mesh.iterators.AdjacentVertexIterator;
import org.vadere.util.geometry.mesh.iterators.EdgeIterator;
import org.vadere.util.geometry.mesh.iterators.AdjacentFaceIterator;
import org.vadere.util.geometry.mesh.iterators.EdgeOfVertexIterator;
import org.vadere.util.geometry.mesh.iterators.IncidentEdgeIterator;
import org.vadere.util.geometry.mesh.iterators.PointIterator;
import org.vadere.util.geometry.mesh.iterators.SurroundingFaceIterator;
import org.vadere.util.geometry.mesh.iterators.VertexIterator;
import org.vadere.util.geometry.shapes.IPoint;
import org.vadere.util.geometry.shapes.VLine;
import org.vadere.util.geometry.shapes.VPoint;
import org.vadere.util.geometry.shapes.VPolygon;
import org.vadere.util.geometry.shapes.VTriangle;
import org.vadere.geometry.Utils;
import org.vadere.geometry.mesh.gen.PFace;
import org.vadere.geometry.mesh.gen.PHalfEdge;
import org.vadere.geometry.mesh.gen.PMesh;
import org.vadere.geometry.mesh.gen.PVertex;
import org.vadere.geometry.mesh.iterators.AdjacentVertexIterator;
import org.vadere.geometry.mesh.iterators.EdgeIterator;
import org.vadere.geometry.mesh.iterators.AdjacentFaceIterator;
import org.vadere.geometry.mesh.iterators.EdgeOfVertexIterator;
import org.vadere.geometry.mesh.iterators.IncidentEdgeIterator;
import org.vadere.geometry.mesh.iterators.PointIterator;
import org.vadere.geometry.mesh.iterators.SurroundingFaceIterator;
import org.vadere.geometry.mesh.iterators.VertexIterator;
import org.vadere.geometry.shapes.IPoint;
import org.vadere.geometry.shapes.VLine;
import org.vadere.geometry.shapes.VPoint;
import org.vadere.geometry.shapes.VPolygon;
import org.vadere.geometry.shapes.VTriangle;
import java.awt.geom.Path2D;
import java.util.ArrayList;
......@@ -39,50 +39,66 @@ import java.util.stream.Stream;
import java.util.stream.StreamSupport;
/**
* <p>
* A {@link IMesh} is a set of {@link IFace}, their half-edges {@link IHalfEdge}, vertices {@link IVertex<P>} and points {@link P}
* defining a geometry. It also is a factory for those geometric base elements: points, vertices, half-edges and faces. The user should use one mesh
* for exactly one geometric and the user should never create any base element without calling its mesh. Furthermore, the user is responsible for the
* correctness of the mesh definition e.g. no overlapping edges. There are some classes for automatic mesh generation like
* {@link org.vadere.util.geometry.mesh.triangulation.triangulator.ITriangulator} or other factory methods like {@link IMesh#createSimpleTriMesh}
*
* It uses the half-edge data structure to store all information and is a generic interface to provide different implementations such as:
*
* a) A pointer based version which implements a doubled-linked-list data structure {@link org.vadere.util.geometry.mesh.gen.PMesh}
* b) A index based version which implements an array data structure {@link org.vadere.util.geometry.mesh.gen.AMesh}
*
* {@link org.vadere.geometry.mesh.triangulation.triangulator.ITriangulator} or other factory methods like {@link IMesh#createSimpleTriMesh}
* </p>
* <p>It uses the half-edge data structure to store all information and is a generic interface to provide different implementations such as:
* <ul>
* <li>A pointer based version which implements a doubled-linked-list data structure {@link org.vadere.geometry.mesh.gen.PMesh}</li>
* <li>An index based version which implements an array data structure {@link org.vadere.geometry.mesh.gen.AMesh}</li>
* </ul>
* </p>
* <p>
* It should be impossible to create faces, edges, and vertices of the mesh without using the mesh i.e. IMesh is a factory for faces, edges and vertices.
* A boundary can be a hole or the border. A hole is surrounded by faces and the border is the infinite large face representing the space which is not
* part of any finite face.
*
* </p>
* <p>
* For all iterators and stream usage it should be clear that if one manipulates the mesh during iteration the result is not clear. Therefore, use those
* iterators and streams only if no manipulation is done while iterating. If you want to manipulate the data structure, construct a list {@link List} beforehand and
* iterate over the list {@link List} while changing elements in the mesh. The mesh offers a large set of different iterators and streams to iterate over all neighbouring
* faces of a face, vertices of a vertex, edges of a vertex or over all edges / vertices / points of a face.
*
* We define as base elements: points {@link P}, vertices {@link V}, half-edges {@link E} and faces {@link F}.
*
* point {@link P}:
* A point is a container object which can be identified by its 2-D coordinates (x,y) and is part of a vertex {@link V}. A point has no reference to
* any other base element of the mesh data structure.
*
* vertex {@link V}: A vertex is the end node / point of a half-edge. Each vertex has exactly one distinct point {@link P}. One can access the point
* of a vertex in O(1). A vertex has also a 1 to 1 relation to a half-edge and the half-edge of a vertex can accessed in O(1) time. Furthermore, it has
* a reference to one arbitrary of its half-edges (half-edges ending in it). If the vertex is at the boundary (hole or border) the half-edge should be
* a boundary half-edge but this is not guaranteed but the aim is to have this situation as often as possible to have quick access to boundary half-edges
* to quickly check if the vertex is a boundary vertex! Note that an arbitrary neighbouring face of the vertex can also be accessed in O(1) by fist getting
* its half-edge and extracting from the half-edge the face.
*
* half-edge {@link E}: A half-edge is part of a full-edge i.e. the half-edge and its twin fully define the full-edge. Each half-edge has a predecessor
* and a successor and a twin half-edge {@link E} which can be accessed in O(1). Furthermore, each half-edge is part of exactly one face {@link F} and ends
* in exactly one vertex {@link V} both can be accessed in O(1) time. As one can see the half-edge has the most amount of references (5).
*
* face {@link F}: A face can be a interior face i.e. a simple polygon, a hole (also a polygon but representing empty space) or the border i.e. the infinite
* face which represents all the space which is not represented by any finite face. An arbitrary half-edge {@link E} can be accessed in O(1).
*
* </p>
* <p>
* We define as base elements: points {@link P}, vertices {@link V}, half-edges {@link E} and faces {@link F}.
* <ul>
* <li>
* point {@link P}: </br>
* A point is a container object which can be identified by its 2-D coordinates (x,y) and is part of a vertex {@link V}. A point has no reference to
* any other base element of the mesh data structure.
* </li>
* <li>
* vertex {@link V}: </br>
* A vertex is the end node / point of a half-edge. Each vertex has exactly one distinct point {@link P}. One can access the point
* of a vertex in O(1). A vertex has also a 1 to 1 relation to a half-edge and the half-edge of a vertex can accessed in O(1) time. Furthermore, it has
* a reference to one arbitrary of its half-edges (half-edges ending in it). If the vertex is at the boundary (hole or border) the half-edge should be
* a boundary half-edge but this is not guaranteed but the aim is to have this situation as often as possible to have quick access to boundary half-edges
* to quickly check if the vertex is a boundary vertex! Note that an arbitrary neighbouring face of the vertex can also be accessed in O(1) by fist getting
* its half-edge and extracting from the half-edge the face.
* </li>
* <li>
* half-edge {@link E}: </br>
* A half-edge is part of a full-edge i.e. the half-edge and its twin fully define the full-edge. Each half-edge has a predecessor
* and a successor and a twin half-edge {@link E} which can be accessed in O(1). Furthermore, each half-edge is part of exactly one face {@link F} and ends
* in exactly one vertex {@link V} both can be accessed in O(1) time. As one can see the half-edge has the most amount of references (5).
* </li>
* <li>
* face {@link F}: </br>
* A face can be a interior face i.e. a simple polygon, a hole (also a polygon but representing empty space) or the border i.e. the infinite
* face which represents all the space which is not represented by any finite face. An arbitrary half-edge {@link E} can be accessed in O(1).
* </li>
* </ul>
* </p>
* <p>
* We say a half-edge is a boundary / border / hole edge if it is part of a boundary / hole or the border. A boundary can be a hole or the border (there is only one border).
* We say a half-edge is at the boundary / border / hole if itself is a boundary / border / hole edge or its twin. Therefore a boundary / border / hole edge is via definition
* at the boundary / hole / border. Sometimes we say edge instead of half-edge but we try to use full-edge if we explicitly talk about the edge defined by the half-edge and
* its twin.
* </p>
*
* @author Benedikt Zoennchen
*
......@@ -240,7 +256,7 @@ public interface IMesh<P extends IPoint, V extends IVertex<P>, E extends IHalfEd
// TODO: this is for the delaunay-hierarchy only!
/**
* This is specifically used by {@link org.vadere.util.geometry.mesh.gen.DelaunayHierarchy<P, V, E, F>}
* This is specifically used by {@link org.vadere.geometry.mesh.gen.DelaunayHierarchy<P, V, E, F>}
* to establish the link of the different hierarchies in O(1).
*
* @param v a vertex of hierarchy k
......@@ -250,7 +266,7 @@ public interface IMesh<P extends IPoint, V extends IVertex<P>, E extends IHalfEd
// TODO: this is for the delaunay-hierarchy only!
/**
* This is specifically used by {@link org.vadere.util.geometry.mesh.gen.DelaunayHierarchy<P, V, E, F>}
* This is specifically used by {@link org.vadere.geometry.mesh.gen.DelaunayHierarchy<P, V, E, F>}
* to establish the link of the different hierarchies. Connects two vertices up and down such that
* up is at the hierarchy k and down is at hierarchy k+1 in O(1).
*
......@@ -717,6 +733,18 @@ public interface IMesh<P extends IPoint, V extends IVertex<P>, E extends IHalfEd
*/
void insertVertex(@NotNull final V vertex);
/**
* Inserts the point into the mesh data structure, returning its vertex
*
* @param point
* @return the vertex of the point
*/
default V insertPoint(final P point) {
V vertex = createVertex(point);
insertVertex(vertex);
return vertex;
}
/**
* Inserts the vertex into the mesh data structure.
*
......@@ -833,7 +861,7 @@ public interface IMesh<P extends IPoint, V extends IVertex<P>, E extends IHalfEd
* @return a face
*/
default F toFace(@NotNull final List<P> points) {
return createFace(points.stream().map(p -> createVertex(p)).collect(Collectors.toList()));
return createFace(points.stream().map(p -> insertPoint(p)).collect(Collectors.toList()));
}
/**
......@@ -944,7 +972,7 @@ public interface IMesh<P extends IPoint, V extends IVertex<P>, E extends IHalfEd
* Returns a parallel stream {@link Stream} of (all alive) interior faces. Note that the required synchronization has to
* be done by the user.
*
* @return a parallel stream {@link Stream<} of (all alive) interior faces
* @return a parallel stream {@link Stream} of (all alive) interior faces
*/
default Stream<F> streamFacesParallel() {
return streamFaces(f -> true).parallel();
......@@ -1692,7 +1720,7 @@ public interface IMesh<P extends IPoint, V extends IVertex<P>, E extends IHalfEd
E result = null;
double minDistance = Double.MAX_VALUE;
for (E edge : getEdgeIt(face)) {
double distance = GeometryUtils.distanceToLineSegment(getPoint(getPrev(edge)), getPoint(edge), x, y);
double distance = Utils.distanceToLineSegment(getPoint(getPrev(edge)), getPoint(edge), x, y);
if(distance < minDistance) {
result = edge;
minDistance = distance;
......
package org.vadere.util.geometry.mesh.inter;
package org.vadere.geometry.mesh.inter;
import org.vadere.util.geometry.shapes.IPoint;
import org.vadere.geometry.shapes.IPoint;
import java.util.function.Supplier;
......
package org.vadere.util.geometry.mesh.inter;
package org.vadere.geometry.mesh.inter;
import org.vadere.util.geometry.shapes.IPoint;
import org.vadere.util.geometry.shapes.VPoint;
import org.vadere.geometry.shapes.IPoint;
import org.vadere.geometry.shapes.VPoint;
@FunctionalInterface
public interface IPointConstructor<P extends IPoint> {
......
package org.vadere.util.geometry.mesh.inter;
package org.vadere.geometry.mesh.inter;
import org.vadere.util.geometry.shapes.IPoint;
import java.util.Collection;
import org.vadere.geometry.shapes.IPoint;
import java.util.Optional;
/**
* <p>
* A point-locator {@link IPointLocator} implements one of the strategies to find a specific triangle
* represented by a face {@link F} inside a mesh {@link ITriangulation}. i.e. a set of connected non-overlapping
* triangles including holes. The most famous strategies are so called triangle walks described in:
*
* + Walking in a Triangulation (devillers-2001)
* + The Delaunay Hierarchy (devillers-2002)
* + Fast randomized point location without preprocessing in two- and three-dimensional Delaunay triangulations (mucke-1999)
* + The Delaunay Tree see Computational Geometry: Algorithms and Applications (berg-2008) page 191
* <ul>
* <li>Walking in a Triangulation (devillers-2001)</li>
* <li>The Delaunay Hierarchy (devillers-2002)</li>
* <li>Fast randomized point location without preprocessing in two- and three-dimensional Delaunay triangulations (mucke-1999)</li>
* <li>The Delaunay Tree see Computational Geometry: Algorithms and Applications (berg-2008) page 191</li>
* </ul>
* </p>
*
* @author Benedikt Zoennchen
*
......
package org.vadere.util.geometry.mesh.inter;
package org.vadere.geometry.mesh.inter;
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.gen.IncrementalTriangulation;
import org.vadere.util.geometry.mesh.iterators.EdgeIterator;
import org.vadere.util.geometry.shapes.IPoint;
import org.vadere.geometry.Utils;
import org.vadere.geometry.mesh.gen.IncrementalTriangulation;
import org.vadere.geometry.mesh.iterators.EdgeIterator;
import org.vadere.geometry.shapes.IPoint;
import java.util.ArrayList;
import java.util.HashSet;
......@@ -17,12 +17,14 @@ import java.util.function.Predicate;
import java.util.stream.Collectors;
/**
* <p>
* A poly-connectivity {@link IPolyConnectivity} is the connectivity of a mesh of non-intersecting connected polygons including holes.
* So it is more abstract than a tri-connectivity {@link ITriConnectivity}. The mesh {@link IMesh} stores all the
* date of the base elements (points {@link P}, vertices {@link V}, half-edges {@link E} and faces {@link F}) and offers factory method
* to create new base elements. The connectivities, i.e. {@link IPolyConnectivity} and {@link ITriConnectivity}
* offers all the operations manipulating the connectivity of the mesh. The connectivity is the relation between vertices and edges which
* define faces which therefore define the mesh structure.
* </p>
*
* @param <P> the type of the points (containers)
* @param <V> the type of the vertices
......@@ -748,7 +750,7 @@ public interface IPolyConnectivity<P extends IPoint, V extends IVertex<P>, E ext
default boolean isRightOf(final double x1, final double y1, final E edge) {
V v1 = getMesh().getVertex(getMesh().getPrev(edge));
V v2 = getMesh().getVertex(edge);
return GeometryUtils.isRightOf(v1.getX(), v1.getY(), v2.getX(), v2.getY(), x1, y1);
return Utils.isRightOf(v1.getX(), v1.getY(), v2.getX(), v2.getY(), x1, y1);
}
/**
......@@ -765,7 +767,7 @@ public interface IPolyConnectivity<P extends IPoint, V extends IVertex<P>, E ext
default boolean isLeftOf(final double x1, final double y1, final E edge) {
V v1 = getMesh().getVertex(getMesh().getPrev(edge));
V v2 = getMesh().getVertex(edge);
return GeometryUtils.isLeftOf(v1.getX(), v1.getY(), v2.getX(), v2.getY(), x1, y1);
return Utils.isLeftOf(v1.getX(), v1.getY(), v2.getX(), v2.getY(), x1, y1);
}
/**
......@@ -781,7 +783,7 @@ public interface IPolyConnectivity<P extends IPoint, V extends IVertex<P>, E ext
default boolean intersects(final IPoint p1, final IPoint p2, E edge) {
V v1 = getMesh().getVertex(getMesh().getPrev(edge));
V v2 = getMesh().getVertex(edge);
return GeometryUtils.intersectLine(p1.getX(), p1.getY(), p2.getX(), p2.getY(), v1.getX(), v1.getY(), v2.getX(), v2.getY());
return Utils.intersectLine(p1.getX(), p1.getY(), p2.getX(), p2.getY(), v1.getX(), v1.getY(), v2.getX(), v2.getY());
}
......
package org.vadere.util.geometry.mesh.inter;
package org.vadere.geometry.mesh.inter;
import org.apache.commons.lang3.tuple.Pair;
import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.vadere.util.debug.gui.DebugGui;
import org.vadere.util.debug.gui.canvas.SimpleTriCanvas;
import org.vadere.util.geometry.GeometryUtils;
import org.vadere.util.geometry.shapes.IPoint;
import org.vadere.util.geometry.shapes.VPoint;
import java.awt.*;
import org.vadere.geometry.Utils;
import org.vadere.geometry.shapes.IPoint;
import org.vadere.geometry.shapes.VPoint;
import java.util.Comparator;
import java.util.LinkedList;
import java.util.List;
import java.util.Optional;
import java.util.Random;
import java.util.function.Predicate;
......@@ -88,7 +83,7 @@ public interface ITriConnectivity<P extends IPoint, V extends IVertex<P>, E exte
* the old point of the vertex this will reposition the vertex without any checks, i.e.
* the user has to know what he does and has to make sure that the mesh is valid and feasible
* afterwards and all listeners e.g. the point locators such as the Delaunay-Hierarchy
* {@link org.vadere.util.geometry.mesh.gen.DelaunayHierarchy<P, V, E, F>} can handle this
* {@link org.vadere.geometry.mesh.gen.DelaunayHierarchy<P, V, E, F>} can handle this
* repositioning!</p>
*
* <p>Does not change the connectivity but may change the position of a vertex and therefore requires
......@@ -98,7 +93,7 @@ public interface ITriConnectivity<P extends IPoint, V extends IVertex<P>, E exte
* @param point the new point of the vertex
*/
default void replacePoint(@NotNull final V vertex, @NotNull final P point) {
assert GeometryUtils.toPolygon(getMesh().getPoint(vertex)).contains(point);
assert Utils.toPolygon(getMesh().getPoint(vertex)).contains(point);
getMesh().setPoint(vertex, point);
}
......@@ -570,7 +565,7 @@ public interface ITriConnectivity<P extends IPoint, V extends IVertex<P>, E exte
P p2 = getMesh().getPoint(getMesh().getNext(edge));
P p3 = getMesh().getPoint(getMesh().getPrev(edge));
return GeometryUtils.isCCW(p1.getX(), p1.getY(), p2.getX(), p2.getY(), p3.getX(), p3.getY());
return Utils.isCCW(p1.getX(), p1.getY(), p2.getX(), p2.getY(), p3.getX(), p3.getY());
}
/**
......@@ -803,8 +798,8 @@ public interface ITriConnectivity<P extends IPoint, V extends IVertex<P>, E exte
E prev = getMesh().getPrev(boundaryEdge);
// can we form a triangle
assert GeometryUtils.isCCW(getMesh().toPoint(prev), getMesh().toPoint(boundaryEdge), getMesh().toPoint(next))
&& GeometryUtils.angle(getMesh().toPoint(prev), getMesh().toPoint(boundaryEdge), getMesh().toPoint(next)) < Math.PI;
assert Utils.isCCW(getMesh().toPoint(prev), getMesh().toPoint(boundaryEdge), getMesh().toPoint(next))
&& Utils.angle(getMesh().toPoint(prev), getMesh().toPoint(boundaryEdge), getMesh().toPoint(next)) < Math.PI;
E nnext = getMesh().getNext(next);
......@@ -1146,13 +1141,13 @@ public interface ITriConnectivity<P extends IPoint, V extends IVertex<P>, E exte
// TODO: still required?
default E walkThroughHole(@NotNull VPoint q, @NotNull VPoint p, @NotNull E enteringEdge) {
assert GeometryUtils.intersectLine(q, p, getMesh().getPoint(enteringEdge), getMesh().getPoint(getMesh().getPrev(enteringEdge)));
assert Utils.intersectLine(q, p, getMesh().getPoint(enteringEdge), getMesh().getPoint(getMesh().getPrev(enteringEdge)));
E next = getMesh().getNext(enteringEdge);
while (enteringEdge != next) {
VPoint p1 = getMesh().toPoint(getMesh().getVertex(enteringEdge));
VPoint p2 = getMesh().toPoint(getMesh().getVertex(getMesh().getPrev(enteringEdge)));
if(GeometryUtils.intersectLine(q, p, p1, p2)) {
if(Utils.intersectLine(q, p, p1, p2)) {
return next;
}
......@@ -1296,8 +1291,8 @@ public interface ITriConnectivity<P extends IPoint, V extends IVertex<P>, E exte
VPoint q = getMesh().toPoint(getMesh().getNext(edge));
VPoint r = getMesh().toPoint(getMesh().getPrev(edge));
if(GeometryUtils.isCCW(r, p, q)) {
double angle = GeometryUtils.angle(r, p, q);
if(Utils.isCCW(r, p, q)) {
double angle = Utils.angle(r, p, q);
if(angle < 0.5*Math.PI) {
createFaceAtBoundary(edge);
}
......@@ -1323,8 +1318,8 @@ public interface ITriConnectivity<P extends IPoint, V extends IVertex<P>, E exte
VPoint q = getMesh().toPoint(getMesh().getNext(edge));
VPoint r = getMesh().toPoint(getMesh().getPrev(edge));
if(GeometryUtils.isCCW(r, p, q)) {
double angle = GeometryUtils.angle(r, p, q);
if(Utils.isCCW(r, p, q)) {
double angle = Utils.angle(r, p, q);
if(angle < 0.5*Math.PI) {
createFaceAtBoundary(edge);
}
......@@ -1694,17 +1689,17 @@ public interface ITriConnectivity<P extends IPoint, V extends IVertex<P>, E exte
first = false;
prevFace = face;
if (GeometryUtils.isRightOf(v3, v1, x1, y1)) {
if (Utils.isRightOf(v3, v1, x1, y1)) {
face = getMesh().getTwinFace(e1);
continue;
}
if (GeometryUtils.isRightOf(v1, v2, x1, y1)) {
if (Utils.isRightOf(v1, v2, x1, y1)) {
face = getMesh().getTwinFace(e2);
continue;
}
if (GeometryUtils.isRightOf(v2, v3, x1, y1)) {
if (Utils.isRightOf(v2, v3, x1, y1)) {
face = getMesh().getTwinFace(e3);
continue;
}
......@@ -1712,12 +1707,12 @@ public interface ITriConnectivity<P extends IPoint, V extends IVertex<P>, E exte
if(prevFace == getMesh().getTwinFace(e1)) {
prevFace = face;
if (GeometryUtils.isRightOf(v2, v3, x1, y1)) {
if (Utils.isRightOf(v2, v3, x1, y1)) {
face = getMesh().getTwinFace(e3);
continue;
}
if(GeometryUtils.isRightOf(v1, v2, x1, y1)) {
if(Utils.isRightOf(v1, v2, x1, y1)) {
face = getMesh().getTwinFace(e2);
continue;
}
......@@ -1726,12 +1721,12 @@ public interface ITriConnectivity<P extends IPoint, V extends IVertex<P>, E exte
else if(prevFace == getMesh().getTwinFace(e2)) {
prevFace = face;
if (GeometryUtils.isRightOf(v3, v1, x1, y1)) {
if (Utils.isRightOf(v3, v1, x1, y1)) {
face = getMesh().getTwinFace(e1);
continue;
}
if (GeometryUtils.isRightOf(v2, v3, x1, y1)) {
if (Utils.isRightOf(v2, v3, x1, y1)) {
face = getMesh().getTwinFace(e3);
continue;
}
......@@ -1740,12 +1735,12 @@ public interface ITriConnectivity<P extends IPoint, V extends IVertex<P>, E exte
else {
prevFace = face;
if(GeometryUtils.isRightOf(v1, v2, x1, y1)) {
if(Utils.isRightOf(v1, v2, x1, y1)) {
face = getMesh().getTwinFace(e2);