Statistics
| Revision:

svn-gvsig-desktop / branches / v2_0_0_prep / libraries / libFMap_geometries / src / org / gvsig / fmap / geom / primitive / impl / EllipticArc2D.java @ 29097

History | View | Annotate | Download (16.9 KB)

1
/*
2
 * Created on 09-feb-2005
3
 *
4
 * gvSIG. Sistema de Informaci�n Geogr�fica de la Generalitat Valenciana
5
 *
6
 * Copyright (C) 2004 IVER T.I. 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,
21
   USA.
22
 *
23
 * For more information, contact:
24
 *
25
 *  Generalitat Valenciana
26
 *   Conselleria d'Infraestructures i Transport
27
 *   Av. Blasco Ib��ez, 50
28
 *   46010 VALENCIA
29
 *   SPAIN
30
 *
31
 *      +34 963862235
32
 *   gvsig@gva.es
33
 *      www.gvsig.gva.es
34
 *
35
 *    or
36
 *
37
 *   IVER T.I. S.A
38
 *   Salamanca 50
39
 *   46005 Valencia
40
 *   Spain
41
 *
42
 *   +34 963163400
43
 *   dac@iver.es
44
 */
45
package org.gvsig.fmap.geom.primitive.impl;
46

    
47
import java.awt.geom.AffineTransform;
48
import java.awt.geom.Arc2D;
49
import java.awt.geom.Point2D;
50
import java.awt.geom.Rectangle2D;
51
import java.util.ArrayList;
52

    
53
import org.cresques.cts.IProjection;
54
import org.gvsig.fmap.geom.Geometry;
55
import org.gvsig.fmap.geom.handler.AbstractHandler;
56
import org.gvsig.fmap.geom.handler.CuadrantHandler;
57
import org.gvsig.fmap.geom.handler.Handler;
58
import org.gvsig.fmap.geom.primitive.EllipticArc;
59
import org.gvsig.fmap.geom.primitive.GeneralPathX;
60
import org.gvsig.fmap.geom.primitive.Point;
61
import org.gvsig.fmap.geom.type.GeometryType;
62
import org.gvsig.fmap.geom.util.UtilFunctions;
63

    
64

    
65

    
66
/**
67
 * DOCUMENT ME!
68
 *
69
 * @author Vicente Caballero Navarro
70
 */
