Statistics
| Revision:

svn-gvsig-desktop / trunk / org.gvsig.desktop / org.gvsig.desktop.compat.cdc / org.gvsig.fmap.geometry / org.gvsig.fmap.geometry.impl / src / main / java / org / gvsig / fmap / geom / primitive / impl / EllipticArc2D.java @ 40559

History | View | Annotate | Download (19.9 KB)

1
/**
2
 * gvSIG. Desktop Geographic Information System.
3
 *
4
 * Copyright (C) 2007-2013 gvSIG Association.
5
 *
6
 * This program is free software; you can redistribute it and/or
7
 * modify it under the terms of the GNU General Public License
8
 * as published by the Free Software Foundation; either version 3
9
 * of the License, or (at your option) any later version.
10
 *
11
 * This program is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 * GNU General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU General Public License
17
 * along with this program; if not, write to the Free Software
18
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19
 * MA  02110-1301, USA.
20
 *
21
 * For any additional information, do not hesitate to contact us
22
 * at info AT gvsig.com, or visit our website www.gvsig.com.
23
 */
24
package org.gvsig.fmap.geom.primitive.impl;
25

    
26
import java.awt.geom.AffineTransform;
27
import java.awt.geom.Arc2D;
28
import java.awt.geom.Point2D;
29
import java.awt.geom.Rectangle2D;
30
import java.util.ArrayList;
31

    
32
import org.cresques.cts.IProjection;
33
import org.gvsig.fmap.geom.Geometry;
34
import org.gvsig.fmap.geom.handler.AbstractHandler;
35
import org.gvsig.fmap.geom.handler.CuadrantHandler;
36
import org.gvsig.fmap.geom.handler.Handler;
37
import org.gvsig.fmap.geom.primitive.EllipticArc;
38
import org.gvsig.fmap.geom.primitive.GeneralPathX;
39
import org.gvsig.fmap.geom.primitive.Point;
40
import org.gvsig.fmap.geom.primitive.SurfaceAppearance;
41
import org.gvsig.fmap.geom.type.GeometryType;
42
import org.gvsig.fmap.geom.util.UtilFunctions;
43

    
44

    
45

    
46
/**
47
 * DOCUMENT ME!
48
 *
49
 * @author Vicente Caballero Navarro
50
 */
