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 @ 42356

History | View | Annotate | Download (14.5 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.ICoordTrans;
30

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

    
42

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

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

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

    
62
    protected Point init;
63

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

    
71

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
204
    }
205

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

    
213
        init.reProject(ct);
214
        middle.reProject(ct);
215
        end.reProject(ct);
216
    }
217

    
218
    /* (non-Javadoc)
219
     * @see org.gvsig.fmap.geom.Geometry#transform(java.awt.geom.AffineTransform)
220
     */
221
    public void transform(AffineTransform at) {
222
        //FIXME: Esto solo ser?a correcto para transformaciones de traslaci?n, rotaci?n y escala
223
        // Ser?a incorrecto para las de deformaci?n en cizallamiento
224

    
225
        init.transform(at);
226
        middle.transform(at);
227
        end.transform(at);
228
    }
229

    
230
    /* (non-Javadoc)
231
     * @see org.gvsig.fmap.geom.Geometry#getDimension()
232
     */
233
    public int getDimension() {
234
        return init.getDimension();
235
    }
236

    
237
    /* (non-Javadoc)
238
     * @see org.gvsig.fmap.geom.Geometry#getShape(java.awt.geom.AffineTransform)
239
     */
240
    public Shape getShape(AffineTransform affineTransform) {
241
        return new DefaultGeneralPathX(getPathIterator(affineTransform),false,0);
242
    }
243

    
244
    /* (non-Javadoc)
245
     * @see org.gvsig.fmap.geom.Geometry#getShape()
246
     */
247
    public Shape getShape() {
248
        return getShape(null);
249
    }
250

    
251
    /* (non-Javadoc)
252
     * @see org.gvsig.fmap.geom.jts.GeometryJTS#is3D()
253
     */
254
    public boolean is3D() {
255
        return ((PointJTS)init).is3D();
256
    }
257

    
258
    /**
259
     * @param initialPoint
260
     * @return
261
     */
262
    protected abstract Point fixPoint(Point point);
263

    
264
    /* (non-Javadoc)
265
     * @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)
266
     */
267
    public void setPoints(Point startPoint, Point midPoint, Point endPoint) {
268
        init = fixPoint(startPoint);
269
        middle = fixPoint(midPoint);
270
        end = fixPoint(endPoint);
271
    }
272

    
273
    /* (non-Javadoc)
274
     * @see org.gvsig.fmap.geom.primitive.Arc#getInitPoint()
275
     */
276
    public Point getInitPoint() {
277
        return init;
278
    }
279

    
280
    /* (non-Javadoc)
281
     * @see org.gvsig.fmap.geom.primitive.Arc#getEndPoint()
282
     */
283
    public Point getEndPoint() {
284
        return end;
285
    }
286

    
287
    /* (non-Javadoc)
288
     * @see org.gvsig.fmap.geom.primitive.Arc#getMiddlePoint()
289
     */
290
    public Point getMiddlePoint() {
291
        return middle;
292
    }
293

    
294
    /**
295
     * Leaves the angle between PI and -PI
296
     * @param angle (radians)
297
     * @return
298
     */
299
    protected double normalizeAngle(double angle) {
300
        if (angle > -Math.PI && angle <= Math.PI) {
301
            return angle;
302
        }
303

    
304
        if (angle == Double.NEGATIVE_INFINITY || angle == Double.POSITIVE_INFINITY) {
305
            return 0;
306
        }
307

    
308
        double abs_ang = Math.abs(angle);
309
        double remove = Math.floor(abs_ang / (2 * Math.PI));
310
        remove = remove * 2 * Math.PI;
311
        double resp = 0;
312

    
313
        if (angle > 0) {
314
            resp = angle - remove;
315
            if (resp > Math.PI) {
316
                // final adjustment
317
                resp = resp - 2 * Math.PI;
318
            }
319
        } else {
320
            resp = angle + remove;
321
            if (resp <= -Math.PI) {
322
                // final adjustment
323
                resp = resp + 2 * Math.PI;
324
            }
325
        }
326

    
327
        return resp;
328
    }
329

    
330

    
331
    /* (non-Javadoc)
332
     * @see org.gvsig.fmap.geom.primitive.Arc#setPointsStartExt(org.gvsig.fmap.geom.primitive.Point, double, double, double)
333
     */
334
    public void setPointsStartExt(Point center, double radius, double startAngle, double angleExt) {
335
        setPoints(center, radius, startAngle, angleExt);
336
    }
