Statistics
| Revision:

svn-gvsig-desktop / trunk / org.gvsig.desktop / org.gvsig.desktop.library / org.gvsig.symbology / org.gvsig.symbology.lib / org.gvsig.symbology.lib.impl / src / main / java / org / gvsig / symbology / fmap / mapcontext / rendering / symbol / style / Line2DOffset_DEPRECATED.java @ 44984

History | View | Annotate | Download (24.3 KB)

1 40560 jjdelcerro
/**
2
 * gvSIG. Desktop Geographic Information System.
3 40435 jjdelcerro
 *
4 40560 jjdelcerro
 * Copyright (C) 2007-2013 gvSIG Association.
5 40435 jjdelcerro
 *
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 40560 jjdelcerro
 * as published by the Free Software Foundation; either version 3
9 40435 jjdelcerro
 * 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 40560 jjdelcerro
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19
 * MA  02110-1301, USA.
20 40435 jjdelcerro
 *
21 40560 jjdelcerro
 * For any additional information, do not hesitate to contact us
22
 * at info AT gvsig.com, or visit our website www.gvsig.com.
23 40435 jjdelcerro
 */
24
package org.gvsig.symbology.fmap.mapcontext.rendering.symbol.style;
25
26
import java.awt.Shape;
27
import java.awt.geom.Line2D;
28
import java.awt.geom.PathIterator;
29
import java.awt.geom.Point2D;
30
import java.util.ArrayList;
31
import java.util.HashMap;
32
import java.util.List;
33
import java.util.Map;
34
35
import org.gvsig.fmap.geom.Geometry;
36
import org.gvsig.fmap.geom.primitive.GeneralPathX;
37
import org.slf4j.Logger;
38
import org.slf4j.LoggerFactory;
39
40
import com.vividsolutions.jts.geom.Coordinate;
41
import com.vividsolutions.jts.geom.LineSegment;
42 44984 fdiaz
43 40435 jjdelcerro
/**
44
 *
45
 * Line2DOffset.java
46
 *
47
 *
48
 * @author jaume dominguez faus - jaume.dominguez@iver.es Jan 3, 2008
49
 *
50
 */
