Statistics
| Revision:

root / branches / v2_0_0_prep / libraries / libFMap_geometries / src / org / gvsig / fmap / geom / primitive / impl / EllipticArc2D.java @ 35475

History | View | Annotate | Download (20.1 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.primitive.SurfaceAppearance;
62
import org.gvsig.fmap.geom.type.GeometryType;
63
import org.gvsig.fmap.geom.util.UtilFunctions;
64

    
65

    
66

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

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

    
81
    /**
82
     * The constructor with the GeometryType like and argument 
83
     * is used by the {@link GeometryType}{@link #create()}
84
     * to create the geometry
85
     * @param type
86
     * The geometry type
87
     */
88
    public EllipticArc2D(GeometryType geometryType) {
89
        super(geometryType);                
90
    }
91

    
92
    /**
93
     * Constructor used in the {@link Geometry#cloneGeometry()} method
94
     * @param id
95
     * @param projection
96
     * @param gpx
97
     * @param axis1Start
98
     * @param axis1End
99
     * @param semiAxis2Length
100
     * @param angSt
101
     * @param angExt
102
     */
103
    EllipticArc2D(GeometryType geometryType, String id, IProjection projection, GeneralPathX gpx, Point2D axis1Start,Point2D axis1End, double semiAxis2Length, double angSt, double angExt) {
104
        super(geometryType, id, projection, gpx);
105
        this.axis1Start = axis1Start;
106
        this.axis1End = axis1End;
107
        this.semiAxis2Length = semiAxis2Length;
108
        this.angSt = angSt;
109
        this.angExt = angExt;
110
    }
111

    
112
    /*
113
     * (non-Javadoc)
114
     * @see org.gvsig.fmap.geom.primitive.EllipticArc#getAxis1Start()
115
     */
116
    public Point getAxis1Start(){
117
        try {
118
            return new org.gvsig.fmap.geom.primitive.impl.Point2D(axis1Start);
119
        } catch (Exception e){
120
            return null;
121
        }
122
    }
123

    
124
    /*
125
     * (non-Javadoc)
126
     * @see org.gvsig.fmap.geom.primitive.EllipticArc#getAxis1End()
127
     */
128
    public Point getAxis1End(){
129
        try {
130
            return new org.gvsig.fmap.geom.primitive.impl.Point2D(axis1End);
131
        } catch (Exception e){
132
            return null;
133
        }
134
    }
135

    
136
    /*
137
     * (non-Javadoc)
138
     * @see org.gvsig.fmap.geom.primitive.EllipticArc#getAxis2Dist()
139
     */
140
    public double getAxis2Dist(){
141
        return this.semiAxis2Length;
142
    }
143

    
144
    /*
145
     * (non-Javadoc)
146
     * @see org.gvsig.fmap.geom.primitive.EllipticArc#getAngSt()
147
     */
148
    public double getAngSt(){
149
        return this.angSt;
150
    }
151

    
152
    /*
153
     * (non-Javadoc)
154
     * @see org.gvsig.fmap.geom.primitive.EllipticArc#getAngExt()
155
     */
156
    public double getAngExt(){
157
        return this.angExt;
158
    }
159

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

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

    
179
        Point2D aux3 = new Point2D.Double();
180
        at.transform(pdist, aux3);
181
        semiAxis2Length = center.distance(aux3);
182
        gp.transform(at);
183
    }
184

    
185
    /*
186
     * (non-Javadoc)
187
     * @see org.gvsig.fmap.geom.primitive.impl.Curve2D#getShapeType()
188
     */
189
    public int getShapeType() {
190
        return TYPES.ELLIPTICARC;
191
    }
192

    
193
    /*
194
     * (non-Javadoc)
195
     * @see org.gvsig.fmap.geom.primitive.impl.OrientablePrimitive2D#getStretchingHandlers()
196
     */
