Statistics
| Revision:

svn-gvsig-desktop / trunk / org.gvsig.desktop / org.gvsig.desktop.compat.cdc / org.gvsig.fmap.geometry / org.gvsig.fmap.geometry.jts / src / main / java / org / gvsig / fmap / geom / jts / primitive / curve / arc / AbstractArc.java @ 44612

History | View | Annotate | Download (16.8 KB)

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

    
25
import java.awt.Shape;
26
import java.awt.geom.AffineTransform;
27
import java.awt.geom.PathIterator;
28

    
29
import org.cresques.cts.CoordTransRuntimeException;
30
import org.cresques.cts.ICoordTrans;
31

    
32
import org.gvsig.fmap.geom.Geometry;
33
import org.gvsig.fmap.geom.jts.gputils.DefaultGeneralPathX;
34
import org.gvsig.fmap.geom.jts.primitive.curve.AbstractCurve;
35
import org.gvsig.fmap.geom.jts.primitive.point.PointJTS;
36
import org.gvsig.fmap.geom.jts.util.UtilFunctions;
37
import org.gvsig.fmap.geom.operation.GeometryOperationException;
38
import org.gvsig.fmap.geom.operation.GeometryOperationNotSupportedException;
39
import org.gvsig.fmap.geom.primitive.Arc;
40
import org.gvsig.fmap.geom.primitive.GeneralPathX;
41
import org.gvsig.fmap.geom.primitive.Point;
42

    
43

    
44
/**
45
 * @author fdiaz
46
 *
47
 */
