View Javadoc

1   /**
2    * File: 	CirculinearDomain2DUtils.java
3    * Project: javaGeom
4    * 
5    * Distributed under the LGPL License.
6    *
7    * Created: 16 mai 09
8    */
9   package math.geom2d.circulinear;
10  
11  import java.util.ArrayList;
12  import java.util.Collection;
13  
14  import math.geom2d.Shape2D;
15  
16  
17  /**
18   * Some utilities for working with circulinear curves.
19   * @author dlegland
20   *
21   */
22  public class CirculinearDomain2DUtils {
23  	
24  	public final static CirculinearDomain2D computeBuffer(
25  			CirculinearDomain2D domain, double dist) {
26  		
27  		ArrayList<CirculinearContour2D> rings =
28  			new ArrayList<CirculinearContour2D>();
29  		
30  		// iterate on all continuous curves
31  		for(CirculinearContour2D cont : 
32  			domain.getBoundary().getContinuousCurves()) {
33  			// split the curve into a set of non self-intersecting curves
34  			for(CirculinearContinuousCurve2D simpleCurve : 
35  				CirculinearCurve2DUtils.splitContinuousCurve(cont)) {
36  				CirculinearContour2D boundary = 
37  					new BoundaryPolyCirculinearCurve2D<CirculinearContinuousCurve2D>(
38  							simpleCurve.getSmoothPieces());
39  				// compute the rings composing the simple curve buffer
40  				rings.addAll(computeBufferSimpleRing(boundary, dist));
41  			}
42  		}
43  		
44  		// All the rings are created, we can now create a new domain with the
45  		// set of rings
46  		return new GenericCirculinearDomain2D(
47  				new CirculinearBoundarySet2D<CirculinearContour2D>(rings));
48  	}
49  	
50  	/**
51  	 * Computes the rings that form the domain of a circulinear curve which
52  	 * does not self-intersect.
53  	 */
54  	public final static Collection<CirculinearContour2D> 
55  	computeBufferSimpleRing(CirculinearContour2D curve, double d) {
56  		
57  		// prepare an array to store the set of rings
58  		ArrayList<CirculinearContour2D> rings =
59  			new ArrayList<CirculinearContour2D>();
60  		
61  		// the parallel in the positive side
62  		CirculinearContinuousCurve2D parallel1 = curve.getParallel(d);
63  		
64  		// split each parallel into continuous curves
65  		CirculinearCurveSet2D<CirculinearContinuousCurve2D> curves =
66  			new CirculinearCurveSet2D<CirculinearContinuousCurve2D>();
67  		
68  		// select only curve parts which do not cross original curve
69  		for(CirculinearContinuousCurve2D split : 
70  				CirculinearCurve2DUtils.splitContinuousCurve(parallel1)) {
71  			if(CirculinearCurve2DUtils.findIntersections(curve, split).size()==0)
72  				curves.addCurve(split);
73  		}
74  		
75  		// create a new boundary for each parallel curve
76  		for(CirculinearContinuousCurve2D split : curves) {
77  			rings.add(
78  					new BoundaryPolyCirculinearCurve2D<CirculinearContinuousCurve2D>(
79  							split.getSmoothPieces(), split.isClosed()));
80  		}
81  		
82  		// prepare an array to store the set of rings
83  		ArrayList<CirculinearContour2D> rings2 =
84  			new ArrayList<CirculinearContour2D>();
85  
86  		// iterate on the set of rings
87  		for(CirculinearContour2D ring : rings)
88  			// split rings into curves which do not self-intersect
89  			for(CirculinearContinuousCurve2D split : 
90  				CirculinearCurve2DUtils.splitContinuousCurve(ring)) {
91  				
92  				// compute distance to original curve
93  				// (assuming it is sufficient to compute distance to vertices
94  				// of the reference curve).
95  				double dist = CirculinearCurve2DUtils.getDistanceCurvePoints(
96  						curve, split.getSingularPoints());
97  				
98  				// check if distance condition is verified
99  				if(dist-d<-Shape2D.ACCURACY)
100 					continue;
101 				
102 				// convert the set of elements to a Circulinear ring
103 				rings2.add(
104 						new BoundaryPolyCirculinearCurve2D<CirculinearContinuousCurve2D>(
105 								split.getSmoothPieces(), split.isClosed()));
106 		}
107 		
108 		// return the set of created rings
109 		return rings2;
110 	}
111 }