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 ray in 3D Euclidean space. A ray is a portion of a line consisting of
24 * a single start point and extending to infinity along the direction of the line.
25 *
26 * <p>Instances of this class are guaranteed to be immutable.</p>
27 * @see ReverseRay3D
28 * @see Lines3D
29 * @see <a href="https://en.wikipedia.org/wiki/Line_(geometry)#Ray">Ray</a>
30 */
31 public final class Ray3D extends LineConvexSubset3D {
32
33 /** The start abscissa value for the ray. */
34 private final double start;
35
36 /** Construct a ray from a line and a start point. The start point is projected
37 * onto the line. No validation is performed.
38 * @param line line for the ray
39 * @param startPoint start point for the ray
40 */
41 Ray3D(final Line3D line, final Vector3D startPoint) {
42 this(line, line.abscissa(startPoint));
43 }
44
45 /** Construct a ray from a line and a 1D start location. No validation is performed.
46 * @param line line for the ray
47 * @param start 1D start location
48 */
49 Ray3D(final Line3D line, final double start) {
50 super(line);
51
52 this.start = start;
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 @Override
83 public Vector3D getStartPoint() {
84 return getLine().toSpace(start);
85 }
86
87 /** {@inheritDoc} */
88 @Override
89 public double getSubspaceStart() {
90 return start;
91 }
92
93 /** {@inheritDoc}
94 *
95 * <p>This method always returns {@code null}.</p>
96 */
97 @Override
98 public Vector3D getEndPoint() {
99 return null;
100 }
101
102 /** {@inheritDoc}
103 *
104 * <p>This method always returns {@link Double#POSITIVE_INFINITY}.</p>
105 */
106 @Override
107 public double getSubspaceEnd() {
108 return Double.POSITIVE_INFINITY;
109 }
110
111 /** {@inheritDoc}
112 *
113 * <p>This method always returns {@code null}.</p>
114 */
115 @Override
116 public Vector3D getCentroid() {
117 return null; // infinite; no center
118 }
119
120 /** {@inheritDoc}
121 *
122 * <p>This method always returns {@code null}.</p>
123 */
124 @Override
125 public Bounds3D getBounds() {
126 return null; // infinite; no bounds
127 }
128
129 /** Get the direction of the ray. This is a convenience method for {@code ray.getLine().getDirection()}.
130 * @return the direction of the ray
131 */
132 public Vector3D getDirection() {
133 return getLine().getDirection();
134 }
135
136 /** {@inheritDoc} */
137 @Override
138 public Ray3D transform(final Transform<Vector3D> transform) {
139 final Line3D tLine = getLine().transform(transform);
140 final Vector3D tStart = transform.apply(getStartPoint());
141
142 return new Ray3D(tLine, tStart);
143 }
144
145 /** {@inheritDoc} */
146 @Override
147 public String toString() {
148 final StringBuilder sb = new StringBuilder();
149 sb.append(getClass().getSimpleName())
150 .append("[startPoint= ")
151 .append(getStartPoint())
152 .append(", direction= ")
153 .append(getLine().getDirection())
154 .append(']');
155
156 return sb.toString();
157 }
158
159 /** {@inheritDoc} */
160 @Override
161 boolean containsAbscissa(final double abscissa) {
162 return getLine().getPrecision().gte(abscissa, start);
163 }
164 }