/** * Tests if the given is located on this line. * <p> * More precisely, the point is assumed to be on this line if it is located at a distance less than * {@code 1.0e-8} from it. * </p> * * @param point the coordinates of the query. Not modified. * @return {@code true} if the point is located on this line, {@code false} otherwise. */ default boolean isPointOnLine(Point2DReadOnly point) { return isPointOnLine(point, 1.0e-8); }
/** * Returns a boolean value, stating whether a 2D point is on the left or right side of this line. * The idea of "side" is determined based on the direction of the line. * <p> * For instance, given the {@code this.direction} components x = 0, and y = 1, and the * {@code this.point} coordinates x = 0, and y = 0, a point located on: * <ul> * <li>the left side of this line has a negative y coordinate. * <li>the right side of this line has a positive y coordinate. * </ul> * </p> * This method will return {@code false} if the point is on this line. * * @param point the coordinates of the query point. * @return {@code true} if the point is on the right side of this line, {@code false} if the point * is on the left side or exactly on this line. */ default boolean isPointOnRightSideOfLine(Point2DReadOnly point) { return isPointOnSideOfLine(point, false); }
/** * Compares {@code this} with {@code other} to determine if the two lines are collinear. * * @param other the line to compare to. Not modified. * @param angleEpsilon the tolerance of the comparison for angle. * @param distanceEpsilon the tolerance of the comparison for distance. * @return {@code true} if the lines are collinear, {@code false} otherwise. */ default boolean isCollinear(Line2DReadOnly other, double angleEpsilon, double distanceEpsilon) { return EuclidGeometryTools.areLine2DsCollinear(getPoint(), getDirection(), other.getPoint(), other.getDirection(), angleEpsilon, distanceEpsilon); }
/** * The x-coordinate at which this line intercept the x-axis, i.e. the line defined by {@code y=0}. * * @return the x-coordinate of the intersection between this line and the x-axis. */ default double xIntercept() { double parameterAtIntercept = -getPointY() / getDirectionY(); return parameterAtIntercept * getDirectionX() + getPointX(); }
/** * Calculates the slope value of this line. * <p> * The slope 's' can be used to calculate the y-coordinate of a point located on the line given its * x-coordinate:<br> * y = s * x + y<sub>0</sub><br> * where y<sub>0</sub> is the y-coordinate at which this line intercepts the y-axis and which can be * obtained with {@link #yIntercept()}. * </p> * * @return the value of the slope of this line. */ default double slope() { if (getDirectionX() == 0.0 && getDirectionY() > 0.0) { return Double.POSITIVE_INFINITY; } if (getDirectionX() == 0.0 && getDirectionY() < 0.0) { return Double.NEGATIVE_INFINITY; } return getDirectionY() / getDirectionX(); }
if (!isPointOnLine(pointOnLine, epsilon)) throw new RuntimeException("The given point is not on this line, distance from line: " + distance(pointOnLine)); double x0 = getPointX(); double y0 = getPointY(); double x1 = x0 + getDirectionX(); double y1 = y0 + getDirectionY(); return EuclidGeometryTools.percentageAlongLineSegment2D(pointOnLine.getX(), pointOnLine.getY(), x0, y0, x1, y1);
double t = EuclidGeometryTools.percentageOfIntersectionBetweenTwoLine2Ds(getPoint(), getDirection(), secondLine.getPoint(), secondLine.getDirection()); else if (t == 0.0 && EuclidGeometryTools.areVector2DsParallel(getDirection(), secondLine.getDirection(), 1.0e-7)) double pointOnBisectorX = t * getDirectionX() + getPointX(); double pointOnBisectorY = t * getDirectionY() + getPointY(); double bisectorDirectionX = getDirectionX() + secondLine.getDirectionX(); double bisectorDirectionY = getDirectionY() + secondLine.getDirectionY(); interiorBisectorToPack.set(pointOnBisectorX, pointOnBisectorY, bisectorDirectionX, bisectorDirectionY); return true;
/** * Checks if a line intersects the edge with the given index. */ public static boolean doesLineIntersectEdge(Line2DReadOnly line, int edgeIndex, ConvexPolygon2DReadOnly polygon) { if (polygon.getNumberOfVertices() < 2) return false; Point2DReadOnly edgeStart = polygon.getVertex(edgeIndex); Point2DReadOnly edgeEnd = polygon.getNextVertex(edgeIndex); double lineDirectionX = line.getDirectionX(); double lineDirectionY = line.getDirectionY(); double edgeDirectionX = edgeEnd.getX() - edgeStart.getX(); double edgeDirectionY = edgeEnd.getY() - edgeStart.getY(); if (EuclidGeometryTools.areVector2DsParallel(lineDirectionX, lineDirectionY, edgeDirectionX, edgeDirectionY, EuclidGeometryTools.ONE_TEN_MILLIONTH)) return false; else return EuclidGeometryTools.doLine2DAndLineSegment2DIntersect(line.getPoint(), line.getDirection(), edgeStart, edgeEnd); }
/** * Returns a boolean value, stating whether the query point is in front of this line or not. * <p> * The idea of 'front' refers to the side of the line toward which the x-axis is pointing. * </p> * * @param point the coordinates of the query. Not modified. * @return {@code true} if the point is in front of this line, {@code false} if the point is behind * the line. * @throws RuntimeException if the given point is located exactly on this line. */ default boolean isPointInFrontOfLine(Point2DReadOnly point) { if (getDirectionY() > 0.0) return isPointOnRightSideOfLine(point); else if (getDirectionY() < 0.0) return isPointOnLeftSideOfLine(point); else throw new RuntimeException("Not defined when line is pointing exactly along the x-axis"); }
/** * Returns a boolean value, stating whether the query point is in front of this line or not. * <p> * The idea of 'front' refers to the side of the line toward which the given vector * {@code frontDirection} is pointing. * </p> * * @param frontDirection the vector used to define the side of the line which is to be considered as * the front. Not modified. * @param point the coordinates of the query. Not modified. * @return {@code true} if the point is in front of this line, {@code false} if the point is behind * the line. * @throws RuntimeException if the given point is located exactly on this line. */ default boolean isPointInFrontOfLine(Vector2DReadOnly frontDirection, Point2DReadOnly point) { double crossProduct = frontDirection.cross(getDirection()); if (crossProduct > 0.0) return isPointOnRightSideOfLine(point); else if (crossProduct < 0.0) return isPointOnLeftSideOfLine(point); else throw new RuntimeException("Not defined when line is pointing exactly along the front direction"); }
/** {@inheritDoc} */ @Override default FrameLine2DBasics interiorBisector(Line2DReadOnly secondLine) { return new FrameLine2D(getReferenceFrame(), Line2DReadOnly.super.interiorBisector(secondLine)); }
/** * Tests if this line and the other line are perpendicular. * * @param other the query. Not modified. * @return {@code true} if the two lines are perpendicular, {@code false} otherwise. */ default boolean areLinesPerpendicular(Line2DReadOnly other) { // Dot product of two vectors is zero if the vectors are perpendicular return getDirection().dot(other.getDirection()) < 1e-7; }
/** * Compares {@code this} with {@code other} to determine if the two lines are collinear. * * @param other the line to compare to. Not modified. * @param epsilon the tolerance of the comparison. * @return {@code true} if the lines are collinear, {@code false} otherwise. */ default boolean isCollinear(Line2DReadOnly other, double epsilon) { return isCollinear(other, epsilon, epsilon); }
/** * Gets the x-coordinate of a point this line goes through. * * @return the x-coordinate of this line's point. */ default double getPointX() { return getPoint().getX(); }
/** * Compares {@code this} to {@code other} to determine if the two lines are geometrically * similar. * <p> * Two lines are considered geometrically equal is they are collinear, pointing toward the same * or opposite direction. * </p> * * @param other the line to compare to. Not modified. * @param epsilon the tolerance of the comparison. * @return {@code true} if the two lines represent the same geometry, {@code false} otherwise. * @throws ReferenceFrameMismatchException if {@code this} and {@code other} are not expressed in * the same reference frame. */ default boolean geometricallyEquals(FrameLine2DReadOnly other, double epsilon) { checkReferenceFrameMatch(other); return Line2DReadOnly.super.geometricallyEquals(other, epsilon); }
/** * Computes the minimum distance the given 3D point and this line. * <p> * Edge cases: * <ul> * <li>if {@code direction.length() < }{@link EuclidGeometryTools#ONE_TRILLIONTH}, this method * returns the distance between {@code point} and the given {@code point}. * </ul> * </p> * * @param point 2D point to compute the distance from the line. Not modified. * @return the minimum distance between the 2D point and this 2D line. * @throws ReferenceFrameMismatchException if {@code this} and {@code point} are not expressed in * the same reference frame. */ default double distance(FramePoint2DReadOnly point) { checkReferenceFrameMatch(point); return Line2DReadOnly.super.distance(point); }
/** * The y-coordinate at which this line intercept the y-axis, i.e. the line defined by {@code x=0}. * * @return the y-coordinate of the intersection between this line and the y-axis. */ default double yIntercept() { double parameterAtIntercept = -getPointX() / getDirectionX(); return parameterAtIntercept * getDirectionY() + getPointY(); }
return Line2DReadOnly.super.interiorBisector(secondLine, interiorBisectorToPack);
/** * Gets the x-component of this line's direction. * * @return the x-component of this line's direction. */ default double getDirectionX() { return getDirection().getX(); }
/** * Compares {@code this} to {@code other} to determine if the two lines are geometrically similar. * <p> * Two lines are considered geometrically equal is they are collinear, pointing toward the same or * opposite direction. * </p> * * @param other the line to compare to. Not modified. * @param epsilon the tolerance of the comparison. * @return {@code true} if the two lines represent the same geometry, {@code false} otherwise. */ default boolean geometricallyEquals(Line2DReadOnly other, double epsilon) { return isCollinear(other, epsilon); }