Statistics
| Revision:

root / trunk / libraries / libDwg / src / com / iver / cit / jdwglib / util / GisModelCurveCalculator.java @ 23942

History | View | Annotate | Download (10.7 KB)

1
/* jdwglib. Java Library for reading Dwg files.
2
 * 
3
 * Author: Jose Morell Rama (jose.morell@gmail.com).
4
 * Port from the Pythoncad Dwg library by Art Haas.
5
 *
6
 * Copyright (C) 2005 Jose Morell, IVER TI S.A. and Generalitat Valenciana
7
 *
8
 * This program is free software; you can redistribute it and/or
9
 * modify it under the terms of the GNU General Public License
10
 * as published by the Free Software Foundation; either version 2
11
 * of the License, or (at your option) any later version.
12
 *
13
 * This program is distributed in the hope that it will be useful,
14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
 * GNU General Public License for more details.
17
 *
18
 * You should have received a copy of the GNU General Public License
19
 * along with this program; if not, write to the Free Software
20
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,USA.
21
 *
22
 * For more information, contact:
23
 *
24
 * Jose Morell (jose.morell@gmail.com)
25
 * 
26
 * or
27
 *
28
 * IVER TI S.A.
29
 *  C/Salamanca, 50
30
 *  46005 Valencia
31
 *  Spain
32
 *  +34 963163400
33
 *  dac@iver.es
34
 */
35
package com.iver.cit.jdwglib.util;
36

    
37
import java.awt.geom.Point2D;
38
import java.util.ArrayList;
39
import java.util.List;
40
import java.util.Vector;
41

    
42
/**
43
 * This class allows to obtain arcs and circles given by the most usual parameters, in a
44
 * Gis geometry model. In this model, an arc or a circle is given by a set of points that
45
 * defines it shape
46
 * 
47
 * @author jmorell
48
 */