71
public class EllipticArc2D extends Curve2D implements EllipticArc {
72
        private static final long serialVersionUID = 2988037614443119814L;
73

    
74
        private Point2D axis1Start;
75
        private Point2D axis1End;
76
        private double semiAxis2Length;
77
        private double angSt;
78
        private double angExt;
79

    
80
        /**
81
         * The constructor with the GeometryType like and argument 
82
         * is used by the {@link GeometryType}{@link #create()}
83
         * to create the geometry
84
         * @param type
85
         * The geometry type
86
         */
87
        public EllipticArc2D(GeometryType geometryType) {
88
                super(geometryType);                
89
        }
90
        
91
        /**
92
         * Constructor used in the {@link Geometry#cloneGeometry()} method
93
         * @param id
94
         * @param projection
95
         * @param gpx
96
         * @param axis1Start
97
         * @param axis1End
98
         * @param semiAxis2Length
99
         * @param angSt
100
         * @param angExt
101
         */
102
        EllipticArc2D(GeometryType geometryType, String id, IProjection projection, GeneralPathX gpx, Point2D axis1Start,Point2D axis1End, double semiAxis2Length, double angSt, double angExt) {
103
                super(geometryType, id, projection, gpx);
104
                this.axis1Start = axis1Start;
105
                this.axis1End = axis1End;
106
                this.semiAxis2Length = semiAxis2Length;
107
                this.angSt = angSt;
108
                this.angExt = angExt;
109
        }
110
        
111
        /*
112
         * (non-Javadoc)
113
         * @see org.gvsig.fmap.geom.primitive.EllipticArc#getAxis1Start()
114
         */
115
        public Point getAxis1Start(){
116
                try {
117
                        return new org.gvsig.fmap.geom.primitive.impl.Point2D(axis1Start);
118
                } catch (Exception e){
119
                        return null;
120
                }
121
        }
122
        
123
        /*
124
         * (non-Javadoc)
125
         * @see org.gvsig.fmap.geom.primitive.EllipticArc#getAxis1End()
126
         */
127
        public Point getAxis1End(){
128
                try {
129
                        return new org.gvsig.fmap.geom.primitive.impl.Point2D(axis1End);
130
                } catch (Exception e){
131
                        return null;
132
                }
133
        }
134
        
135
        /*
136
         * (non-Javadoc)
137
         * @see org.gvsig.fmap.geom.primitive.EllipticArc#getAxis2Dist()
138
         */
139
        public double getAxis2Dist(){
140
                return this.semiAxis2Length;
141
        }
142
        
143
        /*
144
         * (non-Javadoc)
145
         * @see org.gvsig.fmap.geom.primitive.EllipticArc#getAngSt()
146
         */
147
        public double getAngSt(){
148
                return this.angSt;
149
        }
150
        
151
        /*
152
         * (non-Javadoc)
153
         * @see org.gvsig.fmap.geom.primitive.EllipticArc#getAngExt()
154
         */
155
        public double getAngExt(){
156
                return this.angExt;
157
        }
158

    
159
        /*
160
         * (non-Javadoc)
161
         * @see org.gvsig.fmap.geom.primitive.impl.OrientablePrimitive2D#transform(java.awt.geom.AffineTransform)
162
         */
163
        public void transform(AffineTransform at) {
164
                Point2D center = new Point2D.Double((axis1Start.getX() + axis1End.getX()) / 2,
165
                                (axis1Start.getY() + axis1End.getY()) / 2);
166
                Point2D pdist = UtilFunctions.getPerpendicularPoint(axis1Start, axis1End, center,
167
                                semiAxis2Length);
168
                Point2D aux1 = new Point2D.Double();
169
                at.transform(axis1Start, aux1);
170
                axis1Start = aux1;
171
                Point2D aux2 = new Point2D.Double();
172
                at.transform(axis1End, aux2);
173
                axis1End = aux2;
174

    
175
                center = new Point2D.Double((axis1Start.getX() + axis1End.getX()) / 2, (axis1Start
176
                                .getY() + axis1End.getY()) / 2);
177

    
178
                Point2D aux3 = new Point2D.Double();
179
                at.transform(pdist, aux3);
180
                semiAxis2Length = center.distance(aux3);
181
                gp.transform(at);
182
        }
183
        
184
        /*
185
         * (non-Javadoc)
186
         * @see org.gvsig.fmap.geom.primitive.impl.Curve2D#getShapeType()
187
         */
188
        public int getShapeType() {
189
                return TYPES.ELLIPTICARC;
190
        }
191
        
192
        /*
193
         * (non-Javadoc)
194
         * @see org.gvsig.fmap.geom.primitive.impl.OrientablePrimitive2D#getStretchingHandlers()
195
         */
196
        public Handler[] getStretchingHandlers() {
197
                ArrayList handlers = new ArrayList();
198
                Rectangle2D rect = this.getBounds2D();
199
                handlers.add(new CenterHandler(0, rect.getCenterX(), rect.getCenterY()));
200
                return (Handler[]) handlers.toArray(new Handler[0]);
201
        }
202

    
203
        /*
204
         * (non-Javadoc)
205
         * @see org.gvsig.fmap.geom.primitive.impl.OrientablePrimitive2D#getSelectHandlers()
206
         */
207
        public Handler[] getSelectHandlers() {
208
                //TODO: Faltaria tener en cuenta handlers para los angulos angSt y angExt
209
                ArrayList handlers = new ArrayList();
210
                Rectangle2D rect = this.getBounds2D();
211
                handlers.add(new CenterSelHandler(0, rect.getCenterX(), rect.getCenterY()));
212
                handlers.add(new Axis1StSelHandler(1, axis1Start.getX(), axis1Start.getY()));
213
                handlers.add(new Axis1EndSelHandler(2, axis1End.getX(), axis1End.getY()));
214
                Point2D mediop = new Point2D.Double((axis1End.getX() + axis1Start.getX()) / 2,
215
                                (axis1End.getY() + axis1Start.getY()) / 2);
216
                Point2D[] p = UtilFunctions.getPerpendicular(axis1Start, axis1End, mediop);
217
                Point2D u = UtilFunctions.getPoint(mediop, p[1], semiAxis2Length);
218
                Point2D d = UtilFunctions.getPoint(mediop, p[1], -semiAxis2Length);
219

    
220
                handlers.add(new RadioSelYHandler(3, u.getX(), u.getY()));
221
                handlers.add(new RadioSelYHandler(4, d.getX(), d.getY()));
222

    
223
                return (Handler[]) handlers.toArray(new Handler[0]);
224
        }
225

    
226
        /**
227
         * DOCUMENT ME!
228
         *
229
         * @author Vicente Caballero Navarro
230
         */
231
        class CenterHandler extends AbstractHandler implements Handler {
232
                /**
233
                 * Crea un nuevo PointHandler.
234
                 *
235
                 * @param i
236
                 *            DOCUMENT ME!
237
                 * @param x
238
                 *            DOCUMENT ME!
239
                 * @param y
240
                 *            DOCUMENT ME!
241
                 */
242
                public CenterHandler(int i, double x, double y) {
243
                        point = new Point2D.Double(x, y);
244
                        index = i;
245
                }
246

    
247
                /**
248
                 * DOCUMENT ME!
249
                 *
250
                 * @param x
251
                 *            DOCUMENT ME!
252
                 * @param y
253
                 *            DOCUMENT ME!
254
                 *
255
                 * @return DOCUMENT ME!
256
                 */
257
                public void move(double x, double y) {
258
                        for (int i = 0; i < gp.getNumCoords() / 2; i++) {
259
                                gp.getPointCoords()[i * 2] += x;
260
                                gp.getPointCoords()[i * 2 + 1] += y;
261
                        }
262
                        axis1Start = new Point2D.Double(axis1Start.getX() + x, axis1Start.getY() + y);
263
                        axis1End = new Point2D.Double(axis1End.getX() + x, axis1End.getY() + y);
264
                }
265

    
266
                /**
267
                 * @see org.gvsig.fmap.geom.handler.Handler#set(double, double)
268
                 */
269
                public void set(double x, double y) {
270
                }
271
        }
272

    
273
        /**
274
         * DOCUMENT ME!
275
         *
276
         * @author Vicente Caballero Navarro
277
         */
278
        class CenterSelHandler extends AbstractHandler implements Handler {
279
                /**
280
                 * Crea un nuevo PointHandler.
281
                 *
282
                 * @param i
283
                 *            DOCUMENT ME!
284
                 * @param x
285
                 *            DOCUMENT ME!
286
                 * @param y
287
                 *            DOCUMENT ME!
288
                 */
289
                public CenterSelHandler(int i, double x, double y) {
290
                        point = new Point2D.Double(x, y);
291
                        index = i;
292
                }
293

    
294
                /**
295
                 * DOCUMENT ME!
296
                 *
297
                 * @param x
298
                 *            DOCUMENT ME!
299
                 * @param y
300
                 *            DOCUMENT ME!
301
                 *
302
                 * @return DOCUMENT ME!
303
                 */
304
                public void move(double x, double y) {
305
                        for (int i = 0; i < gp.getNumCoords() / 2; i++) {
306
                                gp.getPointCoords()[i * 2] += x;
307
                                gp.getPointCoords()[i * 2 + 1] += y;
308
                        }
309
                }
310

    
311
                /**
312
                 * @see org.gvsig.fmap.geom.handler.Handler#set(double, double)
313
                 */
314
                public void set(double x, double y) {
315
                        Point2D center = new Point2D.Double((axis1Start.getX() + axis1End.getX()) / 2,
316
                                        (axis1Start.getY() + axis1End.getY()) / 2);
317
                        double dx = x - center.getX();
318
                        double dy = y - center.getY();
319
                        for (int i = 0; i < gp.getNumCoords() / 2; i++) {
320
                                gp.getPointCoords()[i * 2] += dx;
321
                                gp.getPointCoords()[i * 2 + 1] += dy;
322
                        }
323
                        axis1Start = new Point2D.Double(axis1Start.getX() + dx, axis1Start.getY() + dy);
324
                        axis1End = new Point2D.Double(axis1End.getX() + dx, axis1End.getY() + dy);
325
                }
326
        }
327

    
328
        /**
329
         * DOCUMENT ME!
330
         *
331
         * @author Vicente Caballero Navarro
332
         */
333
        class Axis1StSelHandler extends AbstractHandler implements CuadrantHandler {
334
                /**
335
                 * Crea un nuevo PointHandler.
336
                 *
337
                 * @param i
338
                 *            DOCUMENT ME!
339
                 * @param x
340
                 *            DOCUMENT ME!
341
                 * @param y
342
                 *            DOCUMENT ME!
343
                 */
344
                public Axis1StSelHandler(int i, double x, double y) {
345
                        point = new Point2D.Double(x, y);
346
                        index = i;
347
                }
348

    
349
                /**
350
                 * DOCUMENT ME!
351
                 *
352
                 * @param x
353
                 *            DOCUMENT ME!
354
                 * @param y
355
                 *            DOCUMENT ME!
356
                 *
357
                 * @return DOCUMENT ME!
358
                 */
359
                public void move(double x, double y) {
360

    
361
                }
362

    
363
                /**
364
                 * @see org.gvsig.fmap.geom.handler.Handler#set(double, double)
365
                 */
366
                public void set(double x, double y) {
367
                        // TODO comentado para quitar warning: double dx=x-init.getX();
368
                        // TODO comentado para quitar warning: double dy=y-init.getY();
369
                        Point2D center = new Point2D.Double((axis1Start.getX() + axis1End.getX()) / 2,
370
                                        (axis1Start.getY() + axis1End.getY()) / 2);
371
                        // Point2D[]
372
                        // p1=TrigonometricalFunctions.getPerpendicular(init,end,center);
373
                        // Point2D[]
374
                        // p2=TrigonometricalFunctions.getPerpendicular(p1[0],p1[1],new
375
                        // Point2D.Double(x,y));
376

    
377
                        // Point2D
378
                        // pl=TrigonometricalFunctions.getIntersection(p2[0],p2[1],p1[0],p1[1]);
379
                        // double xdist=2*pl.distance(x,y);
380
                        double xdist = 2 * center.distance(x, y);
381
                        // init=new Point2D.Double(init.getX()+dx,init.getY()+dy);
382
                        axis1Start = UtilFunctions.getPoint(center, axis1Start, center.distance(x, y));
383
                        axis1End = UtilFunctions.getPoint(axis1Start, center, xdist);
384
                        Arc2D.Double arc = new Arc2D.Double(axis1Start.getX(), axis1Start.getY()
385
                                        - semiAxis2Length, xdist, 2 * semiAxis2Length, Math.toDegrees(angSt), Math.toDegrees(angExt), Arc2D.OPEN);
386
                        // TODO comentado para quitar warning: Point2D rotationPoint = new
387
                        // Point2D.Double(init.getX() + xdist /2, init.getY());
388

    
389
                        double angle = UtilFunctions.getAngle(axis1Start, axis1End);
390
                        AffineTransform mT = AffineTransform.getRotateInstance(angle, axis1Start
391
                                        .getX(), axis1Start.getY());
392
                        gp = new GeneralPathX(arc);
393
                        gp.transform(mT);
394

    
395
                }
396
        }
397

    
398
        /**
399
         * DOCUMENT ME!
400
         *
401
         * @author Vicente Caballero Navarro
402
         */
403
        class Axis1EndSelHandler extends AbstractHandler implements CuadrantHandler {
404
                /**
405
                 * Crea un nuevo PointHandler.
406
                 *
407
                 * @param i
408
                 *            DOCUMENT ME!
409
                 * @param x
410
                 *            DOCUMENT ME!
411
                 * @param y
412
                 *            DOCUMENT ME!
413
                 */
414
                public Axis1EndSelHandler(int i, double x, double y) {
415
                        point = new Point2D.Double(x, y);
416
                        index = i;
417
                }
418

    
419
                /**
420
                 * DOCUMENT ME!
421
                 *
422
                 * @param x
423
                 *            DOCUMENT ME!
424
                 * @param y
425
                 *            DOCUMENT ME!
426
                 *
427
                 * @return DOCUMENT ME!
428
                 */
429
                public void move(double x, double y) {
430

    
431
                }
432

    
433
                /**
434
                 * @see org.gvsig.fmap.geom.handler.Handler#set(double, double)
435
                 */
436
                public void set(double x, double y) {
437
                        // double dx=x-getPoint().getX();
438
                        // double dy=y-getPoint().getY();
439
                        Point2D center = new Point2D.Double((axis1Start.getX() + axis1End.getX()) / 2,
440
                                        (axis1Start.getY() + axis1End.getY()) / 2);
441
                        // Point2D[]
442
                        // p1=TrigonometricalFunctions.getPerpendicular(init,end,center);
443
                        // Point2D[]
444
                        // p2=TrigonometricalFunctions.getPerpendicular(p1[0],p1[1],new
445
                        // Point2D.Double(x,y));
446

    
447
                        // Point2D
448
                        // pl=TrigonometricalFunctions.getIntersection(p2[0],p2[1],p1[0],p1[1]);
449
                        // double xdist=2*pl.distance(x,y);
450
                        double xdist = 2 * center.distance(x, y);
451
                        axis1End = UtilFunctions.getPoint(center, axis1End, center.distance(x, y));
452
                        // end=new Point2D.Double(end.getX()+dx,end.getY()+dy);
453
                        axis1Start = UtilFunctions.getPoint(axis1End, center, xdist);
454
                        Arc2D.Double arc = new Arc2D.Double(axis1Start.getX(), axis1Start.getY()
455
                                        - semiAxis2Length, xdist, 2 * semiAxis2Length, Math.toDegrees(angSt), Math.toDegrees(angExt), Arc2D.OPEN);
456
                        // Point2D rotationPoint = new Point2D.Double(init.getX() + xdist
457
                        // /2, init.getY());
458

    
459
                        double angle = UtilFunctions.getAngle(axis1Start, axis1End);
460
                        AffineTransform mT = AffineTransform.getRotateInstance(angle, axis1Start
461
                                        .getX(), axis1Start.getY());
462
                        gp = new GeneralPathX(arc);
463
                        gp.transform(mT);
464

    
465
                }
466
        }
467

    
468
        /**
469
         * DOCUMENT ME!
470
         *
471
         * @author Vicente Caballero Navarro
472
         */
473
        class RadioSelYHandler extends AbstractHandler implements CuadrantHandler {
474
                /**
475
                 * Crea un nuevo PointHandler.
476
                 *
477
                 * @param i
478
                 *            DOCUMENT ME!
479
                 * @param x
480
                 *            DOCUMENT ME!
481
                 * @param y
482
                 *            DOCUMENT ME!
483
                 */
484
                public RadioSelYHandler(int i, double x, double y) {
485
                        point = new Point2D.Double(x, y);
486
                        index = i;
487
                }
488

    
489
                /**
490
                 * DOCUMENT ME!
491
                 *
492
                 * @param x
493
                 *            DOCUMENT ME!
494
                 * @param y
495
                 *            DOCUMENT ME!
496
                 *
497
                 * @return DOCUMENT ME!
498
                 */
499
                public void move(double x, double y) {
500

    
501
                }
502

    
503
                /**
504
                 * @see org.gvsig.fmap.geom.handler.Handler#set(double, double)
505
                 */
506
                public void set(double x, double y) {
507
                        semiAxis2Length = new Point2D.Double((axis1Start.getX() + axis1End.getX()) / 2, (axis1Start
508
                                        .getY() + axis1End.getY()) / 2).distance(x, y);
509
                        // ydist=getSelectHandlers()[1].getPoint().distance(x,y);
510
                        // Point2D center=new Point2D.Double((init.getX() + end.getX()) / 2,
511
                        // (init.getY() + end.getY()) / 2);
512
                        // Point2D[]
513
                        // p=TrigonometricalFunctions.getPerpendicular(init,end,new
514
                        // Point2D.Double(x,y));
515
                        // Point2D
516
                        // pl=TrigonometricalFunctions.getIntersection(p[0],p[1],init,end);
517
                        // double xdist=2*pl.distance(x,y);
518
                        double xdist = axis1Start.distance(axis1End);
519
                        Arc2D.Double arc = new Arc2D.Double(axis1Start.getX(), axis1Start.getY()
520
                                        - semiAxis2Length, xdist, 2 * semiAxis2Length, Math.toDegrees(angSt), Math.toDegrees(angExt), Arc2D.OPEN);
521
                        // Point2D rotationPoint = new Point2D.Double(init.getX() + xdist
522
                        // /2, init.getY());
523

    
524
                        double angle = UtilFunctions.getAngle(axis1Start, axis1End);
525
                        AffineTransform mT = AffineTransform.getRotateInstance(angle, axis1Start
526
                                        .getX(), axis1Start.getY());
527
                        gp = new GeneralPathX(arc);
528
                        gp.transform(mT);
529
                }
530
        }
531

    
532
//TODO: Faltan Handlers para los angulos inicial y de extension (o final)
533

    
534

    
535

    
536
        /* (non-Javadoc)
537
         * @see com.iver.cit.gvsig.fmap.core.FPolyline2D#intersects(java.awt.geom.Rectangle2D)
538
         */
539
        public boolean intersects(Rectangle2D r) {
540
                return gp.intersects(r);
541
        }
542

    
543
        /* (non-Javadoc)
544
         * @see org.gvsig.fmap.geom.primitive.EllipticArc#setPoints(org.gvsig.fmap.geom.primitive.Point, java.awt.geom.Point2D, double, double, double)
545
         */
546
        public void setPoints(Point axis1Start, Point axis1End,
547
                        double semiAxis2Length, double angSt, double angExt) {
548
                Point2D _axis1Start = new java.awt.geom.Point2D.Double(axis1Start.getCoordinateAt(0), axis1Start.getCoordinateAt(1));
549
                Point2D _axis1End = new java.awt.geom.Point2D.Double(axis1End.getCoordinateAt(0), axis1End.getCoordinateAt(1));
550
                setPoints(_axis1Start, _axis1End, semiAxis2Length, angSt, angExt);
551
        }
552

    
553
        /* (non-Javadoc)
554
         * @see org.gvsig.fmap.geom.primitive.EllipticArc#setPoints(java.awt.geom.Point2D, java.awt.geom.Point2D, double, double, double)
555
         */
556
        private void setPoints(Point2D axis1Start, Point2D axis1End,
557
                        double semiAxis2Length, double angSt, double angExt) {
558
                double axis1Lenght = axis1Start.distance(axis1End);
559
                Point2D center = new Point2D.Double((axis1Start.getX()+axis1End.getX())/2, (axis1Start.getY()+axis1End.getY())/2);
560
                double x = center.getX()-axis1Lenght/2;
561
                double y = center.getY()-semiAxis2Length;
562

    
563
                double angle = UtilFunctions.getAngle(center, axis1Start);
564

    
565
                Arc2D.Double arc = new Arc2D.Double(
566
                                x,
567
                                y,
568
                                axis1Lenght,
569
                                2 * semiAxis2Length,
570
                                Math.toDegrees(angSt),
571
                                Math.toDegrees(angExt),
572
                                Arc2D.OPEN);
573
                AffineTransform mT = AffineTransform.getRotateInstance(angle,
574
                                center.getX(), center.getY());
575
                GeneralPathX gp = new GeneralPathX(arc);
576
                gp.transform(mT);
577

    
578
                this.gp = gp;
579
                this.axis1Start = axis1Start;
580
                this.axis1End = axis1End;
581
                this.semiAxis2Length = semiAxis2Length;
582
                this.angSt = angSt;
583
                this.angExt = angExt;                
584
        }
585
        
586
        /*
587
         * (non-Javadoc)
588
         * @see org.gvsig.fmap.geom.primitive.Curve2D#setGeneralPath(org.gvsig.fmap.geom.primitive.GeneralPathX)
589
         */
590
        public void setGeneralPath(GeneralPathX generalPathX) {
591
                throw new UnsupportedOperationException("Use setPoints(Point center, Point radious)");
592
        }
593
}