All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.apache.commons.geometry.spherical.twod.GreatArc Maven / Gradle / Ivy

The newest version!
/*
 * 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.commons.geometry.spherical.twod;

import java.util.Collections;
import java.util.List;

import org.apache.commons.geometry.core.Transform;
import org.apache.commons.geometry.core.partitioning.Hyperplane;
import org.apache.commons.geometry.core.partitioning.HyperplaneConvexSubset;
import org.apache.commons.geometry.core.partitioning.Split;
import org.apache.commons.geometry.core.partitioning.SplitLocation;
import org.apache.commons.geometry.spherical.oned.AngularInterval;
import org.apache.commons.geometry.spherical.oned.CutAngle;
import org.apache.commons.geometry.spherical.oned.CutAngles;
import org.apache.commons.geometry.spherical.oned.Transform1S;

/** Class representing a single, convex angular interval in a {@link GreatCircle}. Convex
 * angular intervals are those where the shortest path between all pairs of points in the
 * interval are completely contained in the interval. In the case of paths that tie for the
 * shortest length, it is sufficient that one of the paths is completely contained in the
 * interval. In spherical 2D space, convex arcs either fill the entire great circle or have
 * an angular size of less than or equal to {@code pi} radians.
 *
 * 

Instances of this class are guaranteed to be immutable.

* @see GreatCircles */ public final class GreatArc extends GreatCircleSubset implements HyperplaneConvexSubset { /** The interval representing the region of the great circle contained in the arc. */ private final AngularInterval.Convex interval; /** Create a new instance from a great circle and the interval embedded in it. * @param circle defining great circle instance * @param interval convex angular interval embedded in the great circle */ GreatArc(final GreatCircle circle, final AngularInterval.Convex interval) { super(circle); this.interval = interval; } /** Return the start point of the arc, or null if the arc represents the full space. * @return the start point of the arc, or null if the arc represents the full space. */ public Point2S getStartPoint() { if (!interval.isFull()) { return getCircle().toSpace(interval.getMinBoundary().getPoint()); } return null; } /** Return the end point of the arc, or null if the arc represents the full space. * @return the end point of the arc, or null if the arc represents the full space. */ public Point2S getEndPoint() { if (!interval.isFull()) { return getCircle().toSpace(interval.getMaxBoundary().getPoint()); } return null; } /** Return the midpoint of the arc, or null if the arc represents the full space. * @return the midpoint of the arc, or null if the arc represents the full space. */ public Point2S getMidPoint() { if (!interval.isFull()) { return getCircle().toSpace(interval.getMidPoint()); } return null; } /** Get the angular interval for the arc. * @return the angular interval for the arc * @see #getSubspaceRegion() */ public AngularInterval.Convex getInterval() { return interval; } /** {@inheritDoc} */ @Override public AngularInterval.Convex getSubspaceRegion() { return getInterval(); } /** {@inheritDoc} */ @Override public List toConvex() { return Collections.singletonList(this); } /** {@inheritDoc} */ @Override public Split split(final Hyperplane splitter) { final GreatCircle splitterCircle = (GreatCircle) splitter; final GreatCircle thisCircle = getCircle(); final Point2S intersection = splitterCircle.intersection(thisCircle); GreatArc minus = null; GreatArc plus = null; if (intersection != null) { // use a negative-facing cut angle to account for the fact that the great circle // poles point to the minus side of the circle final CutAngle subSplitter = CutAngles.createNegativeFacing( thisCircle.toSubspace(intersection), splitterCircle.getPrecision()); final Split subSplit = interval.splitDiameter(subSplitter); final SplitLocation subLoc = subSplit.getLocation(); if (subLoc == SplitLocation.MINUS) { minus = this; } else if (subLoc == SplitLocation.PLUS) { plus = this; } else if (subLoc == SplitLocation.BOTH) { minus = GreatCircles.arcFromInterval(thisCircle, subSplit.getMinus()); plus = GreatCircles.arcFromInterval(thisCircle, subSplit.getPlus()); } } return new Split<>(minus, plus); } /** {@inheritDoc} */ @Override public GreatArc transform(final Transform transform) { return new GreatArc(getCircle().transform(transform), interval); } /** {@inheritDoc} */ @Override public GreatArc reverse() { return new GreatArc( getCircle().reverse(), interval.transform(Transform1S.createNegation())); } /** Return a string representation of this great arc. * *

In order to keep the string representation short but useful, the exact format of the return * value depends on the properties of the arc. See below for examples. * *

    *
  • Full arc *
      *
    • {@code GreatArc[full= true, circle= GreatCircle[pole= (0.0, 0.0, 1.0), x= (1.0, 0.0, 0.0), y= (0.0, 1.0, 0.0)]}
    • *
    *
  • *
  • Non-full arc *
      *
    • {@code GreatArc[start= (1.0, 1.5707963267948966), end= (2.0, 1.5707963267948966)}
    • *
    *
  • *
*/ @Override public String toString() { final StringBuilder sb = new StringBuilder(); sb.append(this.getClass().getSimpleName()).append('['); if (isFull()) { sb.append("full= true, circle= ") .append(getCircle()); } else { sb.append("start= ") .append(getStartPoint()) .append(", end= ") .append(getEndPoint()); } return sb.toString(); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy