1 /*
2 * Licensed to the Apache Software Foundation (ASF) under one or more
3 * contributor license agreements. See the NOTICE file distributed with
4 * this work for additional information regarding copyright ownership.
5 * The ASF licenses this file to You under the Apache License, Version 2.0
6 * (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17 package org.apache.commons.geometry.euclidean.threed.line;
18
19 import org.apache.commons.geometry.core.Transform;
20 import org.apache.commons.geometry.euclidean.threed.Bounds3D;
21 import org.apache.commons.geometry.euclidean.threed.Vector3D;
22
23 /** Class representing a portion of a line in 3D Euclidean space that starts at infinity and
24 * continues in the direction of the line up to a single end point. This is equivalent to taking a
25 * {@link Ray3D} and reversing the line direction.
26 *
27 * <p>Instances of this class are guaranteed to be immutable.</p>
28 * @see Ray3D
29 * @see Lines3D
30 */
31 public final class ReverseRay3D extends LineConvexSubset3D {
32
33 /** The abscissa of the line subset endpoint. */
34 private final double end;
35
36 /** Construct a new instance from the given line and end point. The end point is projected onto
37 * the line. No validation is performed.
38 * @param line line for the instance
39 * @param endPoint end point for the instance
40 */
41 ReverseRay3D(final Line3D line, final Vector3D endPoint) {
42 this(line, line.abscissa(endPoint));
43 }
44
45 /** Construct a new instance from the given line and 1D end location. No validation is performed.
46 * @param line line for the instance
47 * @param end end location for the instance
48 */
49 ReverseRay3D(final Line3D line, final double end) {
50 super(line);
51
52 this.end = end;
53 }
54
55 /** {@inheritDoc}
56 *
57 * <p>This method always returns {@code true}.</p>
58 */
59 @Override
60 public boolean isInfinite() {
61 return true;
62 }
63
64 /** {@inheritDoc}
65 *
66 * <p>This method always returns {@code false}.</p>
67 */
68 @Override
69 public boolean isFinite() {
70 return false;
71 }
72
73 /** {@inheritDoc}
74 *
75 * <p>This method always returns {@link Double#POSITIVE_INFINITY}.</p>
76 */
77 @Override
78 public double getSize() {
79 return Double.POSITIVE_INFINITY;
80 }
81
82 /** {@inheritDoc}
83 *
84 * <p>This method always returns {@code null}.</p>
85 */
86 @Override
87 public Vector3D getStartPoint() {
88 return null;
89 }
90
91 /** {@inheritDoc}
92 *
93 * <p>This method always returns {@link Double#NEGATIVE_INFINITY}.</p>
94 */
95 @Override
96 public double getSubspaceStart() {
97 return Double.NEGATIVE_INFINITY;
98 }
99
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 }