51
52 44984 fdiaz
public class Line2DOffset_DEPRECATED {
53 40435 jjdelcerro
54 44984 fdiaz
    final static private Logger logger = LoggerFactory.getLogger(Line2DOffset_DEPRECATED.class);
55 40435 jjdelcerro
56 44984 fdiaz
    public static GeneralPathX offsetLine(Shape p, double offset) {
57 40435 jjdelcerro
58 44984 fdiaz
        if (Math.abs(offset) < 1) {
59
            return new GeneralPathX(p.getPathIterator(null));
60
        }
61
        PathIterator pi = p.getPathIterator(null);
62
        double[] dataCoords = new double[6];
63
        Coordinate from = null, first = null;
64
        List<LineSegment> segments = new ArrayList<LineSegment>();
65
        GeneralPathX offsetSegments = new GeneralPathX();
66
        LineSegment line;
67
        try {
68
            while (!pi.isDone()) {
69
                // while not done
70
                int type = pi.currentSegment(dataCoords);
71
72
                switch (type) {
73
                    case PathIterator.SEG_MOVETO:
74
                        if (from == null) {
75
                            from = new Coordinate(dataCoords[0], dataCoords[1]);
76
                            first = from;
77
                            break;
78
                        } else {
79
                            /* Puede significar un agujero en un pol?gono o un salto en una linea.
80 40435 jjdelcerro
                                                 * Entonces, consumimos los segmentos que llevamos
81
                                                 * y empezamos un nuevo pol?gono o una nueva linea.
82 44984 fdiaz
                             */
83
                            try {
84
                                if (((Geometry) p).getType() == Geometry.TYPES.SURFACE) {
85
                                    offsetSegments.append(offsetAndConsumeClosedSegments(offset, segments).getPathIterator(null),
86
                                            false);
87
                                } else {
88
                                    offsetSegments.append(offsetAndConsumeSegments(offset, segments).getPathIterator(null),
89
                                            false);
90
                                }
91
                            } catch (NotEnoughSegmentsToClosePathException e) {
92
                                logger.error(
93
                                        e.getMessage(), e);
94
                            }
95
                            segments.clear();
96
                            from = new Coordinate(dataCoords[0], dataCoords[1]);
97
                            first = from;
98
                            break;
99
                        }
100 40435 jjdelcerro
101 44984 fdiaz
                    case PathIterator.SEG_LINETO:
102 40435 jjdelcerro
103 44984 fdiaz
                        // System.out.println("SEG_LINETO");
104
                        Coordinate to = new Coordinate(dataCoords[0], dataCoords[1]);
105
                        if (from.compareTo(to) != 0) {
106
                            line = new LineSegment(from, to);
107
                            segments.add(line);
108
                            from = to;
109
                        }
110
                        break;
111
                    case PathIterator.SEG_CLOSE:
112
                        line = new LineSegment(from, first);
113
                        segments.add(line);
114
                        //                                        from = first;
115
                        try {
116
                            offsetSegments.append(offsetAndConsumeClosedSegments(
117
                                    offset, segments).getPathIterator(null), false);
118
                        } catch (NotEnoughSegmentsToClosePathException e) {
119
                            logger.error(
120
                                    e.getMessage(), e);
121
                        }
122
                        segments.clear();
123
                        first = null;
124
                        from = null;
125 40435 jjdelcerro
126 44984 fdiaz
                        break;
127 40435 jjdelcerro
128 44984 fdiaz
                } // end switch
129 40435 jjdelcerro
130 44984 fdiaz
                pi.next();
131
            }
132
            offsetSegments.append(offsetAndConsumeSegments(offset, segments)
133
                    .getPathIterator(null), false);
134 40435 jjdelcerro
135 44984 fdiaz
            return offsetSegments;
136
        } catch (ParallelLinesCannotBeResolvedException e) {
137
            logger.error(e.getMessage(), e);
138
            return new GeneralPathX(p.getPathIterator(null));
139
        }
140
    }
141 40435 jjdelcerro
142 44984 fdiaz
    private static GeneralPathX offsetAndConsumeSegments(double offset,
143
            List<LineSegment> segments)
144
            throws ParallelLinesCannotBeResolvedException {
145
        Map<LineSegment, LineEquation> offsetLines
146
                = new HashMap<LineSegment, LineEquation>();
147
        int segmentCount = segments.size();
148
        // first calculate offset lines with the starting point
149
        for (int i = 0; i < segmentCount; i++) {
150
            LineSegment segment = (LineSegment) segments.get(i);
151
            double theta = segment.angle();
152
            //FIXME: ?Esto para qu? es?
153
            //                        if (Math.abs(theta) % (Math.PI*0.5) < 0.00001){
154
            //                                theta=theta+0.00000000000001;
155
            //                        }
156 40435 jjdelcerro
157 44984 fdiaz
            double xOffset = offset * Math.sin(theta);
158
            double yOffset = offset * Math.cos(theta);
159 40435 jjdelcerro
160 44984 fdiaz
            Coordinate p0 = segment.p0;
161
            double x0 = p0.x + xOffset;
162
            double y0 = p0.y - yOffset;
163 40435 jjdelcerro
164 44984 fdiaz
            Coordinate p1 = segment.p1;
165
            double x1 = p1.x + xOffset;
166
            double y1 = p1.y - yOffset;
167 40435 jjdelcerro
168 44984 fdiaz
            LineEquation offsetLine = new LineEquation(theta, x0, y0, x1, y1);
169
            offsetLines.put(segment, offsetLine);
170
        }
171 40435 jjdelcerro
172 44984 fdiaz
        /*
173 40435 jjdelcerro
                 * let's now calculate the end point of each segment with the point
174
                 * where each line crosses the next one. this point will be the end
175
                 * point of the first line, and the start point of its next one.
176 44984 fdiaz
         */
177
        Point2D pIni = null;
178
        Point2D pEnd = null;
179
        GeneralPathX gpx = new GeneralPathX();
180
        for (int i = 0; i < segmentCount; i++) {
181
            LineSegment segment = (LineSegment) segments.get(0);
182
            LineEquation eq = (LineEquation) offsetLines.get(segment);
183
            if (i == 0) {
184
                pIni = new Point2D.Double(eq.x, eq.y);
185
            } else {
186
                pIni = pEnd;
187
            }
188 40435 jjdelcerro
189 44984 fdiaz
            if (i < segmentCount - 1) {
190
                LineEquation eq1 = (LineEquation) offsetLines.get(segments.get(1));
191
                try {
192
                    pEnd = eq.resolve(eq1);
193
                } catch (ParallelLinesCannotBeResolvedException e) { //Las lineas son paralelas y NO son la misma.
194
                    pEnd = new Point2D.Double(eq.xEnd, eq.yEnd);
195
                    gpx.append(new Line2D.Double(pIni, pEnd)
196
                            .getPathIterator(null), true); // a?adimos una linea
197
                    // hasta el final
198
                    // del primer
199
                    // segmento
200
                    //                                         y asignamos como punto final el principio del siguiente segmento
201
                    //                                         para que en la siguiente iteraci?n lo tome como punto inicial.
202
                    pIni = pEnd;
203
                    pEnd = new Point2D.Double(eq1.x, eq1.y);
204
                    segments.remove(0);
205
                    continue;
206
                }
207
            } else {
208
                pEnd = new Point2D.Double(eq.xEnd, eq.yEnd);
209
            }
210 40435 jjdelcerro
211 44984 fdiaz
            gpx.append(new Line2D.Double(pIni, pEnd).getPathIterator(null), true);
212
            segments.remove(0);
213
        }
214
        return gpx;
215
    }
216 40435 jjdelcerro
217 44984 fdiaz
    private static GeneralPathX offsetAndConsumeClosedSegments(double offset,
218
            List<LineSegment> segments)
219
            throws ParallelLinesCannotBeResolvedException, NotEnoughSegmentsToClosePathException {
220
        int segmentCount = segments.size();
221
        if (segmentCount > 1) {
222
            Map<LineSegment, LineEquation> offsetLines = new HashMap<LineSegment, LineEquation>();
223
            // first calculate offset lines with the starting point
224
            for (int i = 0; i < segmentCount; i++) {
225
                LineSegment segment = (LineSegment) segments.get(i);
226
                double theta = segment.angle();
227
                //FIXME: ?Esto para qu? es?
228
                //                        if (Math.abs(theta) % (Math.PI*0.5) < 0.00001){
229
                //                                theta=theta+0.00000000000001;
230
                //                        }
231 40435 jjdelcerro
232 44984 fdiaz
                double xOffset = offset * Math.sin(theta);
233
                double yOffset = offset * Math.cos(theta);
234 40435 jjdelcerro
235 44984 fdiaz
                Coordinate p0 = segment.p0;
236
                double x0 = p0.x + xOffset;
237
                double y0 = p0.y - yOffset;
238 40435 jjdelcerro
239 44984 fdiaz
                Coordinate p1 = segment.p1;
240
                double x1 = p1.x + xOffset;
241
                double y1 = p1.y - yOffset;
242 40435 jjdelcerro
243 44984 fdiaz
                LineEquation offsetLine = new LineEquation(theta, x0, y0, x1, y1);
244
                offsetLines.put(segment, offsetLine);
245
            }
246 40435 jjdelcerro
247 44984 fdiaz
            /*
248 40435 jjdelcerro
                         * let's now calculate the end point of each segment with the point
249
                         * where each line crosses the next one. this point will be the end
250
                         * point of the first line, and the start point of its next one.
251 44984 fdiaz
             */
252
            Point2D pIni = null;
253
            Point2D pEnd = null;
254
            Point2D firstP = null;
255
            GeneralPathX gpx = new GeneralPathX();
256
            for (int i = 0; i < segmentCount; i++) {
257
                LineSegment segment = (LineSegment) segments.get(0);
258
                LineEquation eq = offsetLines.get(segment);
259
                if (i == 0) { //Calculo de la intersecci?n entre el primer segmento y el ?ltimo
260
                    LineEquation eq0 = offsetLines.get((LineSegment) segments.get(segmentCount - 1));
261
                    try {
262
                        pIni = eq0.resolve(eq);
263
                    } catch (ParallelLinesCannotBeResolvedException e) { //Las lineas son paralelas y NO son la misma.
264
                        //                                                pIni = new Point2D.Double(eq0.xEnd, eq0.yEnd);
265
                        pIni = new Point2D.Double(eq.x, eq.y);
266
                    }
267
                    firstP = pIni;
268
                } else {
269
                    pIni = pEnd;
270
                }
271 40435 jjdelcerro
272 44984 fdiaz
                if (i < segmentCount - 1) {
273
                    LineEquation eq1 = offsetLines.get((LineSegment) segments.get(1));
274
                    try {
275
                        pEnd = eq.resolve(eq1);
276
                    } catch (ParallelLinesCannotBeResolvedException e) { //Las lineas son paralelas y NO son la misma.
277
                        pEnd = new Point2D.Double(eq.xEnd, eq.yEnd);
278
                        gpx.append(new Line2D.Double(pIni, pEnd).getPathIterator(null), true); // a?adimos una linea hasta el final del primer segmento
279
                        //                                         y asignamos como punto final el principio del siguiente segmento
280
                        //                                         para que en la siguiente iteraci?n lo tome como punto inicial.
281
                        pIni = pEnd;
282
                        pEnd = new Point2D.Double(eq1.x, eq1.y);
283
                        segments.remove(0);
284
                        continue;
285
                    }
286
                } else {
287
                    //                                        pEnd = new Point2D.Double(eq.xEnd, eq.yEnd);
288
                    pEnd = new Point2D.Double(firstP.getX(), firstP.getY());
289
                }
290 40435 jjdelcerro
291 44984 fdiaz
                gpx.append(new Line2D.Double(pIni, pEnd).getPathIterator(null), true);
292
                segments.remove(0);
293
            }
294
            return gpx;
295
        }
296
        throw new NotEnoughSegmentsToClosePathException(segments);
297 40435 jjdelcerro
298 44984 fdiaz
    }
299 40435 jjdelcerro
300 44984 fdiaz
    //        private static GeneralPathX offsetAndConsumeClosedSegments(double offset,
301
    //                        List<LineSegment> segments)
302
    //        throws ParallelLinesCannotBeResolvedException,
303
    //        NotEnoughSegmentsToClosePathException {
304
    //                int segmentCount = segments.size();
305
    //                if (segmentCount > 1) {
306
    //                        GeneralPathX openPath = offsetAndConsumeSegments(offset, segments);
307
    //                        openPath.closePath();
308
    //                        return openPath;
309
    //                }
310
    //                throw new NotEnoughSegmentsToClosePathException(segments);
311
    //        }
312 40435 jjdelcerro
313
314 44984 fdiaz
private static class LineEquation {
315 40435 jjdelcerro
316 44984 fdiaz
    double theta, m, x, y;
317 40435 jjdelcerro
318 44984 fdiaz
    double xEnd, yEnd; // just for simplicity of code
319
320
    public LineEquation(double theta, double x, double y, double xEnd,
321
            double yEnd) {
322
        //                this.theta = Math.tan(theta); //Esto es un error, no podemos confundir el angulo de la recta con su pendiente
323
        this.theta = theta;
324
        this.m = Math.tan(theta);
325
        this.x = x;
326
        this.y = y;
327
        this.xEnd = xEnd;
328
        this.yEnd = yEnd;
329
    }
330
331
    public Point2D resolve(LineEquation otherLine)
332
            throws ParallelLinesCannotBeResolvedException {
333
        /*
334 40435 jjdelcerro
                 * line1 (this): y - y0 = m*(x - x0)
335
                 * line2 (otherLine): y' - y'0 = m'*(x' - x'0)
336 44984 fdiaz
         */
337 40435 jjdelcerro
338 44984 fdiaz
        double X;
339
        double Y;
340
        if (Math.abs(this.x - this.xEnd) < 0.00001) { //Esta linea es vertical
341
            //                        System.out.println("1 VERTICAL");
342
            X = this.xEnd;
343
            if (Math.abs(otherLine.x - otherLine.xEnd) < 0.00001) {//La otra linea es vertical
344
                //                                System.out.println("    2 PERPENDICULAR");
345
                if (Math.abs(this.x - otherLine.x) < 0.00001) { //Son la misma linea, devolvemos el primer punto de la otra linea.
346
                    //                                        System.out.println("        MISMA LINEA");
347
                    Y = otherLine.y;
348
                } else { //No son la misma linea, entonces son paralelas, excepcion.
349
                    //                                        System.out.println("        CASCO POR 1");
350
                    throw new ParallelLinesCannotBeResolvedException(this, otherLine);
351
                }
352
            } else if (Math.abs(otherLine.y - otherLine.yEnd) < 0.00001) { //La otra linea es horizontal
353
                //                                System.out.println("    2 HORIZONTAL");
354
                Y = otherLine.y;
355
            } else { //Si no
356
                //                                System.out.println("    2 CUALQUIERA");
357
                Y = otherLine.m * (X - otherLine.x) + otherLine.y;
358
            }
359 40435 jjdelcerro
360 44984 fdiaz
        } else if (Math.abs(this.y - this.yEnd) < 0.00001) { //Esta linea es horizontal
361
            //                        System.out.println("1 HORIZONTAL");
362
            Y = this.yEnd;
363
            if (Math.abs(otherLine.y - otherLine.yEnd) < 0.00001) { //La otra linea es horizontal
364
                //                                System.out.println("    2 HORIZONTAL");
365
                if (Math.abs(this.y - otherLine.y) < 0.00001) { //Son la misma linea, devolvemos el primer punto de la otra linea.
366
                    //                                        System.out.println("        MISMA LINEA");
367
                    X = otherLine.x;
368
                } else { //No son la misma linea, entonces son paralelas, excepcion.
369
                    //                                        System.out.println("        CASCO POR 2");
370
                    throw new ParallelLinesCannotBeResolvedException(this, otherLine);
371
                }
372
            } else if (Math.abs(otherLine.x - otherLine.xEnd) < 0.00001) {//La otra linea es vertical
373
                //                                System.out.println("    2 VERTICAL");
374
                X = otherLine.x;
375
            } else { //Si no
376
                //                                System.out.println("    2 CUALQUIERA");
377
                X = (Y - otherLine.y) / otherLine.m + otherLine.x;
378
            }
379
        } else { //Esta linea no es ni vertical ni horizontal
380
            //                        System.out.println("1 CUALQUIERA");
381
            if (Math.abs(otherLine.y - otherLine.yEnd) < 0.00001) { //La otra linea es horizontal
382
                //                                System.out.println("    2 HORIZONTAL");
383
                Y = otherLine.y;
384
                X = (Y - this.y) / this.m + this.x;
385
            } else if (Math.abs(otherLine.x - otherLine.xEnd) < 0.00001) {//La otra linea es vertical
386
                //                                System.out.println("    2 VERTICAL");
387
                X = otherLine.x;
388
                Y = this.m * (X - this.x) + this.y;
389
            } else if ((Math.abs(otherLine.m - this.m) < 0.00001)) { //Tienen la misma pendiente
390
                //                                System.out.println("    MISMA PENDIENTE");
391
                Y = otherLine.m * (this.x - otherLine.x) + otherLine.y;
392
                if (Math.abs(this.y - Y) < 0.00001) { //Las lineas son la misma
393
                    //                                        System.out.println("        MISMA LINEA");
394
                    X = otherLine.x;
395
                    Y = otherLine.y;
396
                } else {
397
                    //                                        System.out.println("        CASCO POR 3");
398
                    throw new ParallelLinesCannotBeResolvedException(this, otherLine);
399
                }
400
            } else {
401
                //                                System.out.println("    AMBAS CUALESQUIERA");
402
                double mTimesX = this.m * this.x;
403
                X = (mTimesX - this.y - otherLine.m * otherLine.x + otherLine.y) / (this.m - otherLine.m);
404
                Y = this.m * X - mTimesX + this.y;
405
            }
406
        }
407 40435 jjdelcerro
408 44984 fdiaz
        //                System.out.println("DEVOLVEMOS X = "+X+" Y = "+Y);
409
        return new Point2D.Double(X, Y);
410 40435 jjdelcerro
411 44984 fdiaz
    }
412 40435 jjdelcerro
413 44984 fdiaz
    public String toString() {
414
        return "Y - " + y + " = " + m + "*(X - " + x + ")";
415
    }
416 40435 jjdelcerro
}
417
418 44984 fdiaz
private static class NotEnoughSegmentsToClosePathException extends Exception {
419 40435 jjdelcerro
420 44984 fdiaz
    private static final long serialVersionUID = 95503944546535L;
421
422
    public NotEnoughSegmentsToClosePathException(List<LineSegment> segments) {
423
        super("Need at least 2 segments to close a path. I've got "
424
                + segments.size() + ".");
425
    }
426 40435 jjdelcerro
}
427
428 44984 fdiaz
private static class ParallelLinesCannotBeResolvedException extends Exception {
429 40435 jjdelcerro
430 44984 fdiaz
    private static final long serialVersionUID = 8322556508820067641L;
431
432
    public ParallelLinesCannotBeResolvedException(LineEquation eq1,
433
            LineEquation eq2) {
434
        super("Lines '" + eq1 + "' and '" + eq2
435
                + "' are parallel and don't share any point!");
436
    }
437 40435 jjdelcerro
}
438 44984 fdiaz
}
439 40435 jjdelcerro
//public class Line2DOffset {
440
441
//private static final double TOL = 1E-8;
442
//private static final double ANGLE_TOL = 0.01/180*Math.PI;
443
//public static GeneralPathX offsetLine(Shape p, double offset) {
444
//PathIterator pi = p.getPathIterator(null);
445
//double[] dataCoords = new double[6];
446
//Coordinate from = null, first = null;
447
//ArrayList<LineSegment> segments = new ArrayList<LineSegment>();
448
//GeneralPathX offsetSegments = new GeneralPathX();
449
//try {
450
//while (!pi.isDone()) {
451
//// while not done
452
//int type = pi.currentSegment(dataCoords);
453
//switch (type) {
454
//case PathIterator.SEG_MOVETO:
455
//from = new Coordinate(dataCoords[0], dataCoords[1]);
456
//first = from;
457
//break;
458
//case PathIterator.SEG_LINETO:
459
//// System.out.println("SEG_LINETO");
460
//Coordinate to = new Coordinate(dataCoords[0], dataCoords[1]);
461
//LineSegment line = new LineSegment(from, to);
462
//int size = segments.size();
463
//if (size>0) {
464
//LineSegment prev = segments.get(size-1);
465
//if (line.angle() == prev.angle()) {
466
//if (Math.abs(line.p0.x - prev.p1.x) < TOL &&
467
//Math.abs(line.p0.y - prev.p1.y) < TOL) {
468
//prev.p1 = line.p1;
469
//break;
470
//}
471
//}
472
//}
473
//from = to;
474
//segments.add(line);
475
//break;
476
//case PathIterator.SEG_CLOSE:
477
//line = new LineSegment(from, first);
478
//segments.add(line);
479
//from = first;
480
//try {
481
//offsetSegments.append(offsetAndConsumeClosedSegments(offset, segments), false);
482
//} catch (NotEnoughSegmentsToClosePathException e) {
483
//Logger.getLogger(Line2DOffset.class).error(e.getMessage(), e);
484
//}
485
//break;
486
//} // end switch
487
//pi.next();
488
//}
489
//offsetSegments.append(offsetAndConsumeSegments(offset, segments), true);
490
//return offsetSegments;
491
//} catch (ParallelLinesCannotBeResolvedException e) {
492
//Logger.getLogger(Line2DOffset.class).error(e.getMessage(), e);
493
//return new GeneralPathX(p);
494
//}
495
//}
496
//private static GeneralPathX offsetAndConsumeSegments(double offset, ArrayList<LineSegment> segments)  {
497
//Hashtable<LineSegment, LineEquation> offsetLines = new Hashtable<LineSegment, LineEquation>();
498
//int segmentCount = segments.size();
499
//// first calculate offset lines with the starting point
500
//for (int i = 0; i < segmentCount; i++) {
501
//LineSegment segment = segments.get(i);
502
//double theta = segment.angle();
503
//double xOffset = offset*Math.sin(theta);
504
//double yOffset = offset*Math.cos(theta);
505
//Coordinate p0 = segment.p0;
506
//double x0 = p0.x + xOffset;
507
//double y0 = p0.y - yOffset;
508
//Coordinate p1 = segment.p1;
509
//double x1 = p1.x + xOffset;
510
//double y1 = p1.y - yOffset;
511
//LineEquation offsetLine = new LineEquation(theta, x0, y0, x1, y1, offset);
512
//offsetLines.put(segment, offsetLine);
513
//}
514
///*
515
//* let's now calculate the end point of each segment with
516
//* the point where each line crosses the next one.
517
//* this point will be the end point of the first line, and
518
//* the start point of its next one.
519
//*/
520
//Point2D pIni = null;
521
//Point2D pEnd = null;
522
//GeneralPathX gpx = new GeneralPathX();
523
//for (int i = 0; i < segmentCount; i++) {
524
//LineSegment segment = segments.get(0);
525
//LineEquation eq = offsetLines.get(segment);
526
//Point2D pAux = null;
527
//if (i < segmentCount -1) {
528
//try {
529
//pAux = eq.resolve(offsetLines.get(segments.get(1)));
530
//if (i == 0) {
531
//pIni = new Point2D.Double(eq.x, eq.y);
532
//} else {
533
//pIni = pEnd;
534
//}
535
//} catch (ParallelLinesCannotBeResolvedException e) {
536
//segments.remove(0);
537
//continue;
538
//}
539
//}
540
//if (pAux != null) {
541
//pEnd = pAux;
542
//} else {
543
//pEnd = new Point2D.Double(eq.xEnd, eq.yEnd);
544
//}
545
//gpx.append(new Line2D.Double(pIni, pEnd), true);
546
//segments.remove(0);
547
//}
548
//return gpx;
549
//}
550
//private static GeneralPathX offsetAndConsumeClosedSegments(double offset, ArrayList<LineSegment> segments) throws ParallelLinesCannotBeResolvedException, NotEnoughSegmentsToClosePathException {
551
//int segmentCount = segments.size();
552
//if (segmentCount > 1) {
553
//GeneralPathX openPath = offsetAndConsumeSegments(offset, segments);
554
//openPath.closePath();
555
//return openPath;
556
//}
557
//throw new NotEnoughSegmentsToClosePathException(segments);
558
//}
559
//}
560
//class LineEquation {
561
//double theta, x, y;
562
//double xEnd, yEnd; // just for simplicity of code
563
//double offset;
564
//public LineEquation(double theta, double x, double y, double xEnd, double yEnd, double offset) {
565
//this.theta = theta;
566
//this.x = x;
567
//this.y = y;
568
//this.xEnd = xEnd;
569
//this.yEnd = yEnd;
570
//this.offset = offset;
571
//}
572
//public Point2D resolve(LineEquation otherLine) throws ParallelLinesCannotBeResolvedException {
573
//double X;
574
//double Y;
575
///*
576
//* line1 (this):      y  -  y0 =  m*(x  - x0)
577
//* line2 (otherLine): y' - y'0 = m'*(x' - x'0)
578
//*/
579
//if (otherLine.theta == this.theta)
580
//throw new ParallelLinesCannotBeResolvedException(this, otherLine);
581
//if (Math.cos(theta) == 0) {
582
//X = otherLine.x + offset*Math.cos(otherLine.theta);
583
//Y = otherLine.y + offset*Math.sin(otherLine.theta);
584
//} else if (Math.cos(otherLine.theta) == 0) {
585
//X = x + offset*Math.cos(theta);
586
//Y = y + offset*Math.sin(theta);
587
//} else {
588
///*
589
//* m*(X - x0) + y0 = m'*(X - x'0) + y0'
590
//* X = (m*x0 - y0 - m'*x0' + y'0) / (m - m')
591
//*/
592
//double tanTheta = Math.tan(theta);
593
//double otherTanTheta = Math.tan(otherLine.theta);
594
//double thetaTimesX = tanTheta*this.x;
595
//X = (thetaTimesX - this.y - otherTanTheta*otherLine.x + otherLine.y) / (tanTheta - otherTanTheta);
596
///*
597
//* Y - y0 = m*(X - x0)
598
//* Y = m*X - m*x0 + y0
599
//*/
600
//Y = tanTheta*X - thetaTimesX + this.y;
601
//}
602
//return new Point2D.Double(X, Y);
603
//}
604
//@Override
605
//public String toString() {
606
//return "Y - "+y+" = "+theta+"*(X - "+x+")";
607
//}
608
//}
609
//class NotEnoughSegmentsToClosePathException extends Exception {
610
//private static final long serialVersionUID = 95503944546535L;
611
//public NotEnoughSegmentsToClosePathException(ArrayList<LineSegment> segments) {
612
//super("Need at least 2 segments to close a path. I've got "+segments.size()+".");
613
//}
614
//}
615
//class ParallelLinesCannotBeResolvedException extends Exception {
616
//private static final long serialVersionUID = 8322556508820067641L;
617
//public ParallelLinesCannotBeResolvedException(LineEquation eq1, LineEquation eq2) {
618
//super("Lines '"+eq1+"' and '"+eq2+"' are parallel and don't share any point!");
619
//}
620 44984 fdiaz
//}