Statistics
| Revision:

root / trunk / libraries / libFMap / src / com / iver / cit / gvsig / fmap / core / FSpline2D.java @ 38563

History | View | Annotate | Download (6.44 KB)

1 8946 caballero
/* gvSIG. Sistema de Informaci?n Geogr?fica de la Generalitat Valenciana
2
 *
3
 * Copyright (C) 2004 IVER T.I. and Generalitat Valenciana.
4
 *
5
 * This program is free software; you can redistribute it and/or
6
 * modify it under the terms of the GNU General Public License
7
 * as published by the Free Software Foundation; either version 2
8
 * of the License, or (at your option) any later version.
9
 *
10
 * This program is distributed in the hope that it will be useful,
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 * GNU General Public License for more details.
14
 *
15
 * You should have received a copy of the GNU General Public License
16
 * along with this program; if not, write to the Free Software
17
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,USA.
18
 *
19
 * For more information, contact:
20
 *
21
 *  Generalitat Valenciana
22
 *   Conselleria d'Infraestructures i Transport
23
 *   Av. Blasco Ib??ez, 50
24
 *   46010 VALENCIA
25
 *   SPAIN
26
 *
27
 *      +34 963862235
28
 *   gvsig@gva.es
29
 *      www.gvsig.gva.es
30
 *
31
 *    or
32
 *
33
 *   IVER T.I. S.A
34
 *   Salamanca 50
35
 *   46005 Valencia
36
 *   Spain
37
 *
38
 *   +34 963163400
39
 *   dac@iver.es
40
 */
41
package com.iver.cit.gvsig.fmap.core;
42
43 24488 vcaballero
import java.awt.geom.AffineTransform;
44 8946 caballero
import java.awt.geom.Point2D;
45
import java.util.ArrayList;
46
47
48
/**
49
 * Spline2D.
50
 *
51
 * @author Vicente Caballero Navarro
52
 */
