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

History | View | Annotate | Download (13.5 KB)

1 42267 fdiaz
/* 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 42464 fdiaz
import org.cresques.cts.CoordTransRuntimeException;
30 42267 fdiaz
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 42281 fdiaz
import org.gvsig.fmap.geom.operation.GeometryOperationException;
38
import org.gvsig.fmap.geom.operation.GeometryOperationNotSupportedException;
39 42267 fdiaz
import org.gvsig.fmap.geom.primitive.Arc;
40
import org.gvsig.fmap.geom.primitive.GeneralPathX;
41 44617 jjdelcerro
import org.gvsig.fmap.geom.primitive.OrientablePrimitive;
42 42267 fdiaz
import org.gvsig.fmap.geom.primitive.Point;
43
44
45
/**
46
 * @author fdiaz
47
 *
48
 */
49
public abstract class AbstractArc extends AbstractCurve implements Arc {
50
51
    /**
52
     *
53
     */
54
    private static final long serialVersionUID = 454301669807892457L;
55
56
    /**
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 44617 jjdelcerro
    @Override
74 42267 fdiaz
    public void setPoints(Point initialPoint, Point endPoint) {
75 42271 fdiaz
        String message = "Calling deprecated method setPoints of a arc";
76
        notifyDeprecated(message);
77
        throw new UnsupportedOperationException(message);
78 42267 fdiaz
    }
79
80 44617 jjdelcerro
    @Override
81 42267 fdiaz
    public double getCoordinateAt(int index, int dimension) {
82 42271 fdiaz
        String message = "Calling deprecated method setPoints of a arc";
83
        notifyDeprecated(message);
84
        throw new UnsupportedOperationException(message);
85 42267 fdiaz
    }
86
87 44617 jjdelcerro
    @Override
88
    public OrientablePrimitive setCoordinateAt(int index, int dimension, double value) {
89 42271 fdiaz
        String message = "Calling deprecated method setPoints of a arc";
90
        notifyDeprecated(message);
91
        throw new UnsupportedOperationException(message);
92 42267 fdiaz
    }
93
94 44617 jjdelcerro
    @Override
95
    public OrientablePrimitive addVertex(Point point) {
96 42271 fdiaz
        String message = "Calling deprecated method setPoints of a arc";
97
        notifyDeprecated(message);
98
        throw new UnsupportedOperationException(message);
99 42267 fdiaz
    }
100
101 44617 jjdelcerro
    @Override
102
    public OrientablePrimitive addVertex(double x, double y) {
103 42271 fdiaz
        String message = "Calling deprecated method setPoints of a arc";
104
        notifyDeprecated(message);
105
        throw new UnsupportedOperationException(message);
106 42267 fdiaz
    }
107
108 44617 jjdelcerro
    @Override
109
    public OrientablePrimitive addVertex(double x, double y, double z) {
110 42271 fdiaz
        String message = "Calling deprecated method setPoints of a arc";
111
        notifyDeprecated(message);
112
        throw new UnsupportedOperationException(message);
113 42267 fdiaz
    }
114
115 44617 jjdelcerro
    @Override
116 42267 fdiaz
    public void removeVertex(int index) {
117 42271 fdiaz
        String message = "Calling deprecated method setPoints of a arc";
118
        notifyDeprecated(message);
119
        throw new UnsupportedOperationException(message);
120 42267 fdiaz
    }
121
122 44617 jjdelcerro
    @Override
123 42267 fdiaz
    public Point getVertex(int index) {
124 42271 fdiaz
        String message = "Calling deprecated method setPoints of a arc";
125
        notifyDeprecated(message);
126
        throw new UnsupportedOperationException(message);
127 42267 fdiaz
    }
128
129 44617 jjdelcerro
    @Override
130 42267 fdiaz
    public int getNumVertices() {
131 42271 fdiaz
        String message = "Calling deprecated method setPoints of a arc";
132
        notifyDeprecated(message);
133
        throw new UnsupportedOperationException(message);
134 42267 fdiaz
    }
135
136 44617 jjdelcerro
    @Override
137
    public OrientablePrimitive insertVertex(int index, Point p) {
138 42271 fdiaz
        String message = "Calling deprecated method setPoints of a arc";
139
        notifyDeprecated(message);
140
        throw new UnsupportedOperationException(message);
141 42267 fdiaz
    }
142
143 44617 jjdelcerro
    @Override
144
    public OrientablePrimitive setVertex(int index, Point p) {
145 42271 fdiaz
        String message = "Calling deprecated method setPoints of a arc";
146
        notifyDeprecated(message);
147
        throw new UnsupportedOperationException(message);
148 42267 fdiaz
    }
149
150 44617 jjdelcerro
    @Override
151 42267 fdiaz
    public void setGeneralPath(GeneralPathX generalPathX) {
152 42271 fdiaz
        String message = "Calling deprecated method setPoints of a arc";
153
        notifyDeprecated(message);
154
        throw new UnsupportedOperationException(message);
155 42267 fdiaz
    }
156
157 44617 jjdelcerro
    @Override
158 42267 fdiaz
    public void addMoveToVertex(Point point) {
159 42271 fdiaz
        String message = "Calling deprecated method setPoints of a arc";
160
        notifyDeprecated(message);
161
        throw new UnsupportedOperationException(message);
162 42267 fdiaz
    }
163
164 44617 jjdelcerro
    @Override
165 42267 fdiaz
    public void closePrimitive() {
166 42271 fdiaz
        String message = "Calling deprecated method setPoints of a arc";
167
        notifyDeprecated(message);
168
        throw new UnsupportedOperationException(message);
169 42267 fdiaz
    }
170
171 44617 jjdelcerro
    @Override
172
    public OrientablePrimitive ensureCapacity(int capacity) {
173 42267 fdiaz
        // TODO Auto-generated method stub
174 44617 jjdelcerro
        return this;
175 42267 fdiaz
    }
176
177 44617 jjdelcerro
    @Override
178 42267 fdiaz
    public void reProject(ICoordTrans ct) {
179 42283 fdiaz
        //FIXME: Esto solo ser?a correcto para transformaciones de traslaci?n, rotaci?n y escala
180
        // Ser?a incorrecto para las de deformaci?n en cizallamiento
181 42267 fdiaz
182 42464 fdiaz
        try {
183 42283 fdiaz
        init.reProject(ct);
184
        middle.reProject(ct);
185
        end.reProject(ct);
186 43785 jjdelcerro
        this.setProjection(ct.getPDest());
187 42464 fdiaz
        } catch (CoordTransRuntimeException e){
188
            //Si ha fallado la reproyecci?n de alguno de los puntos, ponemos todas las coordenadas a 0
189
            init.setX(0);
190
            init.setY(0);
191
            middle.setX(0);
192
            middle.setY(0);
193
            end.setX(0);
194
            end.setY(0);
195
        }
196 42267 fdiaz
    }
197
198 44617 jjdelcerro
    @Override
199 42267 fdiaz
    public void transform(AffineTransform at) {
200 42283 fdiaz
        //FIXME: Esto solo ser?a correcto para transformaciones de traslaci?n, rotaci?n y escala
201
        // Ser?a incorrecto para las de deformaci?n en cizallamiento
202 42267 fdiaz
203 42268 fdiaz
        init.transform(at);
204
        middle.transform(at);
205
        end.transform(at);
206 42267 fdiaz
    }
207
208 44617 jjdelcerro
    @Override
209 42267 fdiaz
    public int getDimension() {
210
        return init.getDimension();
211
    }
212
213 44617 jjdelcerro
    @Override
214 42267 fdiaz
    public Shape getShape(AffineTransform affineTransform) {
215 42268 fdiaz
        return new DefaultGeneralPathX(getPathIterator(affineTransform),false,0);
216 42267 fdiaz
    }
217
218 44617 jjdelcerro
    @Override
219 42267 fdiaz
    public Shape getShape() {
220 42268 fdiaz
        return getShape(null);
221 42267 fdiaz
    }
222
223 44617 jjdelcerro
    @Override
224 42267 fdiaz
    public boolean is3D() {
225
        return ((PointJTS)init).is3D();
226
    }
227
228
    /**
229 44617 jjdelcerro
     * @param point
230 42267 fdiaz
     * @return
231
     */
232
    protected abstract Point fixPoint(Point point);
233
234 44617 jjdelcerro
    @Override
235 42267 fdiaz
    public void setPoints(Point startPoint, Point midPoint, Point endPoint) {
236
        init = fixPoint(startPoint);
237
        middle = fixPoint(midPoint);
238
        end = fixPoint(endPoint);
239
    }
240
241 44617 jjdelcerro
    @Override
242 42267 fdiaz
    public Point getInitPoint() {
243
        return init;
244
    }
245
246 44617 jjdelcerro
    @Override
247 42267 fdiaz
    public Point getEndPoint() {
248
        return end;
249
    }
250
251 44617 jjdelcerro
    @Override
252 42283 fdiaz
    public Point getMiddlePoint() {
253
        return middle;
254
    }
255
256 42267 fdiaz
    /**
257
     * Leaves the angle between PI and -PI
258
     * @param angle (radians)
259
     * @return
260
     */
261
    protected double normalizeAngle(double angle) {
262
        if (angle > -Math.PI && angle <= Math.PI) {
263
            return angle;
264
        }
265
266
        if (angle == Double.NEGATIVE_INFINITY || angle == Double.POSITIVE_INFINITY) {
267
            return 0;
268
        }
269
270
        double abs_ang = Math.abs(angle);
271
        double remove = Math.floor(abs_ang / (2 * Math.PI));
272
        remove = remove * 2 * Math.PI;
273
        double resp = 0;
274
275
        if (angle > 0) {
276
            resp = angle - remove;
277
            if (resp > Math.PI) {
278
                // final adjustment
279
                resp = resp - 2 * Math.PI;
280
            }
281
        } else {
282
            resp = angle + remove;
283
            if (resp <= -Math.PI) {
284
                // final adjustment
285
                resp = resp + 2 * Math.PI;
286
            }
287
        }
288
289
        return resp;
290
    }
291
292
293 44617 jjdelcerro
    @Override
294 42267 fdiaz
    public void setPointsStartExt(Point center, double radius, double startAngle, double angleExt) {
295
        setPoints(center, radius, startAngle, angleExt);
296
    }
297
298 44617 jjdelcerro
    @Override
299 42267 fdiaz
    public void setPointsStartEnd(Point center, double radius, double startAngle, double endAngle) {
300
301
        if (startAngle == endAngle) {
302
            setPointsStartExt(center, radius, startAngle, 0);
303
        } else {
304
305
            /*
306
             * Normalize then force clockwise:
307
             */
308
            double norm_start = normalizeAngle(startAngle);
309
            double norm_end = normalizeAngle(endAngle);
310
            double ang_ext = 0;
311
312
            // clockwise
313
            // ang_ext must be positive
314
            if (norm_start >= norm_end) {
315
                ang_ext = norm_start - norm_end;
316
            } else {
317
                ang_ext = 2 * Math.PI - (norm_end - norm_start);
318
            }
319 42283 fdiaz
            setPointsStartExt(center, radius, startAngle, ang_ext);
320 42267 fdiaz
321
            // finally call other method with ang_ext
322
        }
323
    }
324
325 44617 jjdelcerro
    @Override
326 42267 fdiaz
    public GeneralPathX getGeneralPath() {
327
328
       GeneralPathX gp = new DefaultGeneralPathX(getPathIterator(null, getManager().getFlatness()), is3D(), 0.0);
329
        return gp;
330
    }
331
332
333 44617 jjdelcerro
    @Override
334 42267 fdiaz
    public PathIterator getPathIterator(AffineTransform at) {
335
        return getPathIterator(at, getManager().getFlatness());
336
    }
337
338
339 44617 jjdelcerro
    @Override
340 42267 fdiaz
    public PathIterator getPathIterator(AffineTransform at, double flatness) {
341
342
        java.awt.geom.Point2D.Double p1 = new java.awt.geom.Point2D.Double(init.getX(), init.getY());
343
        java.awt.geom.Point2D.Double p2 = new java.awt.geom.Point2D.Double(middle.getX(), middle.getY());
344
        java.awt.geom.Point2D.Double p3 = new java.awt.geom.Point2D.Double(end.getX(), end.getY());
345
346
        java.awt.geom.Arc2D arco = UtilFunctions.createArc(p1, p2, p3);
347
        if (arco == null) {
348
            logger.info("Did not set arc points (probably aligned points): " + p1.getX() + " " + p1.getY() + " :: "
349
                + p2.getX() + " " + p2.getY() + " :: " + p3.getX() + " " + p3.getY());
350
            throw new IllegalArgumentException("Did not set arc points (probably aligned points).");
351
        }
352
353
        return arco.getPathIterator(at, flatness);
354
    }
355 42281 fdiaz
356 44617 jjdelcerro
    @Override
357 42281 fdiaz
    public void flip() throws GeometryOperationNotSupportedException, GeometryOperationException {
358
        Point aux = init;
359
        init = end;
360
        end = aux;
361
    }
362 42356 fdiaz
363
364 44617 jjdelcerro
    @Override
365 42356 fdiaz
    public double getStartAngle() throws GeometryOperationNotSupportedException, GeometryOperationException {
366
        return getAngle(getCenterPoint(), getInitPoint());
367
    }
368
369 44617 jjdelcerro
    @Override
370 42356 fdiaz
    public double getEndAngle() throws GeometryOperationNotSupportedException, GeometryOperationException {
371
        return getAngle(getCenterPoint(), getEndPoint());
372
    }
373
374
    private double getAngle(Point start, Point end) throws GeometryOperationNotSupportedException, GeometryOperationException {
375
        double angle = Math.acos((end.getX() - start.getX()) / start.distance(end));
376
377
        if (start.getY() > end.getY()) {
378
            angle = -angle;
379
        }
380
381
        if (angle < 0) {
382
            angle += (2 * Math.PI);
383
        }
384
385
        return angle;
386
    }
387
388 42441 fdiaz
389 44617 jjdelcerro
    @Override
390 42441 fdiaz
    public Geometry offset(double distance) throws GeometryOperationNotSupportedException, GeometryOperationException {
391
        // TODO Auto-generated method stub
392
        Point center = getCenterPoint();
393
        double radius = center.distance(init);
394
        double scale = (radius+distance)/radius;
395
        AffineTransform at = getScaleAffineTransform(center, scale);
396
        Geometry cloned = this.cloneGeometry();
397
        cloned.transform(at);
398
        return cloned;
399
    }
400
401
    protected AffineTransform getScaleAffineTransform(Point center, Double scale)
402
        throws GeometryOperationNotSupportedException,
403
        GeometryOperationException {
404
405
        AffineTransform translate =
406
            AffineTransform
407
                .getTranslateInstance(-center.getX(), -center.getY());
408
409
        AffineTransform scaleTransform = AffineTransform.getScaleInstance(scale,scale);
410
411
        AffineTransform inverseTranslate =
412
            AffineTransform.getTranslateInstance(center.getX(), center.getY());
413
        AffineTransform at = new AffineTransform(translate);
414
415
        at.preConcatenate(scaleTransform);
416
        at.preConcatenate(inverseTranslate);
417
        return at;
418
    }
419 43002 fdiaz
420
    @Override
421
    public boolean canBeTransformed(AffineTransform at) {
422
        return false;
423
    }
424
425
    @Override
426
    public boolean canBeReprojected(ICoordTrans ct) {
427
        return false;
428
    }
429 44612 jjdelcerro
430
    @Override
431
    public Geometry force2D() throws GeometryOperationNotSupportedException, GeometryOperationException {
432
        Arc2D other = new Arc2D();
433
        other.setProjection(this.getProjection());
434
        Point clonedInit = (Point)init.force2D();
435
        Point clonedMiddle = (Point)middle.force2D();
436
        Point clonedEnd = (Point)end.force2D();
437
        other.setPoints(clonedInit, clonedMiddle, clonedEnd);
438
        return other;
439
    }
440
441 42267 fdiaz
}