197
    public Handler[] getStretchingHandlers() {
198
        ArrayList handlers = new ArrayList();
199
        Rectangle2D rect = this.getBounds2D();
200
        handlers.add(new CenterHandler(0, rect.getCenterX(), rect.getCenterY()));
201
        return (Handler[]) handlers.toArray(new Handler[0]);
202
    }
203

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

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

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

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

    
248
        /**
249
         * DOCUMENT ME!
250
         *
251
         * @param x
252
         *            DOCUMENT ME!
253
         * @param y
254
         *            DOCUMENT ME!
255
         *
256
         * @return DOCUMENT ME!
257
         */
258
        public void move(double x, double y) {
259
            Point point;
260
            for (int i = 0; i < gp.getNumCoords(); i++) {
261
                point = gp.getPointAt(i);
262
                point.setX(point.getX() + x);
263
                point.setY(point.getY() + y);
264
            }
265
            axis1Start = new Point2D.Double(axis1Start.getX() + x, axis1Start.getY() + y);
266
            axis1End = new Point2D.Double(axis1End.getX() + x, axis1End.getY() + y);
267
        }
268

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

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

    
297
        /**
298
         * DOCUMENT ME!
299
         *
300
         * @param x
301
         *            DOCUMENT ME!
302
         * @param y
303
         *            DOCUMENT ME!
304
         *
305
         * @return DOCUMENT ME!
306
         */
307
        public void move(double x, double y) {
308
            Point point;
309
            for (int i = 0; i < gp.getNumCoords(); i++) {
310
                point = gp.getPointAt(i);
311
                point.setX(point.getX() + x);
312
                point.setY(point.getY() + y);
313
            }
314
        }
315

    
316
        /**
317
         * @see org.gvsig.fmap.geom.handler.Handler#set(double, double)
318
         */
319
        public void set(double x, double y) {
320
            Point2D center = new Point2D.Double((axis1Start.getX() + axis1End.getX()) / 2,
321
                (axis1Start.getY() + axis1End.getY()) / 2);
322
            double dx = x - center.getX();
323
            double dy = y - center.getY();
324
            Point point;
325
            for (int i = 0; i < gp.getNumCoords(); i++) {
326
                point = gp.getPointAt(i);
327
                point.setX(point.getX() + dx);
328
                point.setY(point.getY() + dy);
329
            }
330
            axis1Start = new Point2D.Double(axis1Start.getX() + dx, axis1Start.getY() + dy);
331
            axis1End = new Point2D.Double(axis1End.getX() + dx, axis1End.getY() + dy);
332
        }
333
    }
334

    
335
    /**
336
     * DOCUMENT ME!
337
     *
338
     * @author Vicente Caballero Navarro
339
     */
340
    class Axis1StSelHandler extends AbstractHandler implements CuadrantHandler {
341
        /**
342
         * Crea un nuevo PointHandler.
343
         *
344
         * @param i
345
         *            DOCUMENT ME!
346
         * @param x
347
         *            DOCUMENT ME!
348
         * @param y
349
         *            DOCUMENT ME!
350
         */
351
        public Axis1StSelHandler(int i, double x, double y) {
352
            point = new Point2D.Double(x, y);
353
            index = i;
354
        }
355

    
356
        /**
357
         * DOCUMENT ME!
358
         *
359
         * @param x
360
         *            DOCUMENT ME!
361
         * @param y
362
         *            DOCUMENT ME!
363
         *
364
         * @return DOCUMENT ME!
365
         */
366
        public void move(double x, double y) {
367

    
368
        }
369

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

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

    
396
            double angle = UtilFunctions.getAngle(axis1Start, axis1End);
397
            AffineTransform mT = AffineTransform.getRotateInstance(angle, axis1Start
398
                .getX(), axis1Start.getY());
399
            gp = new GeneralPathX(arc.getPathIterator(null));
400
            gp.transform(mT);
401

    
402
        }
403
    }
