Statistics
| Revision:

root / branches / v2_0_0_prep / libraries / libFMap_geometries / src / org / gvsig / fmap / geom / primitive / Spline2D.java @ 21308

History | View | Annotate | Download (6.8 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 org.gvsig.fmap.geom.primitive;
42

    
43
import java.awt.geom.Point2D;
44
import java.util.ArrayList;
45

    
46
import org.cresques.cts.IProjection;
47
import org.gvsig.fmap.geom.GeometryManager;
48
import org.gvsig.fmap.geom.handler.AbstractHandler;
49
import org.gvsig.fmap.geom.handler.FinalHandler;
50
import org.gvsig.fmap.geom.handler.Handler;
51
import org.gvsig.fmap.geom.type.GeometryType;
52

    
53

    
54
/**
55
 * Spline2D.
56
 *
57
 * @author Vicente Caballero Navarro
58
 */
59
public class Spline2D extends Curve2D implements Curve {
60

    
61
        private static final long serialVersionUID = 1L;
62
        
63
        private static GeometryType geomType = GeometryManager.getInstance()
64
        .registerGeometryType(Spline2D.class);        
65
        public static int CODE = geomType.getType();        
66
        
67
        private Point2D[] points;
68
        /**
69
         * Crea un nuevo FPolyline2D.
70
         *
71
         * @param gpx GeneralPathX.
72
         */
73
        public Spline2D(String id, IProjection projection, Point2D[] ps) {
74
                super(id, projection, getGeneralPathX(ps));
75
                points=ps;
76
        }
77

    
78
        private static GeneralPathX getGeneralPathX(Point2D[] ps) {
79
                GeneralPathX gpx=new GeneralPathX();
80
                int num=ps.length;
81
                double[] px=new double[num];
82
            double[] py=new double[num];
83
            for (int i=0;i<num;i++) {
84
                    Point2D p=ps[i];
85
                    px[i]=p.getX();
86
                    py[i]=p.getY();
87

    
88
            }
89
            Spline splineX = new Spline(px);
90
        Spline splineY = new Spline(py);
91
        gpx.moveTo(px[0],py[0]);
92
        for (int i = 0; i < px.length - 1; i++) {
93
            for (int t = 1; t < 31; t++) {
94
                double x1 = splineX.fn(i, ((double) t) / 30.0);
95
                double y1 = splineY.fn(i, ((double) t) / 30.0);
96
                gpx.lineTo(x1,y1);
97
            }
98
        }
99
        if (ps[0].getX()==ps[ps.length-1].getX() && ps[0].getY()==ps[ps.length-1].getY())
100
                gpx.closePath();
101
                return gpx;
102
        }
103

    
104

    
105
        /**
106
         * @see org.gvsig.fmap.geom.primitive.FShape#getShapeType()
107
         */
108
        public int getShapeType() {
109
                return FShape.LINE;
110
        }
111

    
112
        /* (non-Javadoc)
113
         * @see com.iver.cit.gvsig.fmap.core.FShape#cloneFShape()
114
         */
115
        public FShape cloneFShape() {
116
                return new Spline2D(id, projection, points);
117
        }
118

    
119
        /* (non-Javadoc)
120
         * @see com.iver.cit.gvsig.fmap.core.FShape#getStretchingHandlers()
121
         */
122
        public Handler[] getStretchingHandlers() {
123
                ArrayList handlers = new ArrayList();
124
                for (int i=0;i<points.length;i++) {
125
                        handlers.add(new PointHandler(i, points[i].getX(), points[i].getY()));
126
                }
127
                return (Handler[]) handlers.toArray(new Handler[0]);
128
        }
129
        /* (non-Javadoc)
130
         * @see com.iver.cit.gvsig.fmap.core.FShape#getSelectHandlers()
131
         */
132
        public Handler[] getSelectHandlers() {
133
                ArrayList handlers = new ArrayList();
134
                for (int i=0;i<points.length;i++) {
135
                        Point2D p=points[i];
136
                        handlers.add(new PointSelHandler(i, p.getX(), p.getY()));
137
                }
138
                return (Handler[]) handlers.toArray(new Handler[0]);
139
        }
140

    
141
        /**
142
         * DOCUMENT ME!
143
         *
144
         * @author Vicente Caballero Navarro
145
         */
146
        class PointHandler extends AbstractHandler implements FinalHandler{
147
                /**
148
                 * Crea un nuevo PointHandler.
149
                 *
150
                 * @param x DOCUMENT ME!
151
                 * @param y DOCUMENT ME!
152
                 */
153
                public PointHandler(int i,double x, double y) {
154
                        point = new Point2D.Double(x,y);
155
                        index=i;
156
                }
157

    
158
                /**
159
                 * DOCUMENT ME!
160
                 *
161
                 * @param x DOCUMENT ME!
162
                 * @param y DOCUMENT ME!
163
                 *
164
                 * @return DOCUMENT ME!
165
                 */
166
                public void move(double x, double y) {
167
                        point.setLocation(point.getX()+x,point.getY()+y);
168
                        //TODO falta actualizar el GeneralPathX
169
                }
170

    
171
                /**
172
                 * @see org.gvsig.fmap.geom.handler.Handler#set(double, double)
173
                 */
174
                public void set(double x, double y) {
175
                        point.setLocation(x,y);
176
                        //TODO falta actualizar el GeneralPathX
177
                }
178
        }
179
        /**
180
         * DOCUMENT ME!
181
         *
182
         * @author Vicente Caballero Navarro
183
         */
184
        class PointSelHandler extends AbstractHandler implements FinalHandler{
185
                /**
186
                 * Crea un nuevo PointHandler.
187
                 *
188
                 * @param x DOCUMENT ME!
189
                 * @param y DOCUMENT ME!
190
                 */
191
                public PointSelHandler(int i,double x, double y) {
192
                        point = new Point2D.Double(x,y);
193
                        index=i;
194
                }
195

    
196
                /**
197
                 * DOCUMENT ME!
198
                 *
199
                 * @param x DOCUMENT ME!
200
                 * @param y DOCUMENT ME!
201
                 *
202
                 * @return DOCUMENT ME!
203
                 */
204
                public void move(double x, double y) {
205
                        point.setLocation(point.getX()+x,point.getY()+y);
206
                        points[index]=point;
207
                        gp=getGeneralPathX(points);
208
                }
209

    
210
                /**
211
                 * @see org.gvsig.fmap.geom.handler.Handler#set(double, double)
212
                 */
213
                public void set(double x, double y) {
214
                        point.setLocation(x,y);
215
                        points[index]=point;
216
                        gp=getGeneralPathX(points);
217
                }
218
        }
219
         static class Spline {
220
                    private double y[];
221
                    private double y2[];
222

    
223
                    /**
224
                     * The constructor calculates the second derivatives of the interpolating function
225
                     * at the tabulated points xi, with xi = (i, y[i]).
226
                     * Based on numerical recipes in C, http://www.library.cornell.edu/nr/bookcpdf/c3-3.pdf .
227
                     * @param y Array of y coordinates for cubic-spline interpolation.
228
                     */
229
                    public Spline(double y[]) {
230
                            this.y = y;
231
                            int n = y.length;
232
                            y2 = new double[n];
233
                            double u[] = new double[n];
234
                            for (int i = 1; i < n - 1; i++) {
235
                                    y2[i] = -1.0 / (4.0 + y2[i - 1]);
236
                                    u[i] = (6.0 * (y[i + 1] - 2.0 * y[i] + y[i - 1]) - u[i - 1]) / (4.0 + y2[i - 1]);
237
                            }
238
                            for (int i = n - 2; i >= 0; i--) {
239
                                    y2[i] = y2[i] * y2[i + 1] + u[i];
240
                            }
241
                    }
242

    
243
                    /**
244
                     * Returns a cubic-spline interpolated value y for the point between
245
                     * point (n, y[n]) and (n+1, y[n+1), with t ranging from 0 for (n, y[n])
246
                     * to 1 for (n+1, y[n+1]).
247
                     * @param n The start point.
248
                     * @param t The distance to the next point (0..1).
249
                     * @return A cubic-spline interpolated value.
250
                     */
251
                    public double fn(int n, double t) {
252
                            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];
253
                    }
254

    
255
            }
256
}