Statistics
| Revision:

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

History | View | Annotate | Download (10.7 KB)

1 9720 azabala
/* 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 10632 azabala
import java.util.ArrayList;
39
import java.util.List;
40 9720 azabala
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 23942 vcaballero
        public static List calculateGisModelCircle(Point2D c, double r) {
60
                List pts = new ArrayList();
61 9720 azabala
                int angulo = 0;
62
                for (angulo=0; angulo<360; angulo++) {
63 10632 azabala
                        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 9720 azabala
                }
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 10632 azabala
        public static List calculateGisModelEllipse(Point2D center, Point2D majorAxisVector, double axisRatio, double initAngle, double endAngle) {
84 9720 azabala
                Point2D majorPoint = new Point2D.Double(center.getX()+majorAxisVector.getX(), center.getY()+majorAxisVector.getY());
85 10632 azabala
                double orientation  = Math.atan(majorAxisVector.getY()/majorAxisVector.getX());
86 9720 azabala
            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 23942 vcaballero
                List pts = new ArrayList();
93 9720 azabala
                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 10632 azabala
101
                        double[] pt = new double[]{center.getX() + xrot, center.getY() + yrot };
102
                        pts.add(pt);
103
104 9720 azabala
                        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 10632 azabala
112
                            pt = new double[]{center.getX() + xrot, center.getY() + yrot};
113
                            pts.add(pt);
114 9720 azabala
                        }
115 10632 azabala
116 9720 azabala
                        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 10632 azabala
123
124
                    pt = new double[]{center.getX() + xrot, center.getY() + yrot};
125
                    pts.add(pt);
126
127 9720 azabala
                } 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 10632 azabala
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 9720 azabala
                                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 10632 azabala
147
                            pt = new double[]{center.getX() + xrot, center.getY() + yrot};
148
                            pts.add(pt);
149 9720 azabala
                        }
150 10632 azabala
151
152 9720 azabala
                        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 10632 azabala
160
                            pt = new double[]{center.getX() + xrot, center.getY() + yrot};
161
                            pts.add(pt);
162
163 9720 azabala
                        }
164 10632 azabala
165 9720 azabala
                        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 10632 azabala
172
                    pt = new double[]{center.getX() + xrot, center.getY() + yrot};
173
                    pts.add(pt);
174 9720 azabala
                }
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 10632 azabala
        public static List calculateGisModelArc(double[] center, double r, double sa, double ea) {
189 9720 azabala
                int isa = (int)sa;
190
                int iea = (int)ea;
191
                double angulo;
192 23942 vcaballero
                List pts = new ArrayList();
193 9720 azabala
                if (sa <= ea) {
194
                        angulo = sa;
195 10632 azabala
                        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 9720 azabala
                                angulo = (double)(isa+i);
199 10632 azabala
                                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 9720 azabala
                        }
203
                        angulo = ea;
204 10632 azabala
                        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 9720 azabala
                } else {
208
                        angulo = sa;
209 10632 azabala
                        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 9720 azabala
                                angulo = (double)(isa+i);
214 10632 azabala
                                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 9720 azabala
                        }
218 10632 azabala
219
                        for (int i=( 360-isa)+1; i <= (360-isa)+iea; i++) {
220 9720 azabala
                                angulo = (double)(i-(360-isa));
221 10632 azabala
                                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 9720 azabala
                        }
225
                        angulo = ea;
226 10632 azabala
                        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 9720 azabala
                }
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 23942 vcaballero
        public static List calculateGisModelBulge(List newPts, double[] bulges) {
243
                Vector ptspol = new Vector();
244 10632 azabala
                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 9720 azabala
                                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 23942 vcaballero
                                                ptspol.add(arc.get(k));
259 9720 azabala
                                        }
260
                                        ptspol.remove(ptspol.size()-1);
261
                                } else {
262
                                        for (int k=0;k<arc.size();k++) {
263 23942 vcaballero
                                                ptspol.add(arc.get(k));
264 9720 azabala
                                        }
265
                                        ptspol.remove(ptspol.size()-1);
266
                                }
267
                        }
268
                }
269 23942 vcaballero
                List points = new ArrayList();
270 9720 azabala
                for (int j=0;j<ptspol.size();j++) {
271 10632 azabala
                        points.add(ptspol.get(j));
272 9720 azabala
                }
273
                return points;
274
        }
275
}