51
public class EllipticArc2D extends Curve2D implements EllipticArc {
52
    private static final long serialVersionUID = 2988037614443119814L;
53

    
54
    private Point2D axis1Start;
55
    private Point2D axis1End;
56
    private double semiAxis2Length;
57
    private double angSt;
58
    private double angExt;
59

    
60
    /**
61
     * The constructor with the GeometryType like and argument 
62
     * is used by the {@link GeometryType}{@link #create()}
63
     * to create the geometry
64
     * @param type
65
     * The geometry type
66
     */
67
    public EllipticArc2D(GeometryType geometryType) {
68
        super(geometryType);                
69
    }
70

    
71
    /**
72
     * Constructor used in the {@link Geometry#cloneGeometry()} method
73
     * @param id
74
     * @param projection
75
     * @param gpx
76
     * @param axis1Start
77
     * @param axis1End
78
     * @param semiAxis2Length
79
     * @param angSt
80
     * @param angExt
81
     */
82
    EllipticArc2D(GeometryType geometryType, String id, IProjection projection, GeneralPathX gpx, Point2D axis1Start,Point2D axis1End, double semiAxis2Length, double angSt, double angExt) {
83
        super(geometryType, id, projection, gpx);
84
        this.axis1Start = axis1Start;
85
        this.axis1End = axis1End;
86
        this.semiAxis2Length = semiAxis2Length;
87
        this.angSt = angSt;
88
        this.angExt = angExt;
89
    }
90

    
91
    /*
92
     * (non-Javadoc)
93
     * @see org.gvsig.fmap.geom.primitive.EllipticArc#getAxis1Start()
94
     */
95
    public Point getAxis1Start(){
96
        try {
97
            return new org.gvsig.fmap.geom.primitive.impl.Point2D(axis1Start);
98
        } catch (Exception e){
99
            return null;
100
        }
101
    }
102

    
103
    /*
104
     * (non-Javadoc)
105
     * @see org.gvsig.fmap.geom.primitive.EllipticArc#getAxis1End()
106
     */
107
    public Point getAxis1End(){
108
        try {
109
            return new org.gvsig.fmap.geom.primitive.impl.Point2D(axis1End);
110
        } catch (Exception e){
111
            return null;
112
        }
113
    }
114

    
115
    /*
116
     * (non-Javadoc)
117
     * @see org.gvsig.fmap.geom.primitive.EllipticArc#getAxis2Dist()
118
     */
119
    public double getAxis2Dist(){
120
        return this.semiAxis2Length;
121
    }
122

    
123
    /*
124
     * (non-Javadoc)
125
     * @see org.gvsig.fmap.geom.primitive.EllipticArc#getAngSt()
126
     */
127
    public double getAngSt(){
128
        return this.angSt;
129
    }
130

    
131
    /*
132
     * (non-Javadoc)
133
     * @see org.gvsig.fmap.geom.primitive.EllipticArc#getAngExt()
134
     */
135
    public double getAngExt(){
136
        return this.angExt;
137
    }
138

    
139
    /*
140
     * (non-Javadoc)
141
     * @see org.gvsig.fmap.geom.primitive.impl.OrientablePrimitive2D#transform(java.awt.geom.AffineTransform)
142
     */
143
    public void transform(AffineTransform at) {
144
        
145
        if (at == null) {
146
            return;
147
        }
148

    
149
        Point2D center = new Point2D.Double((axis1Start.getX() + axis1End.getX()) / 2,
150
            (axis1Start.getY() + axis1End.getY()) / 2);
151
        Point2D pdist = UtilFunctions.getPerpendicularPoint(axis1Start, axis1End, center,
152
            semiAxis2Length);
153
        Point2D aux1 = new Point2D.Double();
154
        at.transform(axis1Start, aux1);
155
        axis1Start = aux1;
156
        Point2D aux2 = new Point2D.Double();
157
        at.transform(axis1End, aux2);
158
        axis1End = aux2;
159

    
160
        center = new Point2D.Double((axis1Start.getX() + axis1End.getX()) / 2, (axis1Start
161
            .getY() + axis1End.getY()) / 2);
162

    
163
        Point2D aux3 = new Point2D.Double();
164
        at.transform(pdist, aux3);
165
        semiAxis2Length = center.distance(aux3);
166
        gp.transform(at);
167
    }
168

    
169
    /*
170
     * (non-Javadoc)
171
     * @see org.gvsig.fmap.geom.primitive.impl.Curve2D#getShapeType()
172
     */
173
    public int getShapeType() {
174
        return TYPES.ELLIPTICARC;
175
    }
176

    
177
    /*
178
     * (non-Javadoc)
179
     * @see org.gvsig.fmap.geom.primitive.impl.OrientablePrimitive2D#getStretchingHandlers()
180
     */
181
    public Handler[] getStretchingHandlers() {
182
        ArrayList handlers = new ArrayList();
183
        Rectangle2D rect = this.getBounds2D();
184
        handlers.add(new CenterHandler(0, rect.getCenterX(), rect.getCenterY()));
185
        return (Handler[]) handlers.toArray(new Handler[0]);
186
    }
187

    
188
    /*
189
     * (non-Javadoc)
190
     * @see org.gvsig.fmap.geom.primitive.impl.OrientablePrimitive2D#getSelectHandlers()
191
     */
192
    public Handler[] getSelectHandlers() {
193
        //TODO: Faltaria tener en cuenta handlers para los angulos angSt y angExt
194
        ArrayList handlers = new ArrayList();
195
        Rectangle2D rect = this.getBounds2D();
196
        handlers.add(new CenterSelHandler(0, rect.getCenterX(), rect.getCenterY()));
197
        handlers.add(new Axis1StSelHandler(1, axis1Start.getX(), axis1Start.getY()));
198
        handlers.add(new Axis1EndSelHandler(2, axis1End.getX(), axis1End.getY()));
199
        Point2D mediop = new Point2D.Double((axis1End.getX() + axis1Start.getX()) / 2,
200
            (axis1End.getY() + axis1Start.getY()) / 2);
201
        Point2D[] p = UtilFunctions.getPerpendicular(axis1Start, axis1End, mediop);
202
        Point2D u = UtilFunctions.getPoint(mediop, p[1], semiAxis2Length);
203
        Point2D d = UtilFunctions.getPoint(mediop, p[1], -semiAxis2Length);
204

    
205
        handlers.add(new RadioSelYHandler(3, u.getX(), u.getY()));
206
        handlers.add(new RadioSelYHandler(4, d.getX(), d.getY()));
207

    
208
        return (Handler[]) handlers.toArray(new Handler[0]);
209
    }
210

    
211
    /**
212
     * DOCUMENT ME!
213
     *
214
     * @author Vicente Caballero Navarro
215
     */
216
    class CenterHandler extends AbstractHandler implements Handler {
217
        /**
218
         * Crea un nuevo PointHandler.
219
         *
220
         * @param i
221
         *            DOCUMENT ME!
222
         * @param x
223
         *            DOCUMENT ME!
224
         * @param y
225
         *            DOCUMENT ME!
226
         */
227
        public CenterHandler(int i, double x, double y) {
228
            point = new Point2D.Double(x, y);
229
            index = i;
230
        }
231

    
232
        /**
233
         * DOCUMENT ME!
234
         *
235
         * @param x
236
         *            DOCUMENT ME!
237
         * @param y
238
         *            DOCUMENT ME!
239
         *
240
         * @return DOCUMENT ME!
241
         */
242
        public void move(double x, double y) {
243
            Point point;
244
            for (int i = 0; i < gp.getNumCoords(); i++) {
245
                point = gp.getPointAt(i);
246
                point.setX(point.getX() + x);
247
                point.setY(point.getY() + y);
248
            }
249
            axis1Start = new Point2D.Double(axis1Start.getX() + x, axis1Start.getY() + y);
250
            axis1End = new Point2D.Double(axis1End.getX() + x, axis1End.getY() + y);
251
        }
252

    
253
        /**
254
         * @see org.gvsig.fmap.geom.handler.Handler#set(double, double)
255
         */
256
        public void set(double x, double y) {
257
        }
258
    }
259

    
260
    /**
261
     * DOCUMENT ME!
262
     *
263
     * @author Vicente Caballero Navarro
264
     */
265
    class CenterSelHandler extends AbstractHandler implements Handler {
266
        /**
267
         * Crea un nuevo PointHandler.
268
         *
269
         * @param i
270
         *            DOCUMENT ME!
271
         * @param x
272
         *            DOCUMENT ME!
273
         * @param y
274
         *            DOCUMENT ME!
275
         */
276
        public CenterSelHandler(int i, double x, double y) {
277
            point = new Point2D.Double(x, y);
278
            index = i;
279
        }
280

    
281
        /**
282
         * DOCUMENT ME!
283
         *
284
         * @param x
285
         *            DOCUMENT ME!
286
         * @param y
287
         *            DOCUMENT ME!
288
         *
289
         * @return DOCUMENT ME!
290
         */
291
        public void move(double x, double y) {
292
            Point point;
293
            for (int i = 0; i < gp.getNumCoords(); i++) {
294
                point = gp.getPointAt(i);
295
                point.setX(point.getX() + x);
296
                point.setY(point.getY() + y);
297
            }
298
        }
299

    
300
        /**
301
         * @see org.gvsig.fmap.geom.handler.Handler#set(double, double)
302
         */
303
        public void set(double x, double y) {
304
            Point2D center = new Point2D.Double((axis1Start.getX() + axis1End.getX()) / 2,
305
                (axis1Start.getY() + axis1End.getY()) / 2);
306
            double dx = x - center.getX();
307
            double dy = y - center.getY();
308
            Point point;
309
            for (int i = 0; i < gp.getNumCoords(); i++) {
310
                point = gp.getPointAt(i);
311
                point.setX(point.getX() + dx);
312
                point.setY(point.getY() + dy);
313
            }
314
            axis1Start = new Point2D.Double(axis1Start.getX() + dx, axis1Start.getY() + dy);
315
            axis1End = new Point2D.Double(axis1End.getX() + dx, axis1End.getY() + dy);
316
        }
317
    }
318

    
319
    /**
320
     * DOCUMENT ME!
321
     *
322
     * @author Vicente Caballero Navarro
323
     */
324
    class Axis1StSelHandler extends AbstractHandler implements CuadrantHandler {
325
        /**
326
         * Crea un nuevo PointHandler.
327
         *
328
         * @param i
329
         *            DOCUMENT ME!
330
         * @param x
331
         *            DOCUMENT ME!
332
         * @param y
333
         *            DOCUMENT ME!
334
         */
335
        public Axis1StSelHandler(int i, double x, double y) {
336
            point = new Point2D.Double(x, y);
337
            index = i;
338
        }
339

    
340
        /**
341
         * DOCUMENT ME!
342
         *
343
         * @param x
344
         *            DOCUMENT ME!
345
         * @param y
346
         *            DOCUMENT ME!
347
         *
348
         * @return DOCUMENT ME!
349
         */
350
        public void move(double x, double y) {
351

    
352
        }
353

    
354
        /**
355
         * @see org.gvsig.fmap.geom.handler.Handler#set(double, double)
356
         */
357
        public void set(double x, double y) {
358
            // TODO comentado para quitar warning: double dx=x-init.getX();
359
            // TODO comentado para quitar warning: double dy=y-init.getY();
360
            Point2D center = new Point2D.Double((axis1Start.getX() + axis1End.getX()) / 2,
361
                (axis1Start.getY() + axis1End.getY()) / 2);
362
            // Point2D[]
363
            // p1=TrigonometricalFunctions.getPerpendicular(init,end,center);
364
            // Point2D[]
365
            // p2=TrigonometricalFunctions.getPerpendicular(p1[0],p1[1],new
366
            // Point2D.Double(x,y));
367

    
368
            // Point2D
369
            // pl=TrigonometricalFunctions.getIntersection(p2[0],p2[1],p1[0],p1[1]);
370
            // double xdist=2*pl.distance(x,y);
371
            double xdist = 2 * center.distance(x, y);
372
            // init=new Point2D.Double(init.getX()+dx,init.getY()+dy);
373
            axis1Start = UtilFunctions.getPoint(center, axis1Start, center.distance(x, y));
374
            axis1End = UtilFunctions.getPoint(axis1Start, center, xdist);
375
            Arc2D.Double arc = new Arc2D.Double(axis1Start.getX(), axis1Start.getY()
376
                - semiAxis2Length, xdist, 2 * semiAxis2Length, Math.toDegrees(angSt), Math.toDegrees(angExt), Arc2D.OPEN);
377
            // TODO comentado para quitar warning: Point2D rotationPoint = new
378
            // Point2D.Double(init.getX() + xdist /2, init.getY());
379

    
380
            double angle = UtilFunctions.getAngle(axis1Start, axis1End);
381
            AffineTransform mT = AffineTransform.getRotateInstance(angle, axis1Start
382
                .getX(), axis1Start.getY());
383
            gp = new GeneralPathX(arc.getPathIterator(null));
384
            gp.transform(mT);
385

    
386
        }
387
    }
388

    
389
    /**
390
     * DOCUMENT ME!
391
     *
392
     * @author Vicente Caballero Navarro
393
     */
394
    class Axis1EndSelHandler extends AbstractHandler implements CuadrantHandler {
395
        /**
396
         * Crea un nuevo PointHandler.
397
         *
398
         * @param i
399
         *            DOCUMENT ME!
400
         * @param x
401
         *            DOCUMENT ME!
402
         * @param y
403
         *            DOCUMENT ME!
404
         */
405
        public Axis1EndSelHandler(int i, double x, double y) {
406
            point = new Point2D.Double(x, y);
407
            index = i;
408
        }
409

    
410
        /**
411
         * DOCUMENT ME!
412
         *
413
         * @param x
414
         *            DOCUMENT ME!
415
         * @param y
416
         *            DOCUMENT ME!
417
         *
418
         * @return DOCUMENT ME!
419
         */
420
        public void move(double x, double y) {
421

    
422
        }
423

    
424
        /**
425
         * @see org.gvsig.fmap.geom.handler.Handler#set(double, double)
426
         */
427
        public void set(double x, double y) {
428
            // double dx=x-getPoint().getX();
429
            // double dy=y-getPoint().getY();
430
            Point2D center = new Point2D.Double((axis1Start.getX() + axis1End.getX()) / 2,
431
                (axis1Start.getY() + axis1End.getY()) / 2);
432
            // Point2D[]
433
            // p1=TrigonometricalFunctions.getPerpendicular(init,end,center);
434
            // Point2D[]
435
            // p2=TrigonometricalFunctions.getPerpendicular(p1[0],p1[1],new
436
            // Point2D.Double(x,y));
437

    
438
            // Point2D
439
            // pl=TrigonometricalFunctions.getIntersection(p2[0],p2[1],p1[0],p1[1]);
440
            // double xdist=2*pl.distance(x,y);
441
            double xdist = 2 * center.distance(x, y);
442
            axis1End = UtilFunctions.getPoint(center, axis1End, center.distance(x, y));
443
            // end=new Point2D.Double(end.getX()+dx,end.getY()+dy);
444
            axis1Start = UtilFunctions.getPoint(axis1End, center, xdist);
445
            Arc2D.Double arc = new Arc2D.Double(axis1Start.getX(), axis1Start.getY()
446
                - semiAxis2Length, xdist, 2 * semiAxis2Length, Math.toDegrees(angSt), Math.toDegrees(angExt), Arc2D.OPEN);
447
            // Point2D rotationPoint = new Point2D.Double(init.getX() + xdist
448
            // /2, init.getY());
449

    
450
            double angle = UtilFunctions.getAngle(axis1Start, axis1End);
451
            AffineTransform mT = AffineTransform.getRotateInstance(angle, axis1Start
452
                .getX(), axis1Start.getY());
453
            gp = new GeneralPathX(arc.getPathIterator(null));
454
            gp.transform(mT);
455

    
456
        }
457
    }
458

    
459
    /**
460
     * DOCUMENT ME!
461
     *
462
     * @author Vicente Caballero Navarro
463
     */
464
    class RadioSelYHandler extends AbstractHandler implements CuadrantHandler {
465
        /**
466
         * Crea un nuevo PointHandler.
467
         *
468
         * @param i
469
         *            DOCUMENT ME!
470
         * @param x
471
         *            DOCUMENT ME!
472
         * @param y
473
         *            DOCUMENT ME!
474
         */
475
        public RadioSelYHandler(int i, double x, double y) {
476
            point = new Point2D.Double(x, y);
477
            index = i;
478
        }
479

    
480
        /**
481
         * DOCUMENT ME!
482
         *
483
         * @param x
484
         *            DOCUMENT ME!
485
         * @param y
486
         *            DOCUMENT ME!
487
         *
488
         * @return DOCUMENT ME!
489
         */
490
        public void move(double x, double y) {
491

    
492
        }
493

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

    
515
            double angle = UtilFunctions.getAngle(axis1Start, axis1End);
516
            AffineTransform mT = AffineTransform.getRotateInstance(angle, axis1Start
517
                .getX(), axis1Start.getY());
518
            gp = new GeneralPathX(arc.getPathIterator(null));
519
            gp.transform(mT);
520
        }
521
    }
