View Javadoc

1   /* File InvertedRay2D.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   * Inverted ray is defined from an origin and a direction vector. It is composed
41   * 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 -INFINITY and 0.
46   * This is complementary class to Ray2D.
47   */
48  public class InvertedRay2D extends AbstractLine2D implements Cloneable {
49  
50      // ===================================================================
51      // constants
52  
53      // ===================================================================
54      // class variables
55  
56      // ===================================================================
57      // constructors
58  
59      /**
60       * Empty constructor for Ray2D. Default is ray starting at origin, and
61       * having a slope of 1*dx and 0*dy.
62       */
63      public InvertedRay2D() {
64          this(0, 0, 1, 0);
65      }
66  
67      /**
68       * Creates a new Ray2D, originating from
69       * <code>point1<\code>, and going in the
70       * direction of <code>point2<\code>.
71       */
72      public InvertedRay2D(Point2D point1, Point2D point2) {
73          this(point1.getX(), point1.getY(), 
74          		point2.getX()-point1.getX(), 
75          		point2.getY()-point1.getY());
76      }
77  
78      /**
79       * Creates a new Ray2D, originating from point
80       * <code>(x1,y1)<\code>, and going 
81       * in the direction defined by vector <code>(dx, dy)<\code>.
82       */
83      public InvertedRay2D(double x1, double y1, double dx, double dy) {
84          super(x1, y1, dx, dy);
85      }
86  
87      /**
88       * Creates a new Ray2D, originating from point <code>point<\code>, and going 
89       * in the direction defined by vector <code>(dx,dy)<\code>.
90       */
91      public InvertedRay2D(Point2D point, double dx, double dy) {
92          this(point.getX(), point.getY(), dx, dy);
93      }
94  
95      /**
96       * Creates a new Ray2D, originating from point <code>point<\code>, and going 
97       * in the direction specified by <code>vector<\code>.
98       */
99      public InvertedRay2D(Point2D point, Vector2D vector) {
100         this(point.getX(), point.getY(), vector.getX(), vector.getY());
101     }
102 
103     /**
104      * Creates a new Ray2D, originating from point <code>point<\code>, and going 
105      * in the direction specified by <code>angle<\code> (in radians).
106      */
107     public InvertedRay2D(Point2D point, double angle) {
108         this(point.getX(), point.getY(), Math.cos(angle), Math.sin(angle));
109     }
110 
111     /**
112      * Creates a new Ray2D, originating from point
113      * <code>(x, y)<\code>, and going 
114      * in the direction specified by <code>angle<\code> (in radians).
115      */
116     public InvertedRay2D(double x, double y, double angle) {
117         this(x, y, Math.cos(angle), Math.sin(angle));
118     }
119 
120     /**
121      * Define a new Ray, with same characteristics as given object.
122      */
123     public InvertedRay2D(LinearShape2D line) {
124         super(line);
125     }
126 
127     // ===================================================================
128     // Static factory
129 
130     /**
131      * Static factory for creating a new inverted ray with given direction
132      * to target.
133      * @since 0.8.1
134      */
135     public final static InvertedRay2D create(Point2D target, Vector2D direction) {
136     	return new InvertedRay2D(target, direction);
137     }
138     
139     
140     // ===================================================================
141     // methods specific to InvertedRay2D
142 
143     /**
144      * @deprecated lines will become immutable in a future release
145      */
146     @Deprecated
147     public void setRay(double x0, double y0, double dx, double dy) {
148         this.x0 = x0;
149         this.y0 = y0;
150         this.dx = dx;
151         this.dy = dy;
152     }
153 
154     /**
155      * @deprecated lines will become immutable in a future release
156      */
157     @Deprecated
158     public void setRay(Point2D p1, Point2D p2) {
159         this.x0 = p1.getX();
160         this.y0 = p1.getY();
161         this.dx = p2.getX()-this.x0;
162         this.dy = p2.getY()-this.y0;
163     }
164 
165     /**
166      * @deprecated lines will become immutable in a future release
167      */
168     @Deprecated
169     public void setRay(Point2D point, Vector2D vect) {
170         this.x0 = point.getX();
171         this.y0 = point.getY();
172         this.dx = vect.getX();
173         this.dy = vect.getY();
174     }
175 
176     // ===================================================================
177     // methods implementing the CirculinearCurve2D interface
178 
179 	/* (non-Javadoc)
180 	 * @see math.geom2d.circulinear.CirculinearCurve2D#getParallel(double)
181 	 */
182 	public InvertedRay2D getParallel(double d) {
183         double dd = Math.sqrt(dx*dx+dy*dy);
184         return new InvertedRay2D(x0+dy*d/dd, y0-dx*d/dd, dx, dy);
185 	}
186 
187     // ===================================================================
188     // methods implementing the ContinuousCurve2D interface
189 
190     /** Throws an infiniteShapeException */
191     public GeneralPath appendPath(GeneralPath path) {
192         throw new UnboundedShapeException(this);
193     }
194 
195     /** Throws an infiniteShapeException */
196     public java.awt.geom.GeneralPath getGeneralPath() {
197         throw new UnboundedShapeException(this);
198     }
199 
200     // ===================================================================
201     // methods implementing the Curve2D interface
202 
203     public Point2D getPoint(double t) {
204         t = Math.min(t, 0);
205         return new Point2D(x0+t*dx, y0+t*dy);
206     }
207 
208     public double getT0() {
209         return Double.NEGATIVE_INFINITY;
210     }
211 
212     public double getT1() {
213         return 0;
214     }
215 
216     public Ray2D getReverseCurve() {
217         return new Ray2D(x0, y0, -dx, -dy);
218     }
219 
220     // ===================================================================
221     // methods implementing the Shape2D interface
222 
223     /** Always returns false, because n inverted ray is not bounded. */
224     public boolean isBounded() {
225         return false;
226     }
227 
228     public boolean contains(double x, double y) {
229         if (!this.supportContains(x, y))
230             return false;
231         double t = this.getPositionOnLine(x, y);
232         return t<Shape2D.ACCURACY;
233     }
234 
235     public Box2D getBoundingBox() {
236         double t = Double.NEGATIVE_INFINITY;
237         return new Box2D(x0+t*dx, x0, y0+t*dy, y0);
238     }
239 
240     @Override
241     public InvertedRay2D transform(AffineTransform2D trans) {
242         double[] tab = trans.getCoefficients();
243         double x1 = x0*tab[0]+y0*tab[1]+tab[2];
244         double y1 = x0*tab[3]+y0*tab[4]+tab[5];
245         return new InvertedRay2D(x1, y1, dx*tab[0]+dy*tab[1], dx*tab[3]+dy
246                 *tab[4]);
247     }
248 
249     // ===================================================================
250     // methods implementing the Shape interface
251 
252     // ===================================================================
253     // methods implementing the Object interface
254 
255     @Override
256     public String toString() {
257         return new String("InvertedRay2D(" + x0 + "," + y0 + "," + 
258         		dx + "," + dy + ")");
259     }
260     
261     @Override
262     public boolean equals(Object obj) {
263         if (!(obj instanceof InvertedRay2D))
264             return false;
265         InvertedRay2D ray = (InvertedRay2D) obj;
266         if (Math.abs(x0-ray.x0)>Shape2D.ACCURACY)
267             return false;
268         if (Math.abs(y0-ray.y0)>Shape2D.ACCURACY)
269             return false;
270         if (Math.abs(dx-ray.dx)>Shape2D.ACCURACY)
271             return false;
272         if (Math.abs(dy-ray.dy)>Shape2D.ACCURACY)
273             return false;
274         return true;
275     }
276 
277     @Override
278     public InvertedRay2D clone() {
279         return new InvertedRay2D(x0, y0, dx, dy);
280     }
281 
282 }