49
public class GisModelCurveCalculator {
50
    
51
    /**
52
     * This method calculates an array of Point2D that represents a circle. The distance
53
     * between it points is 1 angular unit 
54
     * 
55
     * @param c Point2D that represents the center of the circle
56
     * @param r double value that represents the radius of the circle
57
     * @return Point2D[] An array of Point2D that represents the shape of the circle
58
     */
59
        public static List calculateGisModelCircle(Point2D c, double r) {
60
                List pts = new ArrayList();
61
                int angulo = 0;
62
                for (angulo=0; angulo<360; angulo++) {
63
                        double[] pt = new double[]{c.getX(), c.getY()};
64
                        pt[0] = pt[0] + r * Math.sin(angulo*Math.PI/(double)180.0);
65
                        pt[1] = pt[1] + r * Math.cos(angulo*Math.PI/(double)180.0);
66
                        
67
                        pts.add(pt);
68
                }
69
                return pts;
70
        }
71
        
72
    /**
73
     * This method calculates an array of Point2D that represents a ellipse. The distance
74
     * between it points is 1 angular unit 
75
     * 
76
     * @param center Point2D that represents the center of the ellipse
77
     * @param majorAxisVector Point2D that represents the vector for the major axis
78
     * @param axisRatio double value that represents the axis ratio
79
         * @param initAngle double value that represents the start angle of the ellipse arc
80
         * @param endAngle double value that represents the end angle of the ellipse arc
81
     * @return Point2D[] An array of Point2D that represents the shape of the ellipse
82
     */
83
        public static List calculateGisModelEllipse(Point2D center, Point2D majorAxisVector, double axisRatio, double initAngle, double endAngle) {
84
                Point2D majorPoint = new Point2D.Double(center.getX()+majorAxisVector.getX(), center.getY()+majorAxisVector.getY());
85
                double orientation  = Math.atan(majorAxisVector.getY()/majorAxisVector.getX());
86
            double semiMajorAxisLength = center.distance(majorPoint);
87
                double semiMinorAxisLength = semiMajorAxisLength*axisRatio;
88
            double eccentricity = Math.sqrt(1-((Math.pow(semiMinorAxisLength, 2))/(Math.pow(semiMajorAxisLength, 2))));
89
                int isa = (int)initAngle;
90
                int iea = (int)endAngle;
91
                double angulo;
92
                List pts = new ArrayList();
93
                if (initAngle <= endAngle) {
94
                        angulo = initAngle;
95
                        double r = semiMinorAxisLength/Math.sqrt(1-((Math.pow(eccentricity, 2))*(Math.pow(Math.cos(angulo*Math.PI/(double)180.0), 2))));
96
                    double x = r*Math.cos(angulo*Math.PI/(double)180.0);
97
                    double y = r*Math.sin(angulo*Math.PI/(double)180.0);
98
                    double xrot = x*Math.cos(orientation) - y*Math.sin(orientation);
99
                    double yrot = x*Math.sin(orientation) + y*Math.cos(orientation);
100
                        
101
                        double[] pt = new double[]{center.getX() + xrot, center.getY() + yrot };
102
                        pts.add(pt);
103
                        
104
                        for (int i=1; i<=(iea-isa)+1; i++) {
105
                                angulo = (double)(isa+i);
106
                                r = semiMinorAxisLength/Math.sqrt(1-((Math.pow(eccentricity, 2))*(Math.pow(Math.cos(angulo*Math.PI/(double)180.0), 2))));
107
                            x = r*Math.cos(angulo*Math.PI/(double)180.0);
108
                            y = r*Math.sin(angulo*Math.PI/(double)180.0);
109
                            xrot = x*Math.cos(orientation) - y*Math.sin(orientation);
110
                            yrot = x*Math.sin(orientation) + y*Math.cos(orientation);
111
                            
112
                            pt = new double[]{center.getX() + xrot, center.getY() + yrot};
113
                            pts.add(pt);
114
                        }
115
                        
116
                        angulo = endAngle;
117
                        r = semiMinorAxisLength/Math.sqrt(1-((Math.pow(eccentricity, 2))*(Math.pow(Math.cos(angulo*Math.PI/(double)180.0), 2))));
118
                    x = r*Math.cos(angulo*Math.PI/(double)180.0);
119
                    y = r*Math.sin(angulo*Math.PI/(double)180.0);
120
                    xrot = x*Math.cos(orientation) - y*Math.sin(orientation);
121
                    yrot = x*Math.sin(orientation) + y*Math.cos(orientation);
122
                    
123
                    
124
                    pt = new double[]{center.getX() + xrot, center.getY() + yrot};
125
                    pts.add(pt);
126
                    
127
                } else {
128
                        angulo = initAngle;
129
                        double r = semiMinorAxisLength/Math.sqrt(1-((Math.pow(eccentricity, 2))*(Math.pow(Math.cos(angulo*Math.PI/(double)180.0), 2))));
130
                    double x = r*Math.cos(angulo*Math.PI/(double)180.0);
131
                    double y = r*Math.sin(angulo*Math.PI/(double)180.0);
132
                    double xrot = x*Math.cos(orientation) - y*Math.sin(orientation);
133
                    double yrot = x*Math.sin(orientation) + y*Math.cos(orientation);
134
                    
135
                  
136
                        double[] pt = new double[]{center.getX() + r*Math.cos(angulo*Math.PI/(double)180.0), center.getY() + r*Math.sin(angulo*Math.PI/(double)180.0)};
137
                    pts.add(pt);
138
                    
139
                    for (int i=1; i<=(360-isa); i++) {
140
                                angulo = (double)(isa+i);
141
                                r = semiMinorAxisLength/Math.sqrt(1-((Math.pow(eccentricity, 2))*(Math.pow(Math.cos(angulo*Math.PI/(double)180.0), 2))));
142
                            x = r*Math.cos(angulo*Math.PI/(double)180.0);
143
                            y = r*Math.sin(angulo*Math.PI/(double)180.0);
144
                            xrot = x*Math.cos(orientation) - y*Math.sin(orientation);
145
                            yrot = x*Math.sin(orientation) + y*Math.cos(orientation);
146
                            
147
                            pt = new double[]{center.getX() + xrot, center.getY() + yrot};
148
                            pts.add(pt);
149
                        }
150
                    
151
                    
152
                        for (int i=(360-isa)+1; i<=(360-isa)+iea; i++) {
153
                                angulo = (double)(i-(360-isa));
154
                                r = semiMinorAxisLength/Math.sqrt(1-((Math.pow(eccentricity, 2))*(Math.pow(Math.cos(angulo*Math.PI/(double)180.0), 2))));
155
                            x = r*Math.cos(angulo*Math.PI/(double)180.0);
156
                            y = r*Math.sin(angulo*Math.PI/(double)180.0);
157
                            xrot = x*Math.cos(orientation) - y*Math.sin(orientation);
158
                            yrot = x*Math.sin(orientation) + y*Math.cos(orientation);
159
                            
160
                            pt = new double[]{center.getX() + xrot, center.getY() + yrot};
161
                            pts.add(pt);
162
                            
163
                        }
164
                        
165
                        angulo = endAngle;
166
                        r = semiMinorAxisLength/Math.sqrt(1-((Math.pow(eccentricity, 2))*(Math.pow(Math.cos(angulo*Math.PI/(double)180.0), 2))));
167
                    x = r*Math.cos(angulo*Math.PI/(double)180.0);
168
                    y = r*Math.sin(angulo*Math.PI/(double)180.0);
169
                    xrot = x*Math.cos(orientation) - y*Math.sin(orientation);
170
                    yrot = x*Math.sin(orientation) + y*Math.cos(orientation);
171
                    
172
                    pt = new double[]{center.getX() + xrot, center.getY() + yrot};
173
                    pts.add(pt);
174
                }
175
                return pts;
176
        }
177
        
178
        /**
179
     * This method calculates an array of Point2D that represents an arc. The distance
180
     * between it points is 1 angular unit 
181
         * 
182
     * @param c Point2D that represents the center of the arc
183
     * @param r double value that represents the radius of the arc
184
         * @param sa double value that represents the start angle of the arc
185
         * @param ea double value that represents the end angle of the arc
186
     * @return Point2D[] An array of Point2D that represents the shape of the arc
187
         */
188
        public static List calculateGisModelArc(double[] center, double r, double sa, double ea) {
189
                int isa = (int)sa;
190
                int iea = (int)ea;
191
                double angulo;
192
                List pts = new ArrayList();
193
                if (sa <= ea) {
194
                        angulo = sa;
195
                        pts.add(new double[]{center[0] + r * Math.cos(angulo*Math.PI/(double)180.0), 
196
                                        center[1] + r * Math.sin(angulo*Math.PI/(double)180.0)});
197
                        for (int i=1; i <= (iea-isa)+1; i++) {
198
                                angulo = (double)(isa+i);
199
                                double x = center[0] + r * Math.cos(angulo*Math.PI/(double)180.0);
200
                                double y = center[1] + r * Math.sin(angulo*Math.PI/(double)180.0);
201
                                pts.add(new double[]{x, y});
202
                        }
203
                        angulo = ea;
204
                        double x = center[0] + r * Math.cos(angulo*Math.PI/(double)180.0);
205
                        double y = center[1] + r * Math.sin(angulo*Math.PI/(double)180.0);
206
                        pts.add(new double[]{x, y});
207
                } else {
208
                        angulo = sa;
209
                        double x = center[0] + r * Math.cos(angulo*Math.PI/(double)180.0);
210
                        double y = center[1] + r * Math.sin(angulo*Math.PI/(double)180.0);
211
                        pts.add(new double[]{x, y});
212
                        for (int i=1; i <= (360-isa); i++) {
213
                                angulo = (double)(isa+i);
214
                                x = center[0] + r * Math.cos(angulo*Math.PI/(double)180.0);
215
                                y = center[1] + r * Math.sin(angulo*Math.PI/(double)180.0); 
216
                                pts.add(new double[]{x, y});
217
                        }
218
                        
219
                        for (int i=( 360-isa)+1; i <= (360-isa)+iea; i++) {
220
                                angulo = (double)(i-(360-isa));
221
                                x = center[0] + r * Math.cos(angulo*Math.PI/(double)180.0);
222
                                y = center[1] + r * Math.sin(angulo*Math.PI/(double)180.0);
223
                                pts.add(new double[]{x, y});
224
                        }
225
                        angulo = ea;
226
                        x = center[0] + r * Math.cos(angulo*Math.PI/(double)180.0);
227
                        y = center[1] + r * Math.sin(angulo*Math.PI/(double)180.0);
228
                        pts.add(new double[]{x, y});
229
                }
230
                return pts;
231
        }
232
        
233
        /**
234
         * This method applies an array of bulges to an array of Point2D that defines a
235
         * polyline. The result is a polyline with the input points with the addition of the
236
         * points that define the new arcs added to the polyline
237
         * 
238
         * @param newPts Base points of the polyline
239
         * @param bulges Array of bulge parameters
240
         * @return Polyline with a new set of arcs added and defined by the bulge parameters
241
         */
242
        public static List calculateGisModelBulge(List newPts, double[] bulges) {
243
                Vector ptspol = new Vector();
244
                double[] init = null;
245
                double[] end = null;
246
                for (int j=0; j<newPts.size(); j++) {
247
                        init = (double[]) newPts.get(j);
248
                        if (j != newPts.size()-1) 
249
                                end = (double[]) newPts.get(j+1);
250
                        if (bulges[j]==0 || j== newPts.size()-1 || 
251
                                (init[0] == end[0] && init[1] == end[1])) {
252
                                ptspol.add(init);
253
                        } else {
254
                                ArcFromBulgeCalculator arcCalculator = new ArcFromBulgeCalculator(init, end, bulges[j]);
255
                                Vector arc = arcCalculator.getPoints(1);
256
                                if (bulges[j]<0) {
257
                                        for (int k=arc.size()-1; k>=0; k--) {
258
                                                ptspol.add(arc.get(k));
259
                                        }
260
                                        ptspol.remove(ptspol.size()-1);
261
                                } else {
262
                                        for (int k=0;k<arc.size();k++) {
263
                                                ptspol.add(arc.get(k));
264
                                        }
265
                                        ptspol.remove(ptspol.size()-1);
266
                                }
267
                        }
268
                }
269
                List points = new ArrayList();
270
                for (int j=0;j<ptspol.size();j++) {
271
                        points.add(ptspol.get(j));
272
                }
273
                return points;
274
        }
275
}