53
public class FSpline2D extends FPolyline2D {
54 24488 vcaballero
55 29182 vcaballero
        protected Point2D[] points;
56 8946 caballero
        /**
57
         * Crea un nuevo FPolyline2D.
58
         *
59
         * @param gpx GeneralPathX.
60
         */
61
        public FSpline2D(Point2D[] ps) {
62
                super(getGeneralPathX(ps));
63
                points=ps;
64
        }
65
66
        private static GeneralPathX getGeneralPathX(Point2D[] ps) {
67
                GeneralPathX gpx=new GeneralPathX();
68
                int num=ps.length;
69
                double[] px=new double[num];
70
            double[] py=new double[num];
71
            for (int i=0;i<num;i++) {
72
                    Point2D p=ps[i];
73
                    px[i]=p.getX();
74
                    py[i]=p.getY();
75
76
            }
77
            Spline splineX = new Spline(px);
78
        Spline splineY = new Spline(py);
79
        gpx.moveTo(px[0],py[0]);
80
        for (int i = 0; i < px.length - 1; i++) {
81
            for (int t = 1; t < 31; t++) {
82
                double x1 = splineX.fn(i, ((double) t) / 30.0);
83
                double y1 = splineY.fn(i, ((double) t) / 30.0);
84
                gpx.lineTo(x1,y1);
85
            }
86
        }
87
        if (ps[0].getX()==ps[ps.length-1].getX() && ps[0].getY()==ps[ps.length-1].getY())
88
                gpx.closePath();
89
                return gpx;
90
        }
91
92
93
        /**
94
         * @see com.iver.cit.gvsig.fmap.core.FShape#getShapeType()
95
         */
96
        public int getShapeType() {
97
                return FShape.LINE;
98
        }
99
100
        /* (non-Javadoc)
101
         * @see com.iver.cit.gvsig.fmap.core.FShape#cloneFShape()
102
         */
103
        public FShape cloneFShape() {
104 24488 vcaballero
                return new FSpline2D(points.clone());
105 8946 caballero
        }
106
107
        /* (non-Javadoc)
108
         * @see com.iver.cit.gvsig.fmap.core.FShape#getStretchingHandlers()
109
         */
110
        public Handler[] getStretchingHandlers() {
111
                ArrayList handlers = new ArrayList();
112
                for (int i=0;i<points.length;i++) {
113
                        handlers.add(new PointHandler(i, points[i].getX(), points[i].getY()));
114
                }
115
                return (Handler[]) handlers.toArray(new Handler[0]);
116
        }
117
        /* (non-Javadoc)
118
         * @see com.iver.cit.gvsig.fmap.core.FShape#getSelectHandlers()
119
         */
120
        public Handler[] getSelectHandlers() {
121
                ArrayList handlers = new ArrayList();
122
                for (int i=0;i<points.length;i++) {
123
                        Point2D p=points[i];
124
                        handlers.add(new PointSelHandler(i, p.getX(), p.getY()));
125
                }
126
                return (Handler[]) handlers.toArray(new Handler[0]);
127
        }
128
129
        /**
130
         * DOCUMENT ME!
131
         *
132
         * @author Vicente Caballero Navarro
133
         */
134
        class PointHandler extends AbstractHandler implements IFinalHandler{
135
                /**
136
                 * Crea un nuevo PointHandler.
137
                 *
138
                 * @param x DOCUMENT ME!
139
                 * @param y DOCUMENT ME!
140
                 */
141
                public PointHandler(int i,double x, double y) {
142
                        point = new Point2D.Double(x,y);
143
                        index=i;
144
                }
145
146
                /**
147
                 * DOCUMENT ME!
148
                 *
149
                 * @param x DOCUMENT ME!
150
                 * @param y DOCUMENT ME!
151
                 *
152
                 * @return DOCUMENT ME!
153
                 */
154
                public void move(double x, double y) {
155
                        point.setLocation(point.getX()+x,point.getY()+y);
156
                        //TODO falta actualizar el GeneralPathX
157
                }
158
159
                /**
160
                 * @see com.iver.cit.gvsig.fmap.core.Handler#set(double, double)
161
                 */
162
                public void set(double x, double y) {
163
                        point.setLocation(x,y);
164
                        //TODO falta actualizar el GeneralPathX
165
                }
166
        }
167
        /**
168
         * DOCUMENT ME!
169
         *
170
         * @author Vicente Caballero Navarro
171
         */
172
        class PointSelHandler extends AbstractHandler implements IFinalHandler{
173
                /**
174
                 * Crea un nuevo PointHandler.
175
                 *
176
                 * @param x DOCUMENT ME!
177
                 * @param y DOCUMENT ME!
178
                 */
179
                public PointSelHandler(int i,double x, double y) {
180
                        point = new Point2D.Double(x,y);
181
                        index=i;
182
                }
183
184
                /**
185
                 * DOCUMENT ME!
186
                 *
187
                 * @param x DOCUMENT ME!
188
                 * @param y DOCUMENT ME!
189
                 *
190
                 * @return DOCUMENT ME!
191
                 */
192
                public void move(double x, double y) {
193
                        point.setLocation(point.getX()+x,point.getY()+y);
194
                        points[index]=point;
195
                        gp=getGeneralPathX(points);
196
                }
197
198
                /**
199
                 * @see com.iver.cit.gvsig.fmap.core.Handler#set(double, double)
200
                 */
201
                public void set(double x, double y) {
202
                        point.setLocation(x,y);
203
                        points[index]=point;
204
                        gp=getGeneralPathX(points);
205
                }
206
        }
207
         static class Spline {
208
                    private double y[];
209
                    private double y2[];
210
211
                    /**
212
                     * The constructor calculates the second derivatives of the interpolating function
213
                     * at the tabulated points xi, with xi = (i, y[i]).
214
                     * Based on numerical recipes in C, http://www.library.cornell.edu/nr/bookcpdf/c3-3.pdf .
215
                     * @param y Array of y coordinates for cubic-spline interpolation.
216
                     */
217
                    public Spline(double y[]) {
218
                            this.y = y;
219
                            int n = y.length;
220
                            y2 = new double[n];
221
                            double u[] = new double[n];
222
                            for (int i = 1; i < n - 1; i++) {
223
                                    y2[i] = -1.0 / (4.0 + y2[i - 1]);
224
                                    u[i] = (6.0 * (y[i + 1] - 2.0 * y[i] + y[i - 1]) - u[i - 1]) / (4.0 + y2[i - 1]);
225
                            }
226
                            for (int i = n - 2; i >= 0; i--) {
227
                                    y2[i] = y2[i] * y2[i + 1] + u[i];
228
                            }
229
                    }
230
231
                    /**
232
                     * Returns a cubic-spline interpolated value y for the point between
233
                     * point (n, y[n]) and (n+1, y[n+1), with t ranging from 0 for (n, y[n])
234
                     * to 1 for (n+1, y[n+1]).
235
                     * @param n The start point.
236
                     * @param t The distance to the next point (0..1).
237
                     * @return A cubic-spline interpolated value.
238
                     */
239
                    public double fn(int n, double t) {
240
                            return t * y[n + 1] - ((t - 1.0) * t * ((t - 2.0) * y2[n] - (t + 1.0) * y2[n + 1])) / 6.0 + y[n] - t * y[n];
241
                    }
242
243
            }
244 24488 vcaballero
         public void transform(AffineTransform at) {
245
                        for (int i=0;i<points.length;i++) {
246
                                Point2D p=points[i];
247
                                at.transform(p, p);
248
                        }
249
                }
250 8946 caballero
}