48
public abstract class AbstractArc extends AbstractCurve implements Arc {
49

    
50
    /**
51
     *
52
     */
53
    private static final long serialVersionUID = 454301669807892457L;
54

    
55
    /**
56
     * @param type
57
     * @param subtype
58
     */
59
    protected AbstractArc(int subtype) {
60
        super(Geometry.TYPES.ARC, subtype);
61
    }
62

    
63
    protected Point init;
64

    
65
    /**
66
     * This is the middle point (belongs to the arc), not the center
67
     * of the circle/ellipse
68
     */
69
    protected Point middle;
70
    protected Point end;
71

    
72

    
73
    /* (non-Javadoc)
74
     * @see org.gvsig.fmap.geom.primitive.Curve#setPoints(org.gvsig.fmap.geom.primitive.Point, org.gvsig.fmap.geom.primitive.Point)
75
     */
76
    public void setPoints(Point initialPoint, Point endPoint) {
77
        String message = "Calling deprecated method setPoints of a arc";
78
        notifyDeprecated(message);
79
        throw new UnsupportedOperationException(message);
80
    }
81

    
82
    /* (non-Javadoc)
83
     * @see org.gvsig.fmap.geom.primitive.OrientablePrimitive#getCoordinateAt(int, int)
84
     */
85
    public double getCoordinateAt(int index, int dimension) {
86
        String message = "Calling deprecated method setPoints of a arc";
87
        notifyDeprecated(message);
88
        throw new UnsupportedOperationException(message);
89
    }
90

    
91
    /* (non-Javadoc)
92
     * @see org.gvsig.fmap.geom.primitive.OrientablePrimitive#setCoordinateAt(int, int, double)
93
     */
94
    public void setCoordinateAt(int index, int dimension, double value) {
95
        String message = "Calling deprecated method setPoints of a arc";
96
        notifyDeprecated(message);
97
        throw new UnsupportedOperationException(message);
98
    }
99

    
100
    /* (non-Javadoc)
101
     * @see org.gvsig.fmap.geom.primitive.OrientablePrimitive#addVertex(org.gvsig.fmap.geom.primitive.Point)
102
     */
103
    public void addVertex(Point point) {
104
        String message = "Calling deprecated method setPoints of a arc";
105
        notifyDeprecated(message);
106
        throw new UnsupportedOperationException(message);
107
    }
108

    
109
    /* (non-Javadoc)
110
     * @see org.gvsig.fmap.geom.primitive.OrientablePrimitive#addVertex(double, double)
111
     */
112
    public void addVertex(double x, double y) {
113
        String message = "Calling deprecated method setPoints of a arc";
114
        notifyDeprecated(message);
115
        throw new UnsupportedOperationException(message);
116
    }
117

    
118
    /* (non-Javadoc)
119
     * @see org.gvsig.fmap.geom.primitive.OrientablePrimitive#addVertex(double, double, double)
120
     */
121
    public void addVertex(double x, double y, double z) {
122
        String message = "Calling deprecated method setPoints of a arc";
123
        notifyDeprecated(message);
124
        throw new UnsupportedOperationException(message);
125
    }
126

    
127
    /* (non-Javadoc)
128
     * @see org.gvsig.fmap.geom.primitive.OrientablePrimitive#removeVertex(int)
129
     */
130
    public void removeVertex(int index) {
131
        String message = "Calling deprecated method setPoints of a arc";
132
        notifyDeprecated(message);
133
        throw new UnsupportedOperationException(message);
134
    }
135

    
136
    /* (non-Javadoc)
137
     * @see org.gvsig.fmap.geom.primitive.OrientablePrimitive#getVertex(int)
138
     */
139
    public Point getVertex(int index) {
140
        String message = "Calling deprecated method setPoints of a arc";
141
        notifyDeprecated(message);
142
        throw new UnsupportedOperationException(message);
143
    }
144

    
145
    /* (non-Javadoc)
146
     * @see org.gvsig.fmap.geom.primitive.OrientablePrimitive#getNumVertices()
147
     */
148
    public int getNumVertices() {
149
        String message = "Calling deprecated method setPoints of a arc";
150
        notifyDeprecated(message);
151
        throw new UnsupportedOperationException(message);
152
    }
153

    
154
    /* (non-Javadoc)
155
     * @see org.gvsig.fmap.geom.primitive.OrientablePrimitive#insertVertex(int, org.gvsig.fmap.geom.primitive.Point)
156
     */
157
    public void insertVertex(int index, Point p) {
158
        String message = "Calling deprecated method setPoints of a arc";
159
        notifyDeprecated(message);
160
        throw new UnsupportedOperationException(message);
161
    }
162

    
163
    /* (non-Javadoc)
164
     * @see org.gvsig.fmap.geom.primitive.OrientablePrimitive#setVertex(int, org.gvsig.fmap.geom.primitive.Point)
165
     */
166
    public void setVertex(int index, Point p) {
167
        String message = "Calling deprecated method setPoints of a arc";
168
        notifyDeprecated(message);
169
        throw new UnsupportedOperationException(message);
170
    }
171

    
172
    /* (non-Javadoc)
173
     * @see org.gvsig.fmap.geom.primitive.OrientablePrimitive#setGeneralPath(org.gvsig.fmap.geom.primitive.GeneralPathX)
174
     */
175
    public void setGeneralPath(GeneralPathX generalPathX) {
176
        String message = "Calling deprecated method setPoints of a arc";
177
        notifyDeprecated(message);
178
        throw new UnsupportedOperationException(message);
179
    }
180

    
181
    /* (non-Javadoc)
182
     * @see org.gvsig.fmap.geom.primitive.OrientablePrimitive#addMoveToVertex(org.gvsig.fmap.geom.primitive.Point)
183
     */
184
    public void addMoveToVertex(Point point) {
185
        String message = "Calling deprecated method setPoints of a arc";
186
        notifyDeprecated(message);
187
        throw new UnsupportedOperationException(message);
188
    }
189

    
190
    /* (non-Javadoc)
191
     * @see org.gvsig.fmap.geom.primitive.OrientablePrimitive#closePrimitive()
192
     */
193
    public void closePrimitive() {
194
        String message = "Calling deprecated method setPoints of a arc";
195
        notifyDeprecated(message);
196
        throw new UnsupportedOperationException(message);
197
    }
198

    
199
    /* (non-Javadoc)
200
     * @see org.gvsig.fmap.geom.primitive.OrientablePrimitive#ensureCapacity(int)
201
     */
202
    public void ensureCapacity(int capacity) {
203
        // TODO Auto-generated method stub
204

    
205
    }
206

    
207
    /* (non-Javadoc)
208
     * @see org.gvsig.fmap.geom.Geometry#reProject(org.cresques.cts.ICoordTrans)
209
     */
210
    public void reProject(ICoordTrans ct) {
211
        //FIXME: Esto solo ser?a correcto para transformaciones de traslaci?n, rotaci?n y escala
212
        // Ser?a incorrecto para las de deformaci?n en cizallamiento
213

    
214
        try {
215
        init.reProject(ct);
216
        middle.reProject(ct);
217
        end.reProject(ct);
218
        this.setProjection(ct.getPDest());
219
        } catch (CoordTransRuntimeException e){
220
            //Si ha fallado la reproyecci?n de alguno de los puntos, ponemos todas las coordenadas a 0
221
            init.setX(0);
222
            init.setY(0);
223
            middle.setX(0);
224
            middle.setY(0);
225
            end.setX(0);
226
            end.setY(0);
227
        }
228
    }
229

    
230
    /* (non-Javadoc)
231
     * @see org.gvsig.fmap.geom.Geometry#transform(java.awt.geom.AffineTransform)
232
     */
233
    public void transform(AffineTransform at) {
234
        //FIXME: Esto solo ser?a correcto para transformaciones de traslaci?n, rotaci?n y escala
235
        // Ser?a incorrecto para las de deformaci?n en cizallamiento
236

    
237
        init.transform(at);
238
        middle.transform(at);
239
        end.transform(at);
240
    }
241

    
242
    /* (non-Javadoc)
243
     * @see org.gvsig.fmap.geom.Geometry#getDimension()
244
     */
245
    public int getDimension() {
246
        return init.getDimension();
247
    }
248

    
249
    /* (non-Javadoc)
250
     * @see org.gvsig.fmap.geom.Geometry#getShape(java.awt.geom.AffineTransform)
251
     */
252
    public Shape getShape(AffineTransform affineTransform) {
253
        return new DefaultGeneralPathX(getPathIterator(affineTransform),false,0);
254
    }
255

    
256
    /* (non-Javadoc)
257
     * @see org.gvsig.fmap.geom.Geometry#getShape()
258
     */
259
    public Shape getShape() {
260
        return getShape(null);
261
    }
262

    
263
    /* (non-Javadoc)
264
     * @see org.gvsig.fmap.geom.jts.GeometryJTS#is3D()
265
     */
266
    public boolean is3D() {
267
        return ((PointJTS)init).is3D();
268
    }
269

    
270
    /**
271
     * @param initialPoint
272
     * @return
273
     */
274
    protected abstract Point fixPoint(Point point);
275

    
276
    /* (non-Javadoc)
277
     * @see org.gvsig.fmap.geom.primitive.Arc#setPoints(org.gvsig.fmap.geom.primitive.Point, org.gvsig.fmap.geom.primitive.Point, org.gvsig.fmap.geom.primitive.Point)
278
     */
279
    public void setPoints(Point startPoint, Point midPoint, Point endPoint) {
280
        init = fixPoint(startPoint);
281
        middle = fixPoint(midPoint);
282
        end = fixPoint(endPoint);
283
    }
284

    
285
    /* (non-Javadoc)
286
     * @see org.gvsig.fmap.geom.primitive.Arc#getInitPoint()
287
     */
288
    public Point getInitPoint() {
289
        return init;
290
    }
291

    
292
    /* (non-Javadoc)
293
     * @see org.gvsig.fmap.geom.primitive.Arc#getEndPoint()
294
     */
295
    public Point getEndPoint() {
296
        return end;
297
    }
298

    
299
    /* (non-Javadoc)
300
     * @see org.gvsig.fmap.geom.primitive.Arc#getMiddlePoint()
301
     */
302
    public Point getMiddlePoint() {
303
        return middle;
304
    }
305

    
306
    /**
307
     * Leaves the angle between PI and -PI
308
     * @param angle (radians)
309
     * @return
310
     */
311
    protected double normalizeAngle(double angle) {
312
        if (angle > -Math.PI && angle <= Math.PI) {
313
            return angle;
314
        }
315

    
316
        if (angle == Double.NEGATIVE_INFINITY || angle == Double.POSITIVE_INFINITY) {
317
            return 0;
318
        }
319

    
320
        double abs_ang = Math.abs(angle);
321
        double remove = Math.floor(abs_ang / (2 * Math.PI));
322
        remove = remove * 2 * Math.PI;
323
        double resp = 0;
324

    
325
        if (angle > 0) {
326
            resp = angle - remove;
327
            if (resp > Math.PI) {
328
                // final adjustment
329
                resp = resp - 2 * Math.PI;
330
            }
331
        } else {
332
            resp = angle + remove;
333
            if (resp <= -Math.PI) {
334
                // final adjustment
335
                resp = resp + 2 * Math.PI;
336
            }
337
        }
338

    
339
        return resp;
340
    }
341

    
342

    
343
    /* (non-Javadoc)
344
     * @see org.gvsig.fmap.geom.primitive.Arc#setPointsStartExt(org.gvsig.fmap.geom.primitive.Point, double, double, double)
345
     */
346
    public void setPointsStartExt(Point center, double radius, double startAngle, double angleExt) {
347
        setPoints(center, radius, startAngle, angleExt);
348
    }
349

    
350
    /* (non-Javadoc)
351
     * @see org.gvsig.fmap.geom.primitive.Arc#setPointsStartEnd(org.gvsig.fmap.geom.primitive.Point, double, double, double)
352
     */
353
    public void setPointsStartEnd(Point center, double radius, double startAngle, double endAngle) {
354

    
355
        if (startAngle == endAngle) {
356
            setPointsStartExt(center, radius, startAngle, 0);
357
        } else {
358

    
359
            /*
360
             * Normalize then force clockwise:
361
             */
362
            double norm_start = normalizeAngle(startAngle);
363
            double norm_end = normalizeAngle(endAngle);
364
            double ang_ext = 0;
365

    
366
            // clockwise
367
            // ang_ext must be positive
368
            if (norm_start >= norm_end) {
369
                ang_ext = norm_start - norm_end;
370
            } else {
371
                ang_ext = 2 * Math.PI - (norm_end - norm_start);
372
            }
373
            setPointsStartExt(center, radius, startAngle, ang_ext);
374

    
375
            // finally call other method with ang_ext
376
        }
377
    }
378

    
379
    /* (non-Javadoc)
380
     * @see org.gvsig.fmap.geom.Geometry#getGeneralPath()
381
     */
382
    public GeneralPathX getGeneralPath() {
383

    
384
       GeneralPathX gp = new DefaultGeneralPathX(getPathIterator(null, getManager().getFlatness()), is3D(), 0.0);
385
        return gp;
386
    }
387

    
388

    
389
    /* (non-Javadoc)
390
     * @see org.gvsig.fmap.geom.Geometry#getPathIterator(java.awt.geom.AffineTransform)
391
     */
392
    public PathIterator getPathIterator(AffineTransform at) {
393
        return getPathIterator(at, getManager().getFlatness());
394
    }
395

    
396

    
397
    /* (non-Javadoc)
398
     * @see org.gvsig.fmap.geom.Geometry#getPathIterator(java.awt.geom.AffineTransform, double)
399
     */
400
    public PathIterator getPathIterator(AffineTransform at, double flatness) {
401

    
402
        java.awt.geom.Point2D.Double p1 = new java.awt.geom.Point2D.Double(init.getX(), init.getY());
403
        java.awt.geom.Point2D.Double p2 = new java.awt.geom.Point2D.Double(middle.getX(), middle.getY());
404
        java.awt.geom.Point2D.Double p3 = new java.awt.geom.Point2D.Double(end.getX(), end.getY());
405

    
406
        java.awt.geom.Arc2D arco = UtilFunctions.createArc(p1, p2, p3);
407
        if (arco == null) {
408
            logger.info("Did not set arc points (probably aligned points): " + p1.getX() + " " + p1.getY() + " :: "
409
                + p2.getX() + " " + p2.getY() + " :: " + p3.getX() + " " + p3.getY());
410
            throw new IllegalArgumentException("Did not set arc points (probably aligned points).");
411
        }
412

    
413
        return arco.getPathIterator(at, flatness);
414
    }
415

    
416
    /* (non-Javadoc)
417
     * @see org.gvsig.fmap.geom.jts.GeometryJTS#flip()
418
     */
419
    public void flip() throws GeometryOperationNotSupportedException, GeometryOperationException {
420
        Point aux = init;
421
        init = end;
422
        end = aux;
423
    }
424

    
425

    
426
    /* (non-Javadoc)
427
     * @see org.gvsig.fmap.geom.primitive.Arc#getStartAngle()
428
     */
429
    public double getStartAngle() throws GeometryOperationNotSupportedException, GeometryOperationException {
430
        return getAngle(getCenterPoint(), getInitPoint());
431
    }
432

    
433
    /* (non-Javadoc)
434
     * @see org.gvsig.fmap.geom.primitive.Arc#getEndAngle()
435
     */
436
    public double getEndAngle() throws GeometryOperationNotSupportedException, GeometryOperationException {
437
        return getAngle(getCenterPoint(), getEndPoint());
438
    }
439

    
440
    private double getAngle(Point start, Point end) throws GeometryOperationNotSupportedException, GeometryOperationException {
441
        double angle = Math.acos((end.getX() - start.getX()) / start.distance(end));
442

    
443
        if (start.getY() > end.getY()) {
444
            angle = -angle;
445
        }
446

    
447
        if (angle < 0) {
448
            angle += (2 * Math.PI);
449
        }
450

    
451
        return angle;
452
    }
453

    
454

    
455
    /* (non-Javadoc)
456
     * @see org.gvsig.fmap.geom.Geometry#offset(double)
457
     */
458
    public Geometry offset(double distance) throws GeometryOperationNotSupportedException, GeometryOperationException {
459
        // TODO Auto-generated method stub
460
        Point center = getCenterPoint();
461
        double radius = center.distance(init);
462
        double scale = (radius+distance)/radius;
463
        AffineTransform at = getScaleAffineTransform(center, scale);
464
        Geometry cloned = this.cloneGeometry();
465
        cloned.transform(at);
466
        return cloned;
467
    }
468

    
469
    protected AffineTransform getScaleAffineTransform(Point center, Double scale)
470
        throws GeometryOperationNotSupportedException,
471
        GeometryOperationException {
472

    
473
        AffineTransform translate =
474
            AffineTransform
475
                .getTranslateInstance(-center.getX(), -center.getY());
476

    
477
        AffineTransform scaleTransform = AffineTransform.getScaleInstance(scale,scale);
478

    
479
        AffineTransform inverseTranslate =
480
            AffineTransform.getTranslateInstance(center.getX(), center.getY());
481
        AffineTransform at = new AffineTransform(translate);
482

    
483
        at.preConcatenate(scaleTransform);
484
        at.preConcatenate(inverseTranslate);
485
        return at;
486
    }
487

    
488
    @Override
489
    public boolean canBeTransformed(AffineTransform at) {
490
        return false;
491
    }
492

    
493
    @Override
494
    public boolean canBeReprojected(ICoordTrans ct) {
495
        return false;
496
    }
497

    
498
    @Override
499
    public Geometry force2D() throws GeometryOperationNotSupportedException, GeometryOperationException {
500
        Arc2D other = new Arc2D();
501
        other.setProjection(this.getProjection());
502
        Point clonedInit = (Point)init.force2D();
503
        Point clonedMiddle = (Point)middle.force2D();
504
        Point clonedEnd = (Point)end.force2D();
505
        other.setPoints(clonedInit, clonedMiddle, clonedEnd);
506
        return other;
507
    }
508

    
509
}