Statistics
| Revision:

root / trunk / libraries / libFMap / src / com / iver / cit / gvsig / fmap / core / styles / Line2DOffset.java @ 31704

History | View | Annotate | Download (19.4 KB)

1
/* gvSIG. Sistema de Informaci?n Geogr?fica de la Generalitat Valenciana
2
 *
3
 * Copyright (C) 2005 IVER T.I. and Generalitat Valenciana.
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., 59 Temple Place - Suite 330, Boston, MA  02111-1307,USA.
18
 *
19
 * For more information, contact:
20
 *
21
 *  Generalitat Valenciana
22
 *   Conselleria d'Infraestructures i Transport
23
 *   Av. Blasco Ib??ez, 50
24
 *   46010 VALENCIA
25
 *   SPAIN
26
 *
27
 *      +34 963862235
28
 *   gvsig@gva.es
29
 *      www.gvsig.gva.es
30
 *
31
 *    or
32
 *
33
 *   IVER T.I. S.A
34
 *   Salamanca 50
35
 *   46005 Valencia
36
 *   Spain
37
 *
38
 *   +34 963163400
39
 *   dac@iver.es
40
 */
41
package com.iver.cit.gvsig.fmap.core.styles;
42

    
43
import java.awt.Shape;
44
import java.awt.geom.Line2D;
45
import java.awt.geom.PathIterator;
46
import java.awt.geom.Point2D;
47
import java.util.ArrayList;
48
import java.util.Hashtable;
49

    
50
import org.apache.log4j.Logger;
51

    
52
import com.iver.cit.gvsig.fmap.core.FPolygon2D;
53
import com.iver.cit.gvsig.fmap.core.GeneralPathX;
54
import com.vividsolutions.jts.geom.Coordinate;
55
import com.vividsolutions.jts.geom.LineSegment;
56
/**
57
 *
58
 * Line2DOffset.java
59
 *
60
 *
61
 * @author jaume dominguez faus - jaume.dominguez@iver.es Jan 3, 2008
62
 *
63
 */
