Statistics
| Revision:

svn-gvsig-desktop / trunk / libraries / libDwg / src / com / iver / cit / javacad / util / GisModelCurveCalculator.java @ 2896

History | View | Annotate | Download (10.6 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.javacad.util;
36

    
37
import java.awt.geom.Point2D;
38
import java.util.Vector;
39

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