001/*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements.  See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License.  You may obtain a copy of the License at
008 *
009 *      http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017package org.apache.commons.geometry.euclidean.threed.line;
018
019import org.apache.commons.geometry.core.Transform;
020import org.apache.commons.geometry.euclidean.threed.Bounds3D;
021import org.apache.commons.geometry.euclidean.threed.Vector3D;
022
023/** Class representing a portion of a line in 3D Euclidean space that starts at infinity and
024 * continues in the direction of the line up to a single end point. This is equivalent to taking a
025 * {@link Ray3D} and reversing the line direction.
026 *
027 * <p>Instances of this class are guaranteed to be immutable.</p>
028 * @see Ray3D
029 * @see Lines3D
030 */
031public final class ReverseRay3D extends LineConvexSubset3D {
032
033    /** The abscissa of the line subset endpoint. */
034    private final double end;
035
036    /** Construct a new instance from the given line and end point. The end point is projected onto
037     * the line. No validation is performed.
038     * @param line line for the instance
039     * @param endPoint end point for the instance
040     */
041    ReverseRay3D(final Line3D line, final Vector3D endPoint) {
042        this(line, line.abscissa(endPoint));
043    }
044
045    /** Construct a new instance from the given line and 1D end location. No validation is performed.
046     * @param line line for the instance
047     * @param end end location for the instance
048     */
049    ReverseRay3D(final Line3D line, final double end) {
050        super(line);
051
052        this.end = end;
053    }
054
055    /** {@inheritDoc}
056    *
057    * <p>This method always returns {@code true}.</p>
058    */
059    @Override
060    public boolean isInfinite() {
061        return true;
062    }
063
064    /** {@inheritDoc}
065    *
066    * <p>This method always returns {@code false}.</p>
067    */
068    @Override
069    public boolean isFinite() {
070        return false;
071    }
072
073    /** {@inheritDoc}
074    *
075    * <p>This method always returns {@link Double#POSITIVE_INFINITY}.</p>
076    */
077    @Override
078    public double getSize() {
079        return Double.POSITIVE_INFINITY;
080    }
081
082    /** {@inheritDoc}
083    *
084    * <p>This method always returns {@code null}.</p>
085    */
086    @Override
087    public Vector3D getStartPoint() {
088        return null;
089    }
090
091    /** {@inheritDoc}
092    *
093    * <p>This method always returns {@link Double#NEGATIVE_INFINITY}.</p>
094    */
095    @Override
096    public double getSubspaceStart() {
097        return Double.NEGATIVE_INFINITY;
098    }
099
100    /** {@inheritDoc} */
101    @Override
102    public Vector3D getEndPoint() {
103        return getLine().toSpace(end);
104    }
105
106    /** {@inheritDoc} */
107    @Override
108    public double getSubspaceEnd() {
109        return end;
110    }
111
112    /** {@inheritDoc}
113     *
114     * <p>This method always returns {@code null}.</p>
115     */
116    @Override
117    public Vector3D getCentroid() {
118        return null; // infinite; no center
119    }
120
121   /** {@inheritDoc}
122    *
123    * <p>This method always returns {@code null}.</p>
124    */
125    @Override
126    public Bounds3D getBounds() {
127        return null; // infinite; no bounds
128    }
129
130    /** {@inheritDoc} */
131    @Override
132    public ReverseRay3D transform(final Transform<Vector3D> transform) {
133        final Line3D tLine = getLine().transform(transform);
134        final Vector3D tEnd = transform.apply(getEndPoint());
135
136        return new ReverseRay3D(tLine, tEnd);
137    }
138
139    /** {@inheritDoc} */
140    @Override
141    public String toString() {
142        final StringBuilder sb = new StringBuilder();
143        sb.append(getClass().getSimpleName())
144            .append("[direction= ")
145            .append(getLine().getDirection())
146            .append(", endPoint= ")
147            .append(getEndPoint())
148            .append(']');
149
150        return sb.toString();
151    }
152
153    /** {@inheritDoc} */
154    @Override
155    boolean containsAbscissa(final double abscissa) {
156        return getLine().getPrecision().lte(abscissa, end);
157    }
158}