64

    
65
public class Line2DOffset {
66

    
67
        public static GeneralPathX offsetLine(Shape p, double offset) {
68

    
69
                if (Math.abs(offset) < 1) {
70
                        return new GeneralPathX(p);
71
                }
72
                PathIterator pi = p.getPathIterator(null);
73
                double[] dataCoords = new double[6];
74
                Coordinate from = null, first = null;
75
                ArrayList<LineSegment> segments = new ArrayList<LineSegment>();
76
                GeneralPathX offsetSegments = new GeneralPathX();
77
                LineSegment line;
78
                try {
79
                        while (!pi.isDone()) {
80
                                // while not done
81
                                int type = pi.currentSegment(dataCoords);
82

    
83
                                switch (type) {
84
                                case PathIterator.SEG_MOVETO:
85
                                        if(from == null){
86
                                                from = new Coordinate(dataCoords[0], dataCoords[1]);
87
                                                first = from;
88
                                                break;
89
                                        } else {
90
                                                /* Puede significar un agujero en un pol?gono o un salto en una linea.
91
                                                 * Entonces, consumimos los segmentos que llevamos
92
                                                 * y empezamos un nuevo pol?gono o una nueva linea.
93
                                                 */
94
                                                try {
95
                                                        if(p instanceof FPolygon2D){
96
                                                                offsetSegments.append(offsetAndConsumeClosedSegments(offset, segments),
97
                                                                                false);
98
                                                        } else {
99
                                                                offsetSegments.append(offsetAndConsumeSegments(offset, segments),
100
                                                                                false);
101
                                                        }
102
                                                } catch (NotEnoughSegmentsToClosePathException e) {
103
                                                        Logger.getLogger(Line2DOffset.class).error(
104
                                                                        e.getMessage(), e);
105
                                                }
106
                                                segments.clear();
107
                                                from = new Coordinate(dataCoords[0], dataCoords[1]);
108
                                                first = from;
109
                                                break;
110
                                        }
111

    
112
                                case PathIterator.SEG_LINETO:
113

    
114
                                        // System.out.println("SEG_LINETO");
115
                                        Coordinate to = new Coordinate(dataCoords[0], dataCoords[1]);
116
                                        if(from.compareTo(to)!=0){
117
                                                line = new LineSegment(from, to);
118
                                                segments.add(line);
119
                                                from = to;
120
                                        }
121
                                        break;
122
                                case PathIterator.SEG_CLOSE:
123
                                        line = new LineSegment(from, first);
124
                                        segments.add(line);
125
                                        //                                        from = first;
126
                                        try {
127
                                                offsetSegments.append(offsetAndConsumeClosedSegments(
128
                                                                offset, segments), false);
129
                                        } catch (NotEnoughSegmentsToClosePathException e) {
130
                                                Logger.getLogger(Line2DOffset.class).error(
131
                                                                e.getMessage(), e);
132
                                        }
133
                                        segments.clear();
134
                                        first =null;
135
                                        from = null;
136

    
137
                                        break;
138

    
139
                                } // end switch
140

    
141
                                pi.next();
142
                        }
143
                        offsetSegments.append(offsetAndConsumeSegments(offset, segments),
144
                                        false);
145

    
146
                        return offsetSegments;
147
                } catch (ParallelLinesCannotBeResolvedException e) {
148
                        Logger.getLogger(Line2DOffset.class).error(e.getMessage(), e);
149
                        return new GeneralPathX(p);
150
                }
151
        }
152

    
153
        private static GeneralPathX offsetAndConsumeSegments(double offset,
154
                        ArrayList<LineSegment> segments)
155
        throws ParallelLinesCannotBeResolvedException {
156
                Hashtable<LineSegment, LineEquation> offsetLines = new Hashtable<LineSegment, LineEquation>();
157
                int segmentCount = segments.size();
158
                // first calculate offset lines with the starting point
159
                for (int i = 0; i < segmentCount; i++) {
160
                        LineSegment segment = segments.get(i);
161
                        double theta = segment.angle();
162
                        //FIXME: ?Esto para qu? es?
163
//                        if (Math.abs(theta) % (Math.PI*0.5) < 0.00001){
164
//                                theta=theta+0.00000000000001;
165
//                        }
166

    
167
                        double xOffset = offset * Math.sin(theta);
168
                        double yOffset = offset * Math.cos(theta);
169

    
170
                        Coordinate p0 = segment.p0;
171
                        double x0 = p0.x + xOffset;
172
                        double y0 = p0.y - yOffset;
173

    
174
                        Coordinate p1 = segment.p1;
175
                        double x1 = p1.x + xOffset;
176
                        double y1 = p1.y - yOffset;
177

    
178
                        LineEquation offsetLine = new LineEquation(theta, x0, y0, x1, y1);
179
                        offsetLines.put(segment, offsetLine);
180
                }
181

    
182
                /*
183
                 * let's now calculate the end point of each segment with the point
184
                 * where each line crosses the next one. this point will be the end
185
                 * point of the first line, and the start point of its next one.
186
                 */
187
                Point2D pIni = null;
188
                Point2D pEnd = null;
189
                GeneralPathX gpx = new GeneralPathX();
190
                for (int i = 0; i < segmentCount; i++) {
191
                        LineSegment segment = segments.get(0);
192
                        LineEquation eq = offsetLines.get(segment);
193
                        if (i == 0) {
194
                                pIni = new Point2D.Double(eq.x, eq.y);
195
                        } else {
196
                                pIni = pEnd;
197
                        }
198

    
199
                        if (i < segmentCount - 1) {
200
                                LineEquation eq1 = offsetLines.get(segments.get(1));
201
                                try{
202
                                        pEnd = eq.resolve(eq1);
203
                                } catch (ParallelLinesCannotBeResolvedException e) { //Las lineas son paralelas y NO son la misma.
204
                                        pEnd = new Point2D.Double(eq.xEnd, eq.yEnd);
205
                                        gpx.append(new Line2D.Double(pIni, pEnd), true); // a?adimos una linea hasta el final del primer segmento
206
//                                         y asignamos como punto final el principio del siguiente segmento
207
//                                         para que en la siguiente iteraci?n lo tome como punto inicial.
208
                                        pIni = pEnd;
209
                                        pEnd = new Point2D.Double(eq1.x, eq1.y);
210
                                        segments.remove(0);
211
                                        continue;
212
                                }
213
                        } else {
214
                                pEnd = new Point2D.Double(eq.xEnd, eq.yEnd);
215
                        }
216

    
217
                        gpx.append(new Line2D.Double(pIni, pEnd), true);
218
                        segments.remove(0);
219
                }
220
                return gpx;
221
        }
222

    
223
        
224
        private static GeneralPathX offsetAndConsumeClosedSegments(double offset,
225
                        ArrayList<LineSegment> segments)
226
        throws ParallelLinesCannotBeResolvedException, NotEnoughSegmentsToClosePathException {
227
                int segmentCount = segments.size();
228
                if (segmentCount > 1) {
229
                        Hashtable<LineSegment, LineEquation> offsetLines = new Hashtable<LineSegment, LineEquation>();
230
                        // first calculate offset lines with the starting point
231
                        for (int i = 0; i < segmentCount; i++) {
232
                                LineSegment segment = segments.get(i);
233
                                double theta = segment.angle();
234
                                //FIXME: ?Esto para qu? es?
235
                                //                        if (Math.abs(theta) % (Math.PI*0.5) < 0.00001){
236
                                //                                theta=theta+0.00000000000001;
237
                                //                        }
238

    
239
                                double xOffset = offset * Math.sin(theta);
240
                                double yOffset = offset * Math.cos(theta);
241

    
242
                                Coordinate p0 = segment.p0;
243
                                double x0 = p0.x + xOffset;
244
                                double y0 = p0.y - yOffset;
245

    
246
                                Coordinate p1 = segment.p1;
247
                                double x1 = p1.x + xOffset;
248
                                double y1 = p1.y - yOffset;
249

    
250
                                LineEquation offsetLine = new LineEquation(theta, x0, y0, x1, y1);
251
                                offsetLines.put(segment, offsetLine);
252
                        }
253

    
254
                        /*
255
                         * let's now calculate the end point of each segment with the point
256
                         * where each line crosses the next one. this point will be the end
257
                         * point of the first line, and the start point of its next one.
258
                         */
259
                        Point2D pIni = null;
260
                        Point2D pEnd = null;
261
                        Point2D firstP = null;
262
                        GeneralPathX gpx = new GeneralPathX();
263
                        for (int i = 0; i < segmentCount; i++) {
264
                                LineSegment segment = segments.get(0);
265
                                LineEquation eq = offsetLines.get(segment);
266
                                if (i == 0) { //Calculo de la intersecci?n entre el primer segmento y el ?ltimo
267
                                        LineEquation eq0 = offsetLines.get(segments.get(segmentCount-1));
268
                                        try{
269
                                                pIni = eq0.resolve(eq);
270
                                        } catch (ParallelLinesCannotBeResolvedException e) { //Las lineas son paralelas y NO son la misma.
271
//                                                pIni = new Point2D.Double(eq0.xEnd, eq0.yEnd);
272
                                                pIni = new Point2D.Double(eq.x, eq.y);
273
                                        }
274
                                        firstP = pIni;
275
                                } else {
276
                                        pIni = pEnd;
277
                                }
278

    
279
                                if (i < segmentCount - 1) {
280
                                        LineEquation eq1 = offsetLines.get(segments.get(1));
281
                                        try{
282
                                                pEnd = eq.resolve(eq1);
283
                                        } catch (ParallelLinesCannotBeResolvedException e) { //Las lineas son paralelas y NO son la misma.
284
                                                pEnd = new Point2D.Double(eq.xEnd, eq.yEnd);
285
                                                gpx.append(new Line2D.Double(pIni, pEnd), true); // a?adimos una linea hasta el final del primer segmento
286
                                                //                                         y asignamos como punto final el principio del siguiente segmento
287
                                                //                                         para que en la siguiente iteraci?n lo tome como punto inicial.
288
                                                pIni = pEnd;
289
                                                pEnd = new Point2D.Double(eq1.x, eq1.y);
290
                                                segments.remove(0);
291
                                                continue;
292
                                        }
293
                                } else {
294
//                                        pEnd = new Point2D.Double(eq.xEnd, eq.yEnd);
295
                                        pEnd = new Point2D.Double(firstP.getX(), firstP.getY());
296
                                }
297

    
298
                                gpx.append(new Line2D.Double(pIni, pEnd), true);
299
                                segments.remove(0);
300
                        }
301
                        return gpx;
302
                }
303
                throw new NotEnoughSegmentsToClosePathException(segments);
304

    
305
        }
306

    
307
//        private static GeneralPathX offsetAndConsumeClosedSegments(double offset,
308
//                        ArrayList<LineSegment> segments)
309
//        throws ParallelLinesCannotBeResolvedException,
310
//        NotEnoughSegmentsToClosePathException {
311
//                int segmentCount = segments.size();
312
//                if (segmentCount > 1) {
313
//                        GeneralPathX openPath = offsetAndConsumeSegments(offset, segments);
314
//                        openPath.closePath();
315
//                        return openPath;
316
//                }
317
//                throw new NotEnoughSegmentsToClosePathException(segments);
318
//        }
319
}
320

    
321
class LineEquation {
322
        double theta, m, x, y;
323

    
324
        double xEnd, yEnd; // just for simplicity of code
325

    
326
        public LineEquation(double theta, double x, double y, double xEnd,
327
                        double yEnd) {
328
//                this.theta = Math.tan(theta); //Esto es un error, no podemos confundir el angulo de la recta con su pendiente
329
                this.theta = theta;
330
                this.m = Math.tan(theta);
331
                this.x = x;
332
                this.y = y;
333
                this.xEnd = xEnd;
334
                this.yEnd = yEnd;
335
        }
336

    
337
        public Point2D resolve(LineEquation otherLine)
338
        throws ParallelLinesCannotBeResolvedException {
339
                /*
340
                 * line1 (this): y - y0 = m*(x - x0)
341
                 * line2 (otherLine): y' - y'0 = m'*(x' - x'0)
342
                 */
343

    
344
                double X;
345
                double Y;
346
                if(Math.abs(this.x - this.xEnd)<0.00001) { //Esta linea es vertical
347
                        X = this.xEnd;
348
                        if (Math.abs(otherLine.x - otherLine.xEnd)<0.00001){//La otra linea es vertical
349
                                if(Math.abs(this.x - otherLine.x)<0.00001){ //Son la misma linea, devolvemos el primer punto de la otra linea.
350
                                        Y = otherLine.y;
351
                                } else { //No son la misma linea, entonces son paralelas, excepcion.
352
                                        throw new ParallelLinesCannotBeResolvedException(this, otherLine);
353
                                }
354
                        } else if (Math.abs(otherLine.y - otherLine.yEnd)<0.00001) { //La otra linea es horizontal
355
                                Y = otherLine.y;
356
                        } else { //Si la otra linea no es ni vertical ni horizontal
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
                        Y = this.yEnd;
362
                        if (Math.abs(otherLine.y - otherLine.yEnd)<0.00001) { //La otra linea es horizontal
363
                                if(Math.abs(this.y - otherLine.y)<0.00001){ //Son la misma linea, devolvemos el primer punto de la otra linea.
364
                                        X = otherLine.x;
365
                                } else { //No son la misma linea, entonces son paralelas, excepcion.
366
                                        throw new ParallelLinesCannotBeResolvedException(this, otherLine);
367
                                }
368
                        } else if (Math.abs(otherLine.x - otherLine.xEnd)<0.00001){//La otra linea es vertical
369
                                X = otherLine.x;
370
                        } else { //Si la otra linea no es ni vertical ni horizontal
371
                                X = (Y - otherLine.y)/otherLine.m +otherLine.x;
372
                        }
373
                } else { //Esta linea no es ni vertical ni horizontal
374
                        if (Math.abs(otherLine.y - otherLine.yEnd)<0.00001) { //La otra linea es horizontal
375
                                Y = otherLine.y;
376
                                X = (Y - this.y)/this.m +this.x;
377
                        } else if (Math.abs(otherLine.x - otherLine.xEnd)<0.00001){//La otra linea es vertical
378
                                X = otherLine.x;
379
                                Y = this.m*(X - this.x)+this.y;
380
                        } else if ((Math.abs(otherLine.m - this.m)<0.00001)) { //Tienen la misma pendiente
381
                                Y = otherLine.m*(this.x - otherLine.x)+otherLine.y;
382
                                if (Math.abs(this.y - Y)<0.00001){ //Las lineas son la misma
383
                                        X = otherLine.x;
384
                                        Y = otherLine.y;
385
                                } else {
386
                                        throw new ParallelLinesCannotBeResolvedException(this, otherLine);
387
                                }
388
                        } else { //Si la otra linea no es ni vertical ni horizontal
389
                                double mTimesX = this.m * this.x;
390
                                X = (mTimesX - this.y - otherLine.m * otherLine.x + otherLine.y) / (this.m - otherLine.m);
391
                                Y = this.m * X - mTimesX + this.y;
392
                        }
393
                }
394
                return new Point2D.Double(X, Y);
395
        }
396

    
397
        @Override
398
        public String toString() {
399
                return "Y - " + y + " = " + m + "*(X - " + x + ")";
400
        }
401
}
402

    
403
class NotEnoughSegmentsToClosePathException extends Exception {
404
        private static final long serialVersionUID = 95503944546535L;
405

    
406
        public NotEnoughSegmentsToClosePathException(ArrayList<LineSegment> segments) {
407
                super("Need at least 2 segments to close a path. I've got "
408
                                + segments.size() + ".");
409
        }
410
}
411

    
412
class ParallelLinesCannotBeResolvedException extends Exception {
413
        private static final long serialVersionUID = 8322556508820067641L;
414

    
415
        public ParallelLinesCannotBeResolvedException(LineEquation eq1,
416
                        LineEquation eq2) {
417
                super("Lines '" + eq1 + "' and '" + eq2
418
                                + "' are parallel and don't share any point!");
419
        }
420
}
421
//public class Line2DOffset {
422

    
423
//private static final double TOL = 1E-8;
424
//private static final double ANGLE_TOL = 0.01/180*Math.PI;
425

    
426
//public static GeneralPathX offsetLine(Shape p, double offset) {
427

    
428
//PathIterator pi = p.getPathIterator(null);
429
//double[] dataCoords = new double[6];
430
//Coordinate from = null, first = null;
431
//ArrayList<LineSegment> segments = new ArrayList<LineSegment>();
432
//GeneralPathX offsetSegments = new GeneralPathX();
433
//try {
434
//while (!pi.isDone()) {
435
//// while not done
436
//int type = pi.currentSegment(dataCoords);
437

    
438
//switch (type) {
439
//case PathIterator.SEG_MOVETO:
440
//from = new Coordinate(dataCoords[0], dataCoords[1]);
441
//first = from;
442
//break;
443

    
444
//case PathIterator.SEG_LINETO:
445

    
446
//// System.out.println("SEG_LINETO");
447
//Coordinate to = new Coordinate(dataCoords[0], dataCoords[1]);
448
//LineSegment line = new LineSegment(from, to);
449
//int size = segments.size();
450
//if (size>0) {
451
//LineSegment prev = segments.get(size-1);
452
//if (line.angle() == prev.angle()) {
453
//if (Math.abs(line.p0.x - prev.p1.x) < TOL &&
454
//Math.abs(line.p0.y - prev.p1.y) < TOL) {
455
//prev.p1 = line.p1;
456
//break;
457
//}
458
//}
459
//}
460
//from = to;
461
//segments.add(line);
462

    
463
//break;
464
//case PathIterator.SEG_CLOSE:
465
//line = new LineSegment(from, first);
466
//segments.add(line);
467
//from = first;
468
//try {
469
//offsetSegments.append(offsetAndConsumeClosedSegments(offset, segments), false);
470
//} catch (NotEnoughSegmentsToClosePathException e) {
471
//Logger.getLogger(Line2DOffset.class).error(e.getMessage(), e);
472
//}
473
//break;
474

    
475
//} // end switch
476

    
477
//pi.next();
478
//}
479
//offsetSegments.append(offsetAndConsumeSegments(offset, segments), true);
480

    
481
//return offsetSegments;
482
//} catch (ParallelLinesCannotBeResolvedException e) {
483
//Logger.getLogger(Line2DOffset.class).error(e.getMessage(), e);
484
//return new GeneralPathX(p);
485
//}
486
//}
487

    
488
//private static GeneralPathX offsetAndConsumeSegments(double offset, ArrayList<LineSegment> segments)  {
489
//Hashtable<LineSegment, LineEquation> offsetLines = new Hashtable<LineSegment, LineEquation>();
490
//int segmentCount = segments.size();
491
//// first calculate offset lines with the starting point
492
//for (int i = 0; i < segmentCount; i++) {
493
//LineSegment segment = segments.get(i);
494
//double theta = segment.angle();
495

    
496
//double xOffset = offset*Math.sin(theta);
497
//double yOffset = offset*Math.cos(theta);
498

    
499
//Coordinate p0 = segment.p0;
500
//double x0 = p0.x + xOffset;
501
//double y0 = p0.y - yOffset;
502

    
503
//Coordinate p1 = segment.p1;
504
//double x1 = p1.x + xOffset;
505
//double y1 = p1.y - yOffset;
506

    
507
//LineEquation offsetLine = new LineEquation(theta, x0, y0, x1, y1, offset);
508
//offsetLines.put(segment, offsetLine);
509
//}
510

    
511
///*
512
//* let's now calculate the end point of each segment with
513
//* the point where each line crosses the next one.
514
//* this point will be the end point of the first line, and
515
//* the start point of its next one.
516
//*/
517
//Point2D pIni = null;
518
//Point2D pEnd = null;
519
//GeneralPathX gpx = new GeneralPathX();
520
//for (int i = 0; i < segmentCount; i++) {
521
//LineSegment segment = segments.get(0);
522
//LineEquation eq = offsetLines.get(segment);
523
//Point2D pAux = null;
524
//if (i < segmentCount -1) {
525
//try {
526
//pAux = eq.resolve(offsetLines.get(segments.get(1)));
527
//if (i == 0) {
528
//pIni = new Point2D.Double(eq.x, eq.y);
529
//} else {
530
//pIni = pEnd;
531
//}
532
//} catch (ParallelLinesCannotBeResolvedException e) {
533
//segments.remove(0);
534
//continue;
535
//}
536
//}
537

    
538

    
539
//if (pAux != null) {
540
//pEnd = pAux;
541
//} else {
542
//pEnd = new Point2D.Double(eq.xEnd, eq.yEnd);
543
//}
544

    
545
//gpx.append(new Line2D.Double(pIni, pEnd), true);
546
//segments.remove(0);
547
//}
548
//return gpx;
549
//}
550

    
551
//private static GeneralPathX offsetAndConsumeClosedSegments(double offset, ArrayList<LineSegment> segments) throws ParallelLinesCannotBeResolvedException, NotEnoughSegmentsToClosePathException {
552
//int segmentCount = segments.size();
553
//if (segmentCount > 1) {
554
//GeneralPathX openPath = offsetAndConsumeSegments(offset, segments);
555
//openPath.closePath();
556
//return openPath;
557
//}
558
//throw new NotEnoughSegmentsToClosePathException(segments);
559
//}
560
//}
561

    
562
//class LineEquation {
563
//double theta, x, y;
564
//double xEnd, yEnd; // just for simplicity of code
565
//double offset;
566

    
567
//public LineEquation(double theta, double x, double y, double xEnd, double yEnd, double offset) {
568
//this.theta = theta;
569
//this.x = x;
570
//this.y = y;
571
//this.xEnd = xEnd;
572
//this.yEnd = yEnd;
573
//this.offset = offset;
574
//}
575

    
576
//public Point2D resolve(LineEquation otherLine) throws ParallelLinesCannotBeResolvedException {
577
//double X;
578
//double Y;
579

    
580

    
581
///*
582
//* line1 (this):      y  -  y0 =  m*(x  - x0)
583
//* line2 (otherLine): y' - y'0 = m'*(x' - x'0)
584
//*/
585
//if (otherLine.theta == this.theta)
586
//throw new ParallelLinesCannotBeResolvedException(this, otherLine);
587

    
588
//if (Math.cos(theta) == 0) {
589

    
590
//X = otherLine.x + offset*Math.cos(otherLine.theta);
591
//Y = otherLine.y + offset*Math.sin(otherLine.theta);
592
//} else if (Math.cos(otherLine.theta) == 0) {
593
//X = x + offset*Math.cos(theta);
594
//Y = y + offset*Math.sin(theta);
595
//} else {
596
///*
597
//* m*(X - x0) + y0 = m'*(X - x'0) + y0'
598
//* X = (m*x0 - y0 - m'*x0' + y'0) / (m - m')
599
//*/
600
//double tanTheta = Math.tan(theta);
601
//double otherTanTheta = Math.tan(otherLine.theta);
602
//double thetaTimesX = tanTheta*this.x;
603
//X = (thetaTimesX - this.y - otherTanTheta*otherLine.x + otherLine.y) / (tanTheta - otherTanTheta);
604

    
605
///*
606
//* Y - y0 = m*(X - x0)
607
//* Y = m*X - m*x0 + y0
608
//*/
609
//Y = tanTheta*X - thetaTimesX + this.y;
610
//}
611
//return new Point2D.Double(X, Y);
612
//}
613

    
614
//@Override
615
//public String toString() {
616
//return "Y - "+y+" = "+theta+"*(X - "+x+")";
617
//}
618
//}
619

    
620
//class NotEnoughSegmentsToClosePathException extends Exception {
621
//private static final long serialVersionUID = 95503944546535L;
622
//public NotEnoughSegmentsToClosePathException(ArrayList<LineSegment> segments) {
623
//super("Need at least 2 segments to close a path. I've got "+segments.size()+".");
624
//}
625
//}
626

    
627
//class ParallelLinesCannotBeResolvedException extends Exception {
628
//private static final long serialVersionUID = 8322556508820067641L;
629

    
630
//public ParallelLinesCannotBeResolvedException(LineEquation eq1, LineEquation eq2) {
631
//super("Lines '"+eq1+"' and '"+eq2+"' are parallel and don't share any point!");
632
//}
633
//}