404

    
405
    /**
406
     * DOCUMENT ME!
407
     *
408
     * @author Vicente Caballero Navarro
409
     */
410
    class Axis1EndSelHandler extends AbstractHandler implements CuadrantHandler {
411
        /**
412
         * Crea un nuevo PointHandler.
413
         *
414
         * @param i
415
         *            DOCUMENT ME!
416
         * @param x
417
         *            DOCUMENT ME!
418
         * @param y
419
         *            DOCUMENT ME!
420
         */
421
        public Axis1EndSelHandler(int i, double x, double y) {
422
            point = new Point2D.Double(x, y);
423
            index = i;
424
        }
425

    
426
        /**
427
         * DOCUMENT ME!
428
         *
429
         * @param x
430
         *            DOCUMENT ME!
431
         * @param y
432
         *            DOCUMENT ME!
433
         *
434
         * @return DOCUMENT ME!
435
         */
436
        public void move(double x, double y) {
437

    
438
        }
439

    
440
        /**
441
         * @see org.gvsig.fmap.geom.handler.Handler#set(double, double)
442
         */
443
        public void set(double x, double y) {
444
            // double dx=x-getPoint().getX();
445
            // double dy=y-getPoint().getY();
446
            Point2D center = new Point2D.Double((axis1Start.getX() + axis1End.getX()) / 2,
447
                (axis1Start.getY() + axis1End.getY()) / 2);
448
            // Point2D[]
449
            // p1=TrigonometricalFunctions.getPerpendicular(init,end,center);
450
            // Point2D[]
451
            // p2=TrigonometricalFunctions.getPerpendicular(p1[0],p1[1],new
452
            // Point2D.Double(x,y));
453

    
454
            // Point2D
455
            // pl=TrigonometricalFunctions.getIntersection(p2[0],p2[1],p1[0],p1[1]);
456
            // double xdist=2*pl.distance(x,y);
457
            double xdist = 2 * center.distance(x, y);
458
            axis1End = UtilFunctions.getPoint(center, axis1End, center.distance(x, y));
459
            // end=new Point2D.Double(end.getX()+dx,end.getY()+dy);
460
            axis1Start = UtilFunctions.getPoint(axis1End, center, xdist);
461
            Arc2D.Double arc = new Arc2D.Double(axis1Start.getX(), axis1Start.getY()
462
                - semiAxis2Length, xdist, 2 * semiAxis2Length, Math.toDegrees(angSt), Math.toDegrees(angExt), Arc2D.OPEN);
463
            // Point2D rotationPoint = new Point2D.Double(init.getX() + xdist
464
            // /2, init.getY());
465

    
466
            double angle = UtilFunctions.getAngle(axis1Start, axis1End);
467
            AffineTransform mT = AffineTransform.getRotateInstance(angle, axis1Start
468
                .getX(), axis1Start.getY());
469
            gp = new GeneralPathX(arc.getPathIterator(null));
470
            gp.transform(mT);
471

    
472
        }
473
    }
474

    
475
    /**
476
     * DOCUMENT ME!
477
     *
478
     * @author Vicente Caballero Navarro
479
     */
480
    class RadioSelYHandler extends AbstractHandler implements CuadrantHandler {
481
        /**
482
         * Crea un nuevo PointHandler.
483
         *
484
         * @param i
485
         *            DOCUMENT ME!
486
         * @param x
487
         *            DOCUMENT ME!
488
         * @param y
489
         *            DOCUMENT ME!
490
         */
491
        public RadioSelYHandler(int i, double x, double y) {
492
            point = new Point2D.Double(x, y);
493
            index = i;
494
        }
495

    
496
        /**
497
         * DOCUMENT ME!
498
         *
499
         * @param x
500
         *            DOCUMENT ME!
501
         * @param y
502
         *            DOCUMENT ME!
503
         *
504
         * @return DOCUMENT ME!
505
         */
506
        public void move(double x, double y) {
507

    
508
        }
509

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

    
531
            double angle = UtilFunctions.getAngle(axis1Start, axis1End);
532
            AffineTransform mT = AffineTransform.getRotateInstance(angle, axis1Start
533
                .getX(), axis1Start.getY());
534
            gp = new GeneralPathX(arc.getPathIterator(null));
535
            gp.transform(mT);
536
        }
