/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.apache.lucene.geo;

import org.apache.lucene.index.PointValues;

import static org.apache.lucene.geo.GeoUtils.orient;

2D Geometry object that supports spatial relationships with bounding boxes, triangles and points.
@lucene.internal
/** * 2D Geometry object that supports spatial relationships with bounding boxes, * triangles and points. * * @lucene.internal **/
public interface Component2D {
min X value for the component
/** min X value for the component **/
double getMinX();
max X value for the component
/** max X value for the component **/
double getMaxX();
min Y value for the component
/** min Y value for the component **/
double getMinY();
max Y value for the component
/** max Y value for the component **/
double getMaxY();
relates this component2D with a point
/** relates this component2D with a point **/
boolean contains(double x, double y);
relates this component2D with a bounding box
/** relates this component2D with a bounding box **/
PointValues.Relation relate(double minX, double maxX, double minY, double maxY);
return true if this component2D intersects the provided line
/** return true if this component2D intersects the provided line **/
boolean intersectsLine(double minX, double maxX, double minY, double maxY, double aX, double aY, double bX, double bY);
return true if this component2D intersects the provided triangle
/** return true if this component2D intersects the provided triangle **/
boolean intersectsTriangle(double minX, double maxX, double minY, double maxY, double aX, double aY, double bX, double bY, double cX, double cY);
return true if this component2D contains the provided line
/** return true if this component2D contains the provided line **/
boolean containsLine(double minX, double maxX, double minY, double maxY, double aX, double aY, double bX, double bY);
return true if this component2D contains the provided triangle
/** return true if this component2D contains the provided triangle **/
boolean containsTriangle(double minX, double maxX, double minY, double maxY, double aX, double aY, double bX, double bY, double cX, double cY);
Used by withinTriangle to check the within relationship between a triangle and the query shape (e.g. if the query shape is within the triangle).
/** Used by withinTriangle to check the within relationship between a triangle and the query shape * (e.g. if the query shape is within the triangle). */
enum WithinRelation {
If the shape is a candidate for within. Typically this is return if the query shape is fully inside the triangle or if the query shape intersects only edges that do not belong to the original shape.
/** If the shape is a candidate for within. Typically this is return if the query shape is fully inside * the triangle or if the query shape intersects only edges that do not belong to the original shape. */
CANDIDATE,
The query shape intersects an edge that does belong to the original shape or any point of the triangle is inside the shape.
/** The query shape intersects an edge that does belong to the original shape or any point of * the triangle is inside the shape. */
NOTWITHIN,
The query shape is disjoint with the triangle.
/** The query shape is disjoint with the triangle. */
DISJOINT }
Compute the within relation of this component2D with a point
/** Compute the within relation of this component2D with a point **/
WithinRelation withinPoint(double x, double y);
Compute the within relation of this component2D with a line
/** Compute the within relation of this component2D with a line **/
WithinRelation withinLine(double minX, double maxX, double minY, double maxY, double aX, double aY, boolean ab, double bX, double bY);
Compute the within relation of this component2D with a triangle
/** Compute the within relation of this component2D with a triangle **/
WithinRelation withinTriangle(double minX, double maxX, double minY, double maxY, double aX, double aY, boolean ab, double bX, double bY, boolean bc, double cX, double cY, boolean ca);
return true if this component2D intersects the provided line
/** return true if this component2D intersects the provided line **/
default boolean intersectsLine(double aX, double aY, double bX, double bY) { double minY = StrictMath.min(aY, bY); double minX = StrictMath.min(aX, bX); double maxY = StrictMath.max(aY, bY); double maxX = StrictMath.max(aX, bX); return intersectsLine(minX, maxX, minY, maxY, aX, aY, bX, bY); }
return true if this component2D intersects the provided triangle
/** return true if this component2D intersects the provided triangle **/
default boolean intersectsTriangle(double aX, double aY, double bX, double bY, double cX, double cY) { double minY = StrictMath.min(StrictMath.min(aY, bY), cY); double minX = StrictMath.min(StrictMath.min(aX, bX), cX); double maxY = StrictMath.max(StrictMath.max(aY, bY), cY); double maxX = StrictMath.max(StrictMath.max(aX, bX), cX); return intersectsTriangle(minX, maxX, minY, maxY, aX, aY, bX, bY, cX, cY); }
return true if this component2D contains the provided line
/** return true if this component2D contains the provided line **/
default boolean containsLine(double aX, double aY, double bX, double bY) { double minY = StrictMath.min(aY, bY); double minX = StrictMath.min(aX, bX); double maxY = StrictMath.max(aY, bY); double maxX = StrictMath.max(aX, bX); return containsLine(minX, maxX, minY, maxY, aX, aY, bX, bY); }
return true if this component2D contains the provided triangle
/** return true if this component2D contains the provided triangle **/
default boolean containsTriangle(double aX, double aY, double bX, double bY, double cX, double cY) { double minY = StrictMath.min(StrictMath.min(aY, bY), cY); double minX = StrictMath.min(StrictMath.min(aX, bX), cX); double maxY = StrictMath.max(StrictMath.max(aY, bY), cY); double maxX = StrictMath.max(StrictMath.max(aX, bX), cX); return containsTriangle(minX, maxX, minY, maxY, aX, aY, bX, bY, cX, cY); }
Compute the within relation of this component2D with a triangle
/** Compute the within relation of this component2D with a triangle **/
default WithinRelation withinLine(double aX, double aY, boolean ab, double bX, double bY) { double minY = StrictMath.min(aY, bY); double minX = StrictMath.min(aX, bX); double maxY = StrictMath.max(aY, bY); double maxX = StrictMath.max(aX, bX); return withinLine(minX, maxX, minY, maxY, aX, aY, ab, bX, bY); }
Compute the within relation of this component2D with a triangle
/** Compute the within relation of this component2D with a triangle **/
default WithinRelation withinTriangle(double aX, double aY, boolean ab, double bX, double bY, boolean bc, double cX, double cY, boolean ca) { double minY = StrictMath.min(StrictMath.min(aY, bY), cY); double minX = StrictMath.min(StrictMath.min(aX, bX), cX); double maxY = StrictMath.max(StrictMath.max(aY, bY), cY); double maxX = StrictMath.max(StrictMath.max(aX, bX), cX); return withinTriangle(minX, maxX, minY, maxY, aX, aY, ab, bX, bY, bc, cX, cY, ca); }
Compute whether the bounding boxes are disjoint
/** Compute whether the bounding boxes are disjoint **/
static boolean disjoint(double minX1, double maxX1, double minY1, double maxY1, double minX2, double maxX2, double minY2, double maxY2) { return (maxY1 < minY2 || minY1 > maxY2 || maxX1 < minX2 || minX1 > maxX2); }
Compute whether the first bounding box 1 is within the second bounding box
/** Compute whether the first bounding box 1 is within the second bounding box **/
static boolean within(double minX1, double maxX1, double minY1, double maxY1, double minX2, double maxX2, double minY2, double maxY2) { return (minY2 <= minY1 && maxY2 >= maxY1 && minX2 <= minX1 && maxX2 >= maxX1); }
returns true if rectangle (defined by minX, maxX, minY, maxY) contains the X Y point
/** returns true if rectangle (defined by minX, maxX, minY, maxY) contains the X Y point */
static boolean containsPoint(final double x, final double y, final double minX, final double maxX, final double minY, final double maxY) { return x >= minX && x <= maxX && y >= minY && y <= maxY; }
Compute whether the given x, y point is in a triangle; uses the winding order method
/** * Compute whether the given x, y point is in a triangle; uses the winding order method */
static boolean pointInTriangle(double minX, double maxX, double minY, double maxY, double x, double y, double aX, double aY, double bX, double bY, double cX, double cY) { // check the bounding box because if the triangle is degenerated, e.g points and lines, we need to filter out // coplanar points that are not part of the triangle. if (x >= minX && x <= maxX && y >= minY && y <= maxY) { int a = orient(x, y, aX, aY, bX, bY); int b = orient(x, y, bX, bY, cX, cY); if (a == 0 || b == 0 || a < 0 == b < 0) { int c = orient(x, y, cX, cY, aX, aY); return c == 0 || (c < 0 == (b < 0 || a < 0)); } return false; } else { return false; } } }