522

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

    
525

    
526

    
527
    /* (non-Javadoc)
528
     * @see com.iver.cit.gvsig.fmap.core.FPolyline2D#intersects(java.awt.geom.Rectangle2D)
529
     */
530
    public boolean intersects(Rectangle2D r) {
531
        return gp.intersects(r);
532
    }
533

    
534
    /* (non-Javadoc)
535
     * @see org.gvsig.fmap.geom.primitive.EllipticArc#setPoints(org.gvsig.fmap.geom.primitive.Point, java.awt.geom.Point2D, double, double, double)
536
     */
537
    public void setPoints(Point axis1Start, Point axis1End,
538
        double semiAxis2Length, double angSt, double angExt) {
539
        Point2D _axis1Start = new java.awt.geom.Point2D.Double(axis1Start.getCoordinateAt(0), axis1Start.getCoordinateAt(1));
540
        Point2D _axis1End = new java.awt.geom.Point2D.Double(axis1End.getCoordinateAt(0), axis1End.getCoordinateAt(1));
541
        setPoints(_axis1Start, _axis1End, semiAxis2Length, angSt, angExt);
542
    }
543

    
544
    /* (non-Javadoc)
545
     * @see org.gvsig.fmap.geom.primitive.EllipticArc#setPoints(java.awt.geom.Point2D, java.awt.geom.Point2D, double, double, double)
546
     */
