Statistics
| Revision:

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

History | View | Annotate | Download (20.2 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
        
166
        if (at == null) {
167
            return;
168
        }
169

    
170
        Point2D center = new Point2D.Double((axis1Start.getX() + axis1End.getX()) / 2,
171
            (axis1Start.getY() + axis1End.getY()) / 2);
172
        Point2D pdist = UtilFunctions.getPerpendicularPoint(axis1Start, axis1End, center,
173
            semiAxis2Length);
174
        Point2D aux1 = new Point2D.Double();
175
        at.transform(axis1Start, aux1);
176
        axis1Start = aux1;
177
        Point2D aux2 = new Point2D.Double();
178
        at.transform(axis1End, aux2);
179
        axis1End = aux2;
180

    
181
        center = new Point2D.Double((axis1Start.getX() + axis1End.getX()) / 2, (axis1Start
182
            .getY() + axis1End.getY()) / 2);
183

    
184
        Point2D aux3 = new Point2D.Double();
185
        at.transform(pdist, aux3);
186
        semiAxis2Length = center.distance(aux3);
187
        gp.transform(at);
188
    }
189

    
190
    /*
191
     * (non-Javadoc)
192
     * @see org.gvsig.fmap.geom.primitive.impl.Curve2D#getShapeType()
193
     */
194
    public int getShapeType() {
195
        return TYPES.ELLIPTICARC;
196
    }
197

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

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

    
226
        handlers.add(new RadioSelYHandler(3, u.getX(), u.getY()));
227
        handlers.add(new RadioSelYHandler(4, d.getX(), d.getY()));
228

    
229
        return (Handler[]) handlers.toArray(new Handler[0]);
230
    }
231

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

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

    
274
        /**
275
         * @see org.gvsig.fmap.geom.handler.Handler#set(double, double)
276
         */
277
        public void set(double x, double y) {
278
        }
279
    }
280

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

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

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

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

    
361
        /**
362
         * DOCUMENT ME!
363
         *
364
         * @param x
365
         *            DOCUMENT ME!
366
         * @param y
367
         *            DOCUMENT ME!
368
         *
369
         * @return DOCUMENT ME!
370
         */
371
        public void move(double x, double y) {
372

    
373
        }
374

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

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

    
401
            double angle = UtilFunctions.getAngle(axis1Start, axis1End);
402
            AffineTransform mT = AffineTransform.getRotateInstance(angle, axis1Start
403
                .getX(), axis1Start.getY());
404
            gp = new GeneralPathX(arc.getPathIterator(null));
405
            gp.transform(mT);
406

    
407
        }
408
    }
409

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

    
431
        /**
432
         * DOCUMENT ME!
433
         *
434
         * @param x
435
         *            DOCUMENT ME!
436
         * @param y
437
         *            DOCUMENT ME!
438
         *
439
         * @return DOCUMENT ME!
440
         */
441
        public void move(double x, double y) {
442

    
443
        }
444

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

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

    
471
            double angle = UtilFunctions.getAngle(axis1Start, axis1End);
472
            AffineTransform mT = AffineTransform.getRotateInstance(angle, axis1Start
473
                .getX(), axis1Start.getY());
474
            gp = new GeneralPathX(arc.getPathIterator(null));
475
            gp.transform(mT);
476

    
477
        }
478
    }
479

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

    
501
        /**
502
         * DOCUMENT ME!
503
         *
504
         * @param x
505
         *            DOCUMENT ME!
506
         * @param y
507
         *            DOCUMENT ME!
508
         *
509
         * @return DOCUMENT ME!
510
         */
511
        public void move(double x, double y) {
512

    
513
        }
514

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

    
536
            double angle = UtilFunctions.getAngle(axis1Start, axis1End);
537
            AffineTransform mT = AffineTransform.getRotateInstance(angle, axis1Start
538
                .getX(), axis1Start.getY());
539
            gp = new GeneralPathX(arc.getPathIterator(null));
540
            gp.transform(mT);
541
        }
542
    }
543

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

    
546

    
547

    
548
    /* (non-Javadoc)
549
     * @see com.iver.cit.gvsig.fmap.core.FPolyline2D#intersects(java.awt.geom.Rectangle2D)
550
     */
551
    public boolean intersects(Rectangle2D r) {
552
        return gp.intersects(r);
553
    }
554

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

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

    
575
        double angle = UtilFunctions.getAngle(center, axis1Start);
576

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

    
590
        this.gp = gp;
591
        this.axis1Start = axis1Start;
592
        this.axis1End = axis1End;
593
        this.semiAxis2Length = semiAxis2Length;
594
        this.angSt = angSt;
595
        this.angExt = angExt;                
596
    }
597

    
598
    /*
599
     * (non-Javadoc)
600
     * @see org.gvsig.fmap.geom.primitive.Curve2D#setGeneralPath(org.gvsig.fmap.geom.primitive.GeneralPathX)
601
     */
602
    public void setGeneralPath(GeneralPathX generalPathX) {
603
        throw new UnsupportedOperationException("Use setPoints(Point center, Point radious)");
604
    }
605

    
606
    public SurfaceAppearance getSurfaceAppearance() {
607
        // TODO Auto-generated method stub
608
        return null;
609
    }
610

    
611
    public void setSurfaceAppearance(SurfaceAppearance app) {
612
        // TODO Auto-generated method stub
613

    
614
    }
615
}