537
    }
538

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

    
541

    
542

    
543
    /* (non-Javadoc)
544
     * @see com.iver.cit.gvsig.fmap.core.FPolyline2D#intersects(java.awt.geom.Rectangle2D)
545
     */
546
    public boolean intersects(Rectangle2D r) {
547
        return gp.intersects(r);
548
    }
549

    
550
    /* (non-Javadoc)
551
     * @see org.gvsig.fmap.geom.primitive.EllipticArc#setPoints(org.gvsig.fmap.geom.primitive.Point, java.awt.geom.Point2D, double, double, double)
552
     */
553
    public void setPoints(Point axis1Start, Point axis1End,
554
        double semiAxis2Length, double angSt, double angExt) {
555
        Point2D _axis1Start = new java.awt.geom.Point2D.Double(axis1Start.getCoordinateAt(0), axis1Start.getCoordinateAt(1));
556
        Point2D _axis1End = new java.awt.geom.Point2D.Double(axis1End.getCoordinateAt(0), axis1End.getCoordinateAt(1));
557
        setPoints(_axis1Start, _axis1End, semiAxis2Length, angSt, angExt);
558
    }
559

    
560
    /* (non-Javadoc)
561
     * @see org.gvsig.fmap.geom.primitive.EllipticArc#setPoints(java.awt.geom.Point2D, java.awt.geom.Point2D, double, double, double)
562
     */
563
    private void setPoints(Point2D axis1Start, Point2D axis1End,
564
        double semiAxis2Length, double angSt, double angExt) {
565
        double axis1Lenght = axis1Start.distance(axis1End);
566
        Point2D center = new Point2D.Double((axis1Start.getX()+axis1End.getX())/2, (axis1Start.getY()+axis1End.getY())/2);
567
        double x = center.getX()-axis1Lenght/2;
568
        double y = center.getY()-semiAxis2Length;
569

    
570
        double angle = UtilFunctions.getAngle(center, axis1Start);
571

    
572
        Arc2D.Double arc = new Arc2D.Double(
573
            x,
574
            y,
575
            axis1Lenght,
576
            2 * semiAxis2Length,
577
            Math.toDegrees(angSt),
578
            Math.toDegrees(angExt),
579
            Arc2D.OPEN);
580
        AffineTransform mT = AffineTransform.getRotateInstance(angle,
581
            center.getX(), center.getY());
582
        GeneralPathX gp = new GeneralPathX(arc.getPathIterator(null));
583
        gp.transform(mT);
584

    
585
        this.gp = gp;
586
        this.axis1Start = axis1Start;
587
        this.axis1End = axis1End;
588
        this.semiAxis2Length = semiAxis2Length;
589
        this.angSt = angSt;
590
        this.angExt = angExt;                
591
    }
592

    
593
    /*
594
     * (non-Javadoc)
595
     * @see org.gvsig.fmap.geom.primitive.Curve2D#setGeneralPath(org.gvsig.fmap.geom.primitive.GeneralPathX)
596
     */
597
    public void setGeneralPath(GeneralPathX generalPathX) {
598
        throw new UnsupportedOperationException("Use setPoints(Point center, Point radious)");
599
    }
600

    
601
    public SurfaceAppearance getSurfaceAppearance() {
602
        // TODO Auto-generated method stub
603
        return null;
604
    }
605

    
606
    public void setSurfaceAppearance(SurfaceAppearance app) {
607
        // TODO Auto-generated method stub
608

    
609
    }
610
}