1 /* File Ray2D.java
2 *
3 * Project : Java Geometry Library
4 *
5 * ===========================================
6 *
7 * This library is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU Lesser General Public License as published by
9 * the Free Software Foundation, either version 2.1 of the License, or (at
10 * your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY, without even the implied warranty of MERCHANTABILITY
14 * or FITNESS FOR A PARTICULAR PURPOSE.
15 *
16 * See the GNU Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public License
19 * along with this library. if not, write to :
20 * The Free Software Foundation, Inc., 59 Temple Place, Suite 330,
21 * Boston, MA 02111-1307, USA.
22 */
23
24 // package
25
26 package math.geom2d.line;
27
28 import java.awt.geom.GeneralPath;
29
30 import math.geom2d.AffineTransform2D;
31 import math.geom2d.Box2D;
32 import math.geom2d.Point2D;
33 import math.geom2d.Shape2D;
34 import math.geom2d.UnboundedShapeException;
35 import math.geom2d.Vector2D;
36
37 // Imports
38
39 /**
40 * Ray, or half-line, defined from an origin and a direction vector. It is
41 * composed of all points satisfying the parametric equation:
42 * <p>
43 * <code>x(t) = x0+t*dx<code><br>
44 * <code>y(t) = y0+t*dy<code></p>
45 * With <code>t<code> comprised between 0 and +INFINITY.
46 */
47 public class Ray2D extends AbstractLine2D implements Cloneable {
48
49 // ===================================================================
50 // constants
51
52 // ===================================================================
53 // class variables
54
55 // ===================================================================
56 // constructors
57
58 /**
59 * Empty constructor for Ray2D. Default is ray starting at origin, and
60 * having a slope of 1*dx and 0*dy.
61 */
62 public Ray2D() {
63 this(0, 0, 1, 0);
64 }
65
66 /**
67 * Creates a new Ray2D, originating from
68 * <code>point1<\code>, and going in the
69 * direction of <code>point2<\code>.
70 */
71 public Ray2D(Point2D point1, Point2D point2) {
72 this(point1.getX(), point1.getY(),
73 point2.getX()-point1.getX(),
74 point2.getY()-point1.getY());
75 }
76
77 /**
78 * Creates a new Ray2D, originating from point
79 * <code>(x1,y1)<\code>, and going
80 * in the direction defined by vector <code>(dx, dy)<\code>.
81 */
82 public Ray2D(double x1, double y1, double dx, double dy) {
83 super(x1, y1, dx, dy);
84 }
85
86 /**
87 * Creates a new Ray2D, originating from point <code>point<\code>, and going
88 * in the direction defined by vector <code>(dx,dy)<\code>.
89 */
90 public Ray2D(Point2D point, double dx, double dy) {
91 this(point.getX(), point.getY(), dx, dy);
92 }
93
94 /**
95 * Creates a new Ray2D, originating from point <code>point<\code>, and going
96 * in the direction specified by <code>vector<\code>.
97 */
98 public Ray2D(Point2D point, Vector2D vector) {
99 this(point.getX(), point.getY(), vector.getX(), vector.getY());
100 }
101
102 /**
103 * Creates a new Ray2D, originating from point <code>point<\code>, and going
104 * in the direction specified by <code>angle<\code> (in radians).
105 */
106 public Ray2D(Point2D point, double angle) {
107 this(point.getX(), point.getY(), Math.cos(angle), Math.sin(angle));
108 }
109
110 /**
111 * Creates a new Ray2D, originating from point
112 * <code>(x, y)<\code>, and going
113 * in the direction specified by <code>angle<\code> (in radians).
114 */
115 public Ray2D(double x, double y, double angle) {
116 this(x, y, Math.cos(angle), Math.sin(angle));
117 }
118
119 /**
120 * Define a new Ray, with same characteristics as given object.
121 */
122 public Ray2D(LinearShape2D line) {
123 super(line);
124 }
125
126 // ===================================================================
127 // methods specific to Ray2D
128
129 /**
130 * Static factory for creating a new ray.
131 * @since 0.8.1
132 */
133 public final static Ray2D create(Point2D origin, Vector2D direction) {
134 return new Ray2D(origin, direction);
135 }
136
137 /**
138 * Static factory for creating a new ray, originating from
139 * <code>origin<\code>, and going in the
140 * direction of <code>target<\code>.
141 * @since 0.8.1
142 */
143 public final static Ray2D create(Point2D origin, Point2D target) {
144 return new Ray2D(origin, target);
145 }
146
147 /**
148 * @deprecated lines will become immutable in a future release
149 */
150 @Deprecated
151 public void setRay(double x0, double y0, double dx, double dy) {
152 this.x0 = x0;
153 this.y0 = y0;
154 this.dx = dx;
155 this.dy = dy;
156 }
157
158 /**
159 * @deprecated lines will become immutable in a future release
160 */
161 @Deprecated
162 public void setRay(Point2D p1, Point2D p2) {
163 this.x0 = p1.getX();
164 this.y0 = p1.getY();
165 this.dx = p2.getX()-this.x0;
166 this.dy = p2.getY()-this.y0;
167 }
168
169 /**
170 * @deprecated lines will become immutable in a future release
171 */
172 @Deprecated
173 public void setRay(Point2D point, Vector2D vect) {
174 this.x0 = point.getX();
175 this.y0 = point.getY();
176 this.dx = vect.getX();
177 this.dy = vect.getY();
178 }
179
180
181 // ===================================================================
182 // methods implementing the CirculinearCurve2D interface
183
184 /* (non-Javadoc)
185 * @see math.geom2d.circulinear.CirculinearCurve2D#getParallel(double)
186 */
187 public Ray2D getParallel(double d) {
188 double dd = Math.sqrt(dx*dx+dy*dy);
189 return new Ray2D(x0+dy*d/dd, y0-dx*d/dd, dx, dy);
190 }
191
192 // ===================================================================
193 // methods implementing the ContinuousCurve2D interface
194
195 /** Throws an infiniteShapeException */
196 public GeneralPath appendPath(GeneralPath path) {
197 throw new UnboundedShapeException(this);
198 }
199
200 /** Throws an infiniteShapeException */
201 public java.awt.geom.GeneralPath getGeneralPath() {
202 throw new UnboundedShapeException(this);
203 }
204
205 // ===================================================================
206 // methods implementing the Curve2D interface
207
208 @Override
209 public Point2D getFirstPoint() {
210 return new Point2D(x0, y0);
211 }
212
213 public Point2D getPoint(double t) {
214 t = Math.max(t, 0);
215 return new Point2D(x0+t*dx, y0+t*dy);
216 }
217
218 public double getT0() {
219 return 0;
220 }
221
222 public double getT1() {
223 return Double.POSITIVE_INFINITY;
224 }
225
226 public InvertedRay2D getReverseCurve() {
227 return new InvertedRay2D(x0, y0, -dx, -dy);
228 }
229
230 // ===================================================================
231 // methods implementing the Shape2D interface
232
233 /** Always returns false, because a ray is not bounded. */
234 public boolean isBounded() {
235 return false;
236 }
237
238 public boolean contains(double x, double y) {
239 if (!this.supportContains(x, y))
240 return false;
241 double t = this.getPositionOnLine(x, y);
242 return t>-Shape2D.ACCURACY;
243 }
244
245 public Box2D getBoundingBox() {
246 double t = Double.POSITIVE_INFINITY;
247 return new Box2D(x0, x0+t*dx, y0, y0+t*dy);
248 }
249
250 @Override
251 public Ray2D transform(AffineTransform2D trans) {
252 double[] tab = trans.getCoefficients();
253 double x1 = x0*tab[0]+y0*tab[1]+tab[2];
254 double y1 = x0*tab[3]+y0*tab[4]+tab[5];
255 return new Ray2D(x1, y1, dx*tab[0]+dy*tab[1], dx*tab[3]+dy*tab[4]);
256 }
257
258
259 // ===================================================================
260 // methods implementing the Object interface
261
262 @Override
263 public String toString() {
264 return new String("Ray2D(" + x0 + "," + y0 + "," +
265 dx + "," + dy + ")");
266 }
267
268 @Override
269 public boolean equals(Object obj) {
270 if (!(obj instanceof Ray2D))
271 return false;
272 Ray2D ray = (Ray2D) obj;
273 if (Math.abs(x0-ray.x0)>Shape2D.ACCURACY)
274 return false;
275 if (Math.abs(y0-ray.y0)>Shape2D.ACCURACY)
276 return false;
277 if (Math.abs(dx-ray.dx)>Shape2D.ACCURACY)
278 return false;
279 if (Math.abs(dy-ray.dy)>Shape2D.ACCURACY)
280 return false;
281 return true;
282 }
283
284 @Override
285 public Ray2D clone() {
286 return new Ray2D(x0, y0, dx, dy);
287
288 }
289 }