/** * Gets the read-only reference to the {@code index}<sup>th</sup> vertex of this polygon. * <p> * Note that the first vertex has the lowest x-coordinate. * </p> * * @param index the index of the vertex in the clockwise ordered list. * @return the read-only reference to the vertex. * @throws OutdatedPolygonException if {@link ConvexPolygon2DBasics#update()} has not been called * since last time this polygon's vertices were edited. */ @Override default Point2DReadOnly getVertex(int index) { checkIfUpToDate(); checkNonEmpty(); checkIndexInBoundaries(index); return getVertexBufferView().get(index); }
/** * Finds the index of the closest vertex to the query. * <p> * Edge cases: * <ul> * <li>If the polygon has no vertices, this method fails and returns {@code -1}. * </ul> * </p> * * @param point the coordinates of the query. Not modified. * @return the index of the closest vertex to the query. * @throws OutdatedPolygonException if {@link ConvexPolygon2DBasics#update()} has not been called * since last time this polygon's vertices were edited. */ default int getClosestVertexIndex(Point2DReadOnly point) { checkIfUpToDate(); return EuclidGeometryPolygonTools.closestVertexIndexToPoint2D(point, getVertexBufferView(), getNumberOfVertices()); }
/** * Gets the index of the vertex located before the vertex at the index {@code currentVertexIndex} * in the list of vertices. * <p> * Note that this polygon's vertices are clockwise ordered and that the first vertex has the * lowest x-coordinate. * </p> * * @param currentVertexIndex the current vertex index. * @return the before vertex index. * @throws OutdatedPolygonException if {@link ConvexPolygon2DBasics#update()} has not been called * since last time this polygon's vertices were edited. * @throws IndexOutOfBoundsException if the given {@code index} is negative or greater or equal * than this polygon's number of vertices. * @throws EmptyPolygonException if this polygon is empty when calling this method. */ default int getPreviousVertexIndex(int currentVertexIndex) { checkIfUpToDate(); checkIndexInBoundaries(currentVertexIndex); checkNonEmpty(); if (currentVertexIndex < 1) return getNumberOfVertices() - 1; else return currentVertexIndex - 1; }
/** * Gets the index of the vertex located after the vertex at the index {@code currentVertexIndex} * in the list of vertices. * <p> * Note that this polygon's vertices are clockwise ordered and that the first vertex has the * lowest x-coordinate. * </p> * * @param currentVertexIndex the current vertex index. * @return the next vertex index. * @throws OutdatedPolygonException if {@link ConvexPolygon2DBasics#update()} has not been called * since last time this polygon's vertices were edited. * @throws IndexOutOfBoundsException if the given {@code index} is negative or greater or equal * than this polygon's number of vertices. * @throws EmptyPolygonException if this polygon is empty when calling this method. */ default int getNextVertexIndex(int currentVertexIndex) { checkIfUpToDate(); checkIndexInBoundaries(currentVertexIndex); checkNonEmpty(); if (currentVertexIndex < getNumberOfVertices() - 1) return currentVertexIndex + 1; else return 0; }
/** * Adds a subset of this polygon's vertices into the given list. * <p> * The subset consists of the vertices from the vertex at {@code startIndexInclusive} to the * vertex {@code endIndexInclusive} while going from start to end in a clockwise order. * </p> * * @param startIndexInclusive the index of the first vertex to add. * @param endIndexInclusive the index of the last vertex to add. * @param pointListToPack the list into which the vertices are to be added. * @throws OutdatedPolygonException if {@link ConvexPolygon2DBasics#update()} has not been called * since last time this polygon's vertices were edited. * @throws EmptyPolygonException if this polygon is empty when calling this method. */ default void getPointsInClockwiseOrder(int startIndexInclusive, int endIndexInclusive, List<Point2DReadOnly> pointListToPack) { checkIfUpToDate(); checkIndexInBoundaries(startIndexInclusive); checkIndexInBoundaries(endIndexInclusive); int index = startIndexInclusive; while (true) { pointListToPack.add(getVertex(index)); if (index == endIndexInclusive) break; index = getNextVertexIndex(index); } }
/** * Finds the index of the closest edge to the query. * <p> * Edge cases: * <ul> * <li>If the polygon has one or no vertices, this method fails and returns {@code -1}. * </ul> * </p> * * @param point the coordinates of the query. Not modified. * @return the index of the closest edge to the query. * @throws OutdatedPolygonException if {@link ConvexPolygon2DBasics#update()} has not been called * since last time this polygon's vertices were edited. */ default int getClosestEdgeIndex(Point2DReadOnly point) { checkIfUpToDate(); return EuclidGeometryPolygonTools.closestEdgeIndexToPoint2D(point, getVertexBufferView(), getNumberOfVertices(), isClockwiseOrdered()); }
/** * Determines whether an observer can see the outside of the given edge of this convex polygon. * <p> * The edge is defined by its start {@code this.getVertex(edgeIndex)} and its end * {@code this.getNextVertex(edgeIndex)}. * </p> * * @param edgeIndex the vertex index of the start of the edge. * @param observer the coordinates of the observer. Not modified. * @return {@code true} if the observer can see the outside of the edge, {@code false} if the * observer cannot see the outside or is lying on the edge. * @throws OutdatedPolygonException if {@link ConvexPolygon2DBasics#update()} has not been called * since last time this polygon's vertices were edited. */ default boolean canObserverSeeEdge(int edgeIndex, Point2DReadOnly observer) { checkIfUpToDate(); return EuclidGeometryPolygonTools.canObserverSeeEdge(edgeIndex, observer, getVertexBufferView(), getNumberOfVertices(), isClockwiseOrdered()); }
/** * Computes the orthogonal projection of a 2D point on this 2D convex polygon. * <p> * WARNING: This method generates garbage. * </p> * <p> * Edge cases: * <ul> * <li>If the polygon has no vertices, this method fails and returns {@code null}. * <li>If the polygon has exactly one vertex, the result is the polygon only vertex. * <li>If the query is inside the polygon, the method fails and returns {@code null}. * </ul> * </p> * * @param pointToProject the coordinate of the point to compute the projection of. Not modified. * @return the coordinates of the projection, or {@code null} if the method failed. * @throws OutdatedPolygonException if {@link ConvexPolygon2DBasics#update()} has not been called * since last time this polygon's vertices were edited. */ default Point2DBasics orthogonalProjectionCopy(Point2DReadOnly pointToProject) { checkIfUpToDate(); return EuclidGeometryPolygonTools.orthogonalProjectionOnConvexPolygon2D(pointToProject, getVertexBufferView(), getNumberOfVertices(), isClockwiseOrdered()); }
/** * Computes the orthogonal projection of a 2D point this 2D convex polygon. * <p> * Edge cases: * <ul> * <li>If the polygon has no vertices, this method fails and returns {@code false}. * <li>If the polygon has exactly one vertex, the result is the polygon only vertex, this method * returns {@code true}. * <li>If the query is inside the polygon, the method fails and returns {@code false}. * </ul> * </p> * * @param pointToProject the coordinate of the point to compute the projection of. Not modified. * @param projectionToPack point in which the projection of the point onto the convex polygon is * stored. Modified. * @return whether the method succeeded or not. * @throws OutdatedPolygonException if {@link ConvexPolygon2DBasics#update()} has not been called * since last time this polygon's vertices were edited. */ default boolean orthogonalProjection(Point2DReadOnly pointToProject, Point2DBasics projectionToPack) { checkIfUpToDate(); return EuclidGeometryPolygonTools.orthogonalProjectionOnConvexPolygon2D(pointToProject, getVertexBufferView(), getNumberOfVertices(), isClockwiseOrdered(), projectionToPack); }
checkIfUpToDate(); return EuclidGeometryPolygonTools.isPoint2DInsideConvexPolygon2D(x, y, getVertexBufferView(), getNumberOfVertices(), isClockwiseOrdered(), epsilon);
/** * Returns minimum distance between the point and this polygon. * <p> * The returned value is negative if the point is inside the polygon. * </p> * <p> * Edge cases: * <ul> * <li>If the polygon has no vertices, this method fails and returns {@link Double#NaN}. * <li>If the polygon has exactly one vertex, the returned value is positive and is equal to the * distance between the query and the polygon's vertex. * <li>If the polygon has exactly two vertices, the returned value is positive and is equal to * the distance and the line segment defined by the polygon's two vertices. * </ul> * </p> * * @param point the coordinates of the query. Not modified. * @return the distance between the query and the polygon, it is negative if the point is inside * the polygon. * @throws OutdatedPolygonException if {@link ConvexPolygon2DBasics#update()} has not been called * since last time this polygon's vertices were edited. */ default double signedDistance(Point2DReadOnly point) { checkIfUpToDate(); return EuclidGeometryPolygonTools.signedDistanceFromPoint2DToConvexPolygon2D(point, getVertexBufferView(), getNumberOfVertices(), isClockwiseOrdered()); }
/** * From the point of view of an observer located outside the polygon, only a continuous subset of * the polygon's edges can be seen defining a line-of-sight. This method finds the index of the * first vertex that is in the line-of-sight. * <p> * WARNING: This method assumes that the given observer is located outside the polygon. * </p> * <p> * Edge cases: * <ul> * <li>The polygon has no vertices, this method fails and returns {@code -1}. * <li>The observer is inside the polygon, this method fails and returns {@code -1}. * <li>The polygon has exactly one vertex, this method returns {@code 0} if the observer is * different from the polygon's vertex, or returns {@code -1} if the observer is equal to the * polygon's vertex. * </ul> * </p> * * @param observer the coordinates of the observer. Not modified. * @return the index of the first vertex that is in the line-of-sight, {@code -1} if this method * fails. * @throws OutdatedPolygonException if {@link ConvexPolygon2DBasics#update()} has not been called * since last time this polygon's vertices were edited. */ default int lineOfSightStartIndex(Point2DReadOnly observer) { checkIfUpToDate(); return EuclidGeometryPolygonTools.lineOfSightStartIndex(observer, getVertexBufferView(), getNumberOfVertices(), isClockwiseOrdered()); }
/** * From the point of view of an observer located outside the polygon, only a continuous subset of * the polygon's edges can be seen defining a line-of-sight. This method finds the index of the * last vertex that is in the line-of-sight. * <p> * WARNING: This method assumes that the given observer is located outside the polygon. * </p> * <p> * Edge cases: * <ul> * <li>The polygon has no vertices, this method fails and returns {@code -1}. * <li>The observer is inside the polygon, this method fails and returns {@code -1}. * <li>The polygon has exactly one vertex, this method returns {@code 0} if the observer is * different from the polygon's vertex, or returns {@code -1} if the observer is equal to the * polygon's vertex. * </ul> * </p> * * @param observer the coordinates of the observer. Not modified. * @return the index of the last vertex that is in the line-of-sight, {@code -1} if this method * fails. * @throws OutdatedPolygonException if {@link ConvexPolygon2DBasics#update()} has not been called * since last time this polygon's vertices were edited. */ default int lineOfSightEndIndex(Point2DReadOnly observer) { checkIfUpToDate(); return EuclidGeometryPolygonTools.lineOfSightEndIndex(observer, getVertexBufferView(), getNumberOfVertices(), isClockwiseOrdered()); }
/** * Finds the index of the closest vertex to the given line. * <p> * Edge cases: * <ul> * <li>If the polygon has no vertices, this method fails and returns {@code -1}. * </ul> * </p> * * @param line the query. Not modified. * @return the index of the closest vertex to the query. * @throws OutdatedPolygonException if {@link ConvexPolygon2DBasics#update()} has not been called * since last time this polygon's vertices were edited. */ default int getClosestVertexIndex(Line2DReadOnly line) { checkIfUpToDate(); return EuclidGeometryPolygonTools.closestVertexIndexToLine2D(line.getPoint(), line.getDirection(), getVertexBufferView(), getNumberOfVertices()); }
/** * Adds a subset of this polygon's vertices into the given polygon. * <p> * The subset consists of the vertices from the vertex at {@code startIndexInclusive} to the * vertex {@code endIndexInclusive} while going from start to end in a clockwise order. * </p> * * @param startIndexInclusive the index of the first vertex to add. * @param endIndexInclusive the index of the last vertex to add. * @param polygonToPack the polygon into which the vertices are to be added. * @throws OutdatedPolygonException if {@link ConvexPolygon2DBasics#update()} has not been called * since last time this polygon's vertices were edited. * @throws EmptyPolygonException if this polygon is empty when calling this method. */ default void getVerticesInClockwiseOrder(int startIndexInclusive, int endIndexInclusive, ConvexPolygon2DBasics polygonToPack) { checkIfUpToDate(); checkIndexInBoundaries(startIndexInclusive); checkIndexInBoundaries(endIndexInclusive); int index = startIndexInclusive; while (true) { polygonToPack.addVertex(getVertex(index)); if (index == endIndexInclusive) break; index = getNextVertexIndex(index); } }
/** * Computes the coordinates of the possible intersection(s) between a given line 2D and this * convex polygon 2D. * <p> * WARNING: This method generates garbage. * </p> * <p> * Edge cases: * <ul> * <li>If the polygon has no vertices, this method behaves as if there is no intersections and * returns {@code null}. * <li>If no intersections exist, this method returns {@code null}. * </ul> * </p> * * @param line the line that may intersect this polygon. Not modified. * @return the coordinates of the intersections between the line and the polygon, or {@code null} * if they do not intersect. * @throws OutdatedPolygonException if {@link ConvexPolygon2DBasics#update()} has not been called * since last time this polygon's vertices were edited. */ default Point2DBasics[] intersectionWith(Line2DReadOnly line) { checkIfUpToDate(); return EuclidGeometryPolygonTools.intersectionBetweenLine2DAndConvexPolygon2D(line.getPoint(), line.getDirection(), getVertexBufferView(), getNumberOfVertices(), isClockwiseOrdered()); }
/** * Computes the coordinates of the possible intersection(s) between a given ray 2D and this * convex polygon 2D. * <p> * WARNING: This method generates garbage. * </p> * <p> * Edge cases: * <ul> * <li>If the polygon has no vertices, this method behaves as if there is no intersections and * returns {@code null}. * <li>If no intersections exist, this method returns {@code null}. * </ul> * </p> * * @param ray the ray that may intersect this polygon. Not modified. * @return the intersections between the ray and the polygon. * @throws OutdatedPolygonException if {@link ConvexPolygon2DBasics#update()} has not been called * since last time this polygon's vertices were edited. */ default Point2DBasics[] intersectionWithRay(Line2DReadOnly ray) { checkIfUpToDate(); return EuclidGeometryPolygonTools.intersectionBetweenRay2DAndConvexPolygon2D(ray.getPoint(), ray.getDirection(), getVertexBufferView(), getNumberOfVertices(), isClockwiseOrdered()); }
/** * Computes the coordinates of the closest point to the ray that belongs to this convex polygon. * <p> * WARNING: This method generates garbage. * </p> * <p> * WARNING: This methods assumes that the ray does not intersect with the polygon. Such scenario * should be handled with * {@link #intersectionWithRay(Line2DReadOnly, Point2DBasics, Point2DBasics)}. * </p> * <p> * Edge cases: * <ul> * <li>If the polygon has no vertices, this method fails and returns {@code null}. * <li>If the ray is parallel to the closest edge, the closest point to the ray origin is chosen. * </ul> * </p> * * @param ray the ray to find the closest point to. Not modified. * @return the coordinates of the closest point if the method succeeds, {@code null} otherwise. * @throws OutdatedPolygonException if {@link ConvexPolygon2DBasics#update()} has not been called * since last time this polygon's vertices were edited. */ default Point2DBasics getClosestPointWithRay(Line2DReadOnly ray) { checkIfUpToDate(); return EuclidGeometryPolygonTools.closestPointToNonInterectingRay2D(ray.getPoint(), ray.getDirection(), getVertexBufferView(), getNumberOfVertices(), isClockwiseOrdered()); }
/** * Computes the coordinates of the closest point to the ray that belongs to this convex polygon. * <p> * WARNING: This methods assumes that the ray does not intersect with the polygon. Such scenario * should be handled with * {@link #intersectionWithRay(Line2DReadOnly, Point2DBasics, Point2DBasics)}. * </p> * <p> * Edge cases: * <ul> * <li>If the polygon has no vertices, this method fails and returns {@code false}. * <li>If the ray is parallel to the closest edge, the closest point to the ray origin is chosen. * </ul> * </p> * * @param ray the ray to find the closest point to. Not modified. * @param closestPointToPack the point in which the coordinates of the closest point are stored. * Modified. * @return {@code true} if the method succeeds, {@code false} otherwise. * @throws OutdatedPolygonException if {@link ConvexPolygon2DBasics#update()} has not been called * since last time this polygon's vertices were edited. */ default boolean getClosestPointWithRay(Line2DReadOnly ray, Point2DBasics closestPointToPack) { checkIfUpToDate(); return EuclidGeometryPolygonTools.closestPointToNonInterectingRay2D(ray.getPoint(), ray.getDirection(), getVertexBufferView(), getNumberOfVertices(), isClockwiseOrdered(), closestPointToPack); }
checkIfUpToDate(); return EuclidGeometryPolygonTools.intersectionBetweenRay2DAndConvexPolygon2D(ray.getPoint(), ray.getDirection(), getVertexBufferView(), getNumberOfVertices(), isClockwiseOrdered(), firstIntersectionToPack,