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
/**
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.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

    
43
/**
44
 *
45
 * Line2DOffset.java
46
 *
47
 *
48
 * @author jaume dominguez faus - jaume.dominguez@iver.es Jan 3, 2008
49
 *
50
 */
51

    
52
public class Line2DOffset_DEPRECATED {
53

    
54
    final static private Logger logger = LoggerFactory.getLogger(Line2DOffset_DEPRECATED.class);
55

    
56
    public static GeneralPathX offsetLine(Shape p, double offset) {
57

    
58
        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
                                                 * Entonces, consumimos los segmentos que llevamos
81
                                                 * y empezamos un nuevo pol?gono o una nueva linea.
82
                             */
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

    
101
                    case PathIterator.SEG_LINETO:
102

    
103
                        // 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

    
126
                        break;
127

    
128
                } // end switch
129

    
130
                pi.next();
131
            }
132
            offsetSegments.append(offsetAndConsumeSegments(offset, segments)
133
                    .getPathIterator(null), false);
134

    
135
            return offsetSegments;
136
        } catch (ParallelLinesCannotBeResolvedException e) {
137
            logger.error(e.getMessage(), e);
138
            return new GeneralPathX(p.getPathIterator(null));
139
        }
140
    }
141

    
142
    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

    
157
            double xOffset = offset * Math.sin(theta);
158
            double yOffset = offset * Math.cos(theta);
159

    
160
            Coordinate p0 = segment.p0;
161
            double x0 = p0.x + xOffset;
162
            double y0 = p0.y - yOffset;
163

    
164
            Coordinate p1 = segment.p1;
165
            double x1 = p1.x + xOffset;
166
            double y1 = p1.y - yOffset;
167

    
168
            LineEquation offsetLine = new LineEquation(theta, x0, y0, x1, y1);
169
            offsetLines.put(segment, offsetLine);
170
        }
171

    
172
        /*
173
                 * 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
         */
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

    
189
            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

    
211
            gpx.append(new Line2D.Double(pIni, pEnd).getPathIterator(null), true);
212
            segments.remove(0);
213
        }
214
        return gpx;
215
    }
216

    
217
    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

    
232
                double xOffset = offset * Math.sin(theta);
233
                double yOffset = offset * Math.cos(theta);
234

    
235
                Coordinate p0 = segment.p0;
236
                double x0 = p0.x + xOffset;
237
                double y0 = p0.y - yOffset;
238

    
239
                Coordinate p1 = segment.p1;
240
                double x1 = p1.x + xOffset;
241
                double y1 = p1.y - yOffset;
242

    
243
                LineEquation offsetLine = new LineEquation(theta, x0, y0, x1, y1);
244
                offsetLines.put(segment, offsetLine);
245
            }
246

    
247
            /*
248
                         * 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
             */
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

    
272
                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

    
291
                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

    
298
    }
299

    
300
    //        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

    
313

    
314
private static class LineEquation {
315

    
316
    double theta, m, x, y;
317

    
318
    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
                 * line1 (this): y - y0 = m*(x - x0)
335
                 * line2 (otherLine): y' - y'0 = m'*(x' - x'0)
336
         */
337

    
338
        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

    
360
        } 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

    
408
        //                System.out.println("DEVOLVEMOS X = "+X+" Y = "+Y);
409
        return new Point2D.Double(X, Y);
410

    
411
    }
412

    
413
    public String toString() {
414
        return "Y - " + y + " = " + m + "*(X - " + x + ")";
415
    }
416
}
417

    
418
private static class NotEnoughSegmentsToClosePathException extends Exception {
419

    
420
    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
}
427

    
428
private static class ParallelLinesCannotBeResolvedException extends Exception {
429

    
430
    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
}
438
}
439
//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
//}