Statistics
| Revision:

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

History | View | Annotate | Download (6.26 KB)

1
/* 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
import java.awt.geom.Point2D;
44
import java.util.ArrayList;
45

    
46

    
47
/**
48
 * Spline2D.
49
 *
50
 * @author Vicente Caballero Navarro
51
 */
52
public class FSpline2D extends FPolyline2D {
53
        private Point2D[] points;
54
        /**
55
         * Crea un nuevo FPolyline2D.
56
         *
57
         * @param gpx GeneralPathX.
58
         */
59
        public FSpline2D(Point2D[] ps) {
60
                super(getGeneralPathX(ps));
61
                points=ps;
62
        }
63

    
64
        private static GeneralPathX getGeneralPathX(Point2D[] ps) {
65
                GeneralPathX gpx=new GeneralPathX();
66
                int num=ps.length;
67
                double[] px=new double[num];
68
            double[] py=new double[num];
69
            for (int i=0;i<num;i++) {
70
                    Point2D p=ps[i];
71
                    px[i]=p.getX();
72
                    py[i]=p.getY();
73

    
74
            }
75
            Spline splineX = new Spline(px);
76
        Spline splineY = new Spline(py);
77
        gpx.moveTo(px[0],py[0]);
78
        for (int i = 0; i < px.length - 1; i++) {
79
            for (int t = 1; t < 31; t++) {
80
                double x1 = splineX.fn(i, ((double) t) / 30.0);
81
                double y1 = splineY.fn(i, ((double) t) / 30.0);
82
                gpx.lineTo(x1,y1);
83
            }
84
        }
85
        if (ps[0].getX()==ps[ps.length-1].getX() && ps[0].getY()==ps[ps.length-1].getY())
86
                gpx.closePath();
87
                return gpx;
88
        }
89

    
90

    
91
        /**
92
         * @see com.iver.cit.gvsig.fmap.core.FShape#getShapeType()
93
         */
94
        public int getShapeType() {
95
                return FShape.LINE;
96
        }
97

    
98
        /* (non-Javadoc)
99
         * @see com.iver.cit.gvsig.fmap.core.FShape#cloneFShape()
100
         */
101
        public FShape cloneFShape() {
102
                return new FSpline2D(points);
103
        }
104

    
105
        /* (non-Javadoc)
106
         * @see com.iver.cit.gvsig.fmap.core.FShape#getStretchingHandlers()
107
         */
108
        public Handler[] getStretchingHandlers() {
109
                ArrayList handlers = new ArrayList();
110
                for (int i=0;i<points.length;i++) {
111
                        handlers.add(new PointHandler(i, points[i].getX(), points[i].getY()));
112
                }
113
                return (Handler[]) handlers.toArray(new Handler[0]);
114
        }
115
        /* (non-Javadoc)
116
         * @see com.iver.cit.gvsig.fmap.core.FShape#getSelectHandlers()
117
         */
118
        public Handler[] getSelectHandlers() {
119
                ArrayList handlers = new ArrayList();
120
                for (int i=0;i<points.length;i++) {
121
                        Point2D p=points[i];
122
                        handlers.add(new PointSelHandler(i, p.getX(), p.getY()));
123
                }
124
                return (Handler[]) handlers.toArray(new Handler[0]);
125
        }
126

    
127
        /**
128
         * DOCUMENT ME!
129
         *
130
         * @author Vicente Caballero Navarro
131
         */
132
        class PointHandler extends AbstractHandler implements IFinalHandler{
133
                /**
134
                 * Crea un nuevo PointHandler.
135
                 *
136
                 * @param x DOCUMENT ME!
137
                 * @param y DOCUMENT ME!
138
                 */
139
                public PointHandler(int i,double x, double y) {
140
                        point = new Point2D.Double(x,y);
141
                        index=i;
142
                }
143

    
144
                /**
145
                 * DOCUMENT ME!
146
                 *
147
                 * @param x DOCUMENT ME!
148
                 * @param y DOCUMENT ME!
149
                 *
150
                 * @return DOCUMENT ME!
151
                 */
152
                public void move(double x, double y) {
153
                        point.setLocation(point.getX()+x,point.getY()+y);
154
                        //TODO falta actualizar el GeneralPathX
155
                }
156

    
157
                /**
158
                 * @see com.iver.cit.gvsig.fmap.core.Handler#set(double, double)
159
                 */
160
                public void set(double x, double y) {
161
                        point.setLocation(x,y);
162
                        //TODO falta actualizar el GeneralPathX
163
                }
164
        }
165
        /**
166
         * DOCUMENT ME!
167
         *
168
         * @author Vicente Caballero Navarro
169
         */
170
        class PointSelHandler extends AbstractHandler implements IFinalHandler{
171
                /**
172
                 * Crea un nuevo PointHandler.
173
                 *
174
                 * @param x DOCUMENT ME!
175
                 * @param y DOCUMENT ME!
176
                 */
177
                public PointSelHandler(int i,double x, double y) {
178
                        point = new Point2D.Double(x,y);
179
                        index=i;
180
                }
181

    
182
                /**
183
                 * DOCUMENT ME!
184
                 *
185
                 * @param x DOCUMENT ME!
186
                 * @param y DOCUMENT ME!
187
                 *
188
                 * @return DOCUMENT ME!
189
                 */
190
                public void move(double x, double y) {
191
                        point.setLocation(point.getX()+x,point.getY()+y);
192
                        points[index]=point;
193
                        gp=getGeneralPathX(points);
194
                }
195

    
196
                /**
197
                 * @see com.iver.cit.gvsig.fmap.core.Handler#set(double, double)
198
                 */
199
                public void set(double x, double y) {
200
                        point.setLocation(x,y);
201
                        points[index]=point;
202
                        gp=getGeneralPathX(points);
203
                }
204
        }
205
         static class Spline {
206
                    private double y[];
207
                    private double y2[];
208

    
209
                    /**
210
                     * The constructor calculates the second derivatives of the interpolating function
211
                     * at the tabulated points xi, with xi = (i, y[i]).
212
                     * Based on numerical recipes in C, http://www.library.cornell.edu/nr/bookcpdf/c3-3.pdf .
213
                     * @param y Array of y coordinates for cubic-spline interpolation.
214
                     */
215
                    public Spline(double y[]) {
216
                            this.y = y;
217
                            int n = y.length;
218
                            y2 = new double[n];
219
                            double u[] = new double[n];
220
                            for (int i = 1; i < n - 1; i++) {
221
                                    y2[i] = -1.0 / (4.0 + y2[i - 1]);
222
                                    u[i] = (6.0 * (y[i + 1] - 2.0 * y[i] + y[i - 1]) - u[i - 1]) / (4.0 + y2[i - 1]);
223
                            }
224
                            for (int i = n - 2; i >= 0; i--) {
225
                                    y2[i] = y2[i] * y2[i + 1] + u[i];
226
                            }
227
                    }
228

    
229
                    /**
230
                     * Returns a cubic-spline interpolated value y for the point between
231
                     * point (n, y[n]) and (n+1, y[n+1), with t ranging from 0 for (n, y[n])
232
                     * to 1 for (n+1, y[n+1]).
233
                     * @param n The start point.
234
                     * @param t The distance to the next point (0..1).
235
                     * @return A cubic-spline interpolated value.
236
                     */
237
                    public double fn(int n, double t) {
238
                            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];
239
                    }
240

    
241
            }
242
}