337

    
338
    /* (non-Javadoc)
339
     * @see org.gvsig.fmap.geom.primitive.Arc#setPointsStartEnd(org.gvsig.fmap.geom.primitive.Point, double, double, double)
340
     */
341
    public void setPointsStartEnd(Point center, double radius, double startAngle, double endAngle) {
342

    
343
        if (startAngle == endAngle) {
344
            setPointsStartExt(center, radius, startAngle, 0);
345
        } else {
346

    
347
            /*
348
             * Normalize then force clockwise:
349
             */
350
            double norm_start = normalizeAngle(startAngle);
351
            double norm_end = normalizeAngle(endAngle);
352
            double ang_ext = 0;
353

    
354
            // clockwise
355
            // ang_ext must be positive
356
            if (norm_start >= norm_end) {
357
                ang_ext = norm_start - norm_end;
358
            } else {
359
                ang_ext = 2 * Math.PI - (norm_end - norm_start);
360
            }
361
            setPointsStartExt(center, radius, startAngle, ang_ext);
362

    
363
            // finally call other method with ang_ext
364
        }
365
    }
366

    
367
    /* (non-Javadoc)
368
     * @see org.gvsig.fmap.geom.Geometry#getGeneralPath()
369
     */
370
    public GeneralPathX getGeneralPath() {
371

    
372
       GeneralPathX gp = new DefaultGeneralPathX(getPathIterator(null, getManager().getFlatness()), is3D(), 0.0);
373
        return gp;
374
    }
375

    
376

    
377
    /* (non-Javadoc)
378
     * @see org.gvsig.fmap.geom.Geometry#getPathIterator(java.awt.geom.AffineTransform)
379
     */
380
    public PathIterator getPathIterator(AffineTransform at) {
381
        return getPathIterator(at, getManager().getFlatness());
382
    }
383

    
384

    
385
    /* (non-Javadoc)
386
     * @see org.gvsig.fmap.geom.Geometry#getPathIterator(java.awt.geom.AffineTransform, double)
387
     */
388
    public PathIterator getPathIterator(AffineTransform at, double flatness) {
389

    
390
        java.awt.geom.Point2D.Double p1 = new java.awt.geom.Point2D.Double(init.getX(), init.getY());
391
        java.awt.geom.Point2D.Double p2 = new java.awt.geom.Point2D.Double(middle.getX(), middle.getY());
392
        java.awt.geom.Point2D.Double p3 = new java.awt.geom.Point2D.Double(end.getX(), end.getY());
393

    
394
        java.awt.geom.Arc2D arco = UtilFunctions.createArc(p1, p2, p3);
395
        if (arco == null) {
396
            logger.info("Did not set arc points (probably aligned points): " + p1.getX() + " " + p1.getY() + " :: "
397
                + p2.getX() + " " + p2.getY() + " :: " + p3.getX() + " " + p3.getY());
398
            throw new IllegalArgumentException("Did not set arc points (probably aligned points).");
399
        }
400

    
401
        return arco.getPathIterator(at, flatness);
402
    }
403

    
404
    /* (non-Javadoc)
405
     * @see org.gvsig.fmap.geom.jts.GeometryJTS#flip()
406
     */
407
    public void flip() throws GeometryOperationNotSupportedException, GeometryOperationException {
408
        Point aux = init;
409
        init = end;
410
        end = aux;
411
    }
412

    
413

    
414
    /* (non-Javadoc)
415
     * @see org.gvsig.fmap.geom.primitive.Arc#getStartAngle()
416
     */
417
    public double getStartAngle() throws GeometryOperationNotSupportedException, GeometryOperationException {
418
        return getAngle(getCenterPoint(), getInitPoint());
419
    }
420

    
421
    /* (non-Javadoc)
422
     * @see org.gvsig.fmap.geom.primitive.Arc#getEndAngle()
423
     */
424
    public double getEndAngle() throws GeometryOperationNotSupportedException, GeometryOperationException {
425
        return getAngle(getCenterPoint(), getEndPoint());
426
    }
427

    
428
    private double getAngle(Point start, Point end) throws GeometryOperationNotSupportedException, GeometryOperationException {
429
        double angle = Math.acos((end.getX() - start.getX()) / start.distance(end));
430

    
431
        if (start.getY() > end.getY()) {
432
            angle = -angle;
433
        }
434

    
435
        if (angle < 0) {
436
            angle += (2 * Math.PI);
437
        }
438

    
439
        return angle;
440
    }
441

    
442
}