547
    private void setPoints(Point2D axis1Start, Point2D axis1End,
548
        double semiAxis2Length, double angSt, double angExt) {
549
        double axis1Lenght = axis1Start.distance(axis1End);
550
        Point2D center = new Point2D.Double((axis1Start.getX()+axis1End.getX())/2, (axis1Start.getY()+axis1End.getY())/2);
551
        double x = center.getX()-axis1Lenght/2;
552
        double y = center.getY()-semiAxis2Length;
553

    
554
        double angle = UtilFunctions.getAngle(center, axis1Start);
555

    
556
        Arc2D.Double arc = new Arc2D.Double(
557
            x,
558
            y,
559
            axis1Lenght,
560
            2 * semiAxis2Length,
561
            Math.toDegrees(angSt),
562
            Math.toDegrees(angExt),
563
            Arc2D.OPEN);
564
        AffineTransform mT = AffineTransform.getRotateInstance(angle,
565
            center.getX(), center.getY());
566
        GeneralPathX gp = new GeneralPathX(arc.getPathIterator(null));
567
        gp.transform(mT);
568

    
569
        this.gp = gp;
570
        this.axis1Start = axis1Start;
571
        this.axis1End = axis1End;
572
        this.semiAxis2Length = semiAxis2Length;
573
        this.angSt = angSt;
574
        this.angExt = angExt;                
575
    }
576

    
577
    /*
578
     * (non-Javadoc)
579
     * @see org.gvsig.fmap.geom.primitive.Curve2D#setGeneralPath(org.gvsig.fmap.geom.primitive.GeneralPathX)
580
     */
581
    public void setGeneralPath(GeneralPathX generalPathX) {
582
        throw new UnsupportedOperationException("Use setPoints(Point center, Point radious)");
583
    }
584

    
585
    public SurfaceAppearance getSurfaceAppearance() {
586
        // TODO Auto-generated method stub
587
        return null;
588
    }
589

    
590
    public void setSurfaceAppearance(SurfaceAppearance app) {
591
        // TODO Auto-generated method stub
592

    
593
    }
594
}