View Javadoc

1   /* file : BoundarySet2D.java
2    * 
3    * Project : geometry
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   * Created on 1 mai 2006
24   *
25   */
26  
27  package math.geom2d.domain;
28  
29  import java.awt.Graphics2D;
30  import java.util.ArrayList;
31  import java.util.Collection;
32  
33  import math.geom2d.AffineTransform2D;
34  import math.geom2d.Box2D;
35  import math.geom2d.curve.*;
36  
37  /**
38   * A BoundarySet2D is a set of continuous oriented curves. Each curve of the set
39   * defines its own domain.
40   * <p>
41   * 
42   * @author dlegland
43   */
44  public class BoundarySet2D<T extends ContinuousBoundary2D> 
45  extends CurveArray2D<T> implements Boundary2D {
46  
47      // ===================================================================
48      // Constructors
49  
50      public BoundarySet2D() {
51      }
52  
53      public BoundarySet2D(int size) {
54      	super(size);
55      }
56  
57      public BoundarySet2D(T[] curves) {
58          super(curves);
59      }
60  
61      public BoundarySet2D(Collection<? extends T> curves) {
62          super(curves);
63      }
64  
65      public BoundarySet2D(T curve) {
66          super();
67          this.addCurve(curve);
68      }
69  
70      
71      // ===================================================================
72      // static methods
73  
74      /**
75       * Static factory for creating a new PolyCurve2D from a collection of
76       * curves.
77       * @since 0.8.1
78       */
79      public static <T extends ContinuousBoundary2D> BoundarySet2D<T> create(
80      		Collection<T> curves) {
81      	return new BoundarySet2D<T>(curves);
82      }
83      
84      /**
85       * Static factory for creating a new PolyCurve2D from an array of
86       * curves.
87       * @since 0.8.1
88       */
89      public static <T extends ContinuousBoundary2D> BoundarySet2D<T> create(
90      		T[] curves) {
91      	return new BoundarySet2D<T>(curves);
92      }
93  
94      // ===================================================================
95      // Methods implementing Boundary2D interface
96  
97      public Collection<ContinuousBoundary2D> getBoundaryCurves() {
98          ArrayList<ContinuousBoundary2D> list = 
99          	new ArrayList<ContinuousBoundary2D>(curves.size());
100         for (Curve2D curve : this.curves)
101             list.add((ContinuousBoundary2D) curve);
102         return list;
103     }
104 
105     public Domain2D getDomain() {
106         return new GenericDomain2D(this);
107     }
108 
109     public void fill(Graphics2D g2) {
110         g2.fill(this.getGeneralPath());
111     }
112 
113     // ===================================================================
114     // Methods implementing OrientedCurve2D interface
115 
116     public double getWindingAngle(java.awt.geom.Point2D point) {
117         double angle = 0;
118         for (OrientedCurve2D curve : this.getCurves())
119             angle += curve.getWindingAngle(point);
120         return angle;
121     }
122 
123     public double getSignedDistance(java.awt.geom.Point2D p) {
124         return getSignedDistance(p.getX(), p.getY());
125     }
126 
127     /*
128      * (non-Javadoc)
129      * 
130      * @see math.geom2d.Shape2D#getSignedDistance(math.geom2d.Point2D)
131      */
132     public double getSignedDistance(double x, double y) {
133         double minDist = Double.POSITIVE_INFINITY;
134         double dist = Double.POSITIVE_INFINITY;
135 
136         for (OrientedCurve2D curve : this.getCurves()) {
137             dist = Math.min(dist, curve.getSignedDistance(x, y));
138             if (Math.abs(dist)<Math.abs(minDist))
139                 minDist = dist;
140         }
141         return minDist;
142     }
143 
144     public boolean isInside(java.awt.geom.Point2D point) {
145         return this.getSignedDistance(point.getX(), point.getY())<0;
146     }
147 
148     // ===================================================================
149     // Methods implementing Curve2D interface
150 
151     @Override
152     public BoundarySet2D<? extends ContinuousBoundary2D> getReverseCurve() {
153         ContinuousBoundary2D[] curves2 = new ContinuousBoundary2D[curves.size()];
154         int n = curves.size();
155         for (int i = 0; i<n; i++)
156             curves2[i] = (ContinuousBoundary2D)curves.get(n-1-i).getReverseCurve();
157         return new BoundarySet2D<ContinuousBoundary2D>(curves2);
158     }
159 
160     @Override
161     public CurveSet2D<? extends ContinuousOrientedCurve2D> getSubCurve(
162             double t0, double t1) {
163         // get the subcurve
164         CurveSet2D<? extends Curve2D> curveSet = super.getSubCurve(t0, t1);
165 
166         // create subcurve array
167         ArrayList<ContinuousOrientedCurve2D> curves = 
168         	new ArrayList<ContinuousOrientedCurve2D>();
169         for (Curve2D curve : curveSet.getCurves())
170             curves.add((ContinuousOrientedCurve2D) curve);
171 
172         // Create CurveSet for the result
173         return new CurveArray2D<ContinuousOrientedCurve2D>(curves);
174     }
175 
176     // ===================================================================
177     // Methods implementing the Shape2D interface
178 
179     /**
180      * Clip the curve by a box. The result is an instance of
181      * CurveSet2D<ContinuousOrientedCurve2D>, which contains
182      * only instances of ContinuousOrientedCurve2D. 
183      * If the curve is not clipped, the result is an instance of 
184      * CurveSet2D<ContinuousOrientedCurve2D> which contains 0 curves.
185      */
186     @Override
187     public CurveSet2D<? extends ContinuousOrientedCurve2D> clip(Box2D box) {
188         // Clip the curve
189         CurveSet2D<? extends Curve2D> set = Curve2DUtils.clipCurve(this, box);
190 
191         // Stores the result in appropriate structure
192         CurveArray2D<ContinuousOrientedCurve2D> result = 
193         	new CurveArray2D<ContinuousOrientedCurve2D>(set.getCurveNumber());
194 
195         // convert the result
196         for (Curve2D curve : set.getCurves()) {
197             if (curve instanceof ContinuousOrientedCurve2D)
198                 result.addCurve((ContinuousOrientedCurve2D) curve);
199         }
200         return result;
201     }
202 
203     @Override
204     public BoundarySet2D<? extends ContinuousBoundary2D> transform(
205             AffineTransform2D trans) {
206         BoundarySet2D<ContinuousBoundary2D> result = 
207         	new BoundarySet2D<ContinuousBoundary2D>(curves.size());
208         for (Curve2D curve : curves)
209             result.addCurve((ContinuousBoundary2D) curve.transform(trans));
210         return result;
211     }
212 }