Statistics
| Revision:

root / branches / pilotoDWG / libraries / libFMap / src / com / iver / cit / gvsig / fmap / edition / cad / TrigonometricalFunctions.java @ 1631

History | View | Annotate | Download (17.6 KB)

1
/*
2
 * Created on 10-feb-2005
3
 *
4
 * gvSIG. Sistema de Informaci?n Geogr?fica de la Generalitat Valenciana
5
 *
6
 * Copyright (C) 2004 IVER T.I. and Generalitat Valenciana.
7
 *
8
 * This program is free software; you can redistribute it and/or
9
 * modify it under the terms of the GNU General Public License
10
 * as published by the Free Software Foundation; either version 2
11
 * of the License, or (at your option) any later version.
12
 *
13
 * This program is distributed in the hope that it will be useful,
14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
 * GNU General Public License for more details.
17
 *
18
 * You should have received a copy of the GNU General Public License
19
 * along with this program; if not, write to the Free Software
20
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
21
 *
22
 * For more information, contact:
23
 *
24
 *  Generalitat Valenciana
25
 *   Conselleria d'Infraestructures i Transport
26
 *   Av. Blasco Ib??ez, 50
27
 *   46010 VALENCIA
28
 *   SPAIN
29
 *
30
 *      +34 963862235
31
 *   gvsig@gva.es
32
 *      www.gvsig.gva.es
33
 *
34
 *    or
35
 *
36
 *   IVER T.I. S.A
37
 *   Salamanca 50
38
 *   46005 Valencia
39
 *   Spain
40
 *
41
 *   +34 963163400
42
 *   dac@iver.es
43
 */
44
package com.iver.cit.gvsig.fmap.edition.cad;
45

    
46
import com.iver.cit.gvsig.fmap.core.v02.FConverter;
47

    
48
import com.vividsolutions.jts.algorithm.LineIntersector;
49
import com.vividsolutions.jts.algorithm.RobustCGAlgorithms;
50
import com.vividsolutions.jts.geom.Coordinate;
51
import com.vividsolutions.jts.geom.GeometryFactory;
52
import com.vividsolutions.jts.geom.LineString;
53
import com.vividsolutions.jts.operation.linemerge.LineMerger;
54

    
55
import java.awt.geom.Arc2D;
56
import java.awt.geom.Line2D;
57
import java.awt.geom.Point2D;
58
import java.awt.geom.Rectangle2D;
59

    
60

    
61
/**
62
 * Funciones de utilidad relacionadas con trigonometr?a
63
 */
64
public class TrigonometricalFunctions {
65
        /**
66
         * Obtiene un par de puntos que definen la recta perpendicular a p1-p2 que
67
         * pasa por el punto perp
68
         *
69
         * @param p1 punto de la recta p1-p2
70
         * @param p2 punto de la recta p1-p2
71
         * @param perp Punto por el que pasa la recta perpendicular, debe ser
72
         *                   distinto a p2
73
         *
74
         * @return Array con dos puntos que definen la recta resultante
75
         */
76
        public static Point2D[] getPerpendicular(Point2D p1, Point2D p2,
77
                Point2D perp) {
78
                if ((p2.getY() - p1.getY()) == 0) {
79
                        return new Point2D[] {
80
                                new Point2D.Double(perp.getX(), 0),
81
                                new Point2D.Double(perp.getX(), 1)
82
                        };
83
                }
84

    
85
                //Pendiente de la recta perpendicular
86
                double m = (p1.getX() - p2.getX()) / (p2.getY() - p1.getY());
87

    
88
                //b de la funcion de la recta perpendicular
89
                double b = perp.getY() - (m * perp.getX());
90

    
91
                //Obtenemos un par de puntos
92
                Point2D[] res = new Point2D[2];
93

    
94
                res[0] = new Point2D.Double(0, (m * 0) + b);
95
                res[1] = new Point2D.Double(1000, (m * 1000) + b);
96

    
97
                return res;
98
        }
99

    
100
        /**
101
         * Obtiene un arco a partir de 3 puntos. Devuelve null si no se puede crear
102
         * el arco porque los puntos est?n alineados o los 3 puntos no son
103
         * distintos
104
         *
105
         * @param p1
106
         * @param p2
107
         * @param p3
108
         *
109
         * @return Arco
110
         */
111
        public static Arc2D createArc(Point2D p1, Point2D p2, Point2D p3) {
112
                Point2D center = getCenter(p1, p2, p3);
113

    
114
                if (center == null) {
115
                        return null;
116
                }
117

    
118
                double angle1 = getAngle(center, p1);
119
                double angle2 = getAngle(center, p3);
120
                double extent = angleDistance(angle1, angle2);
121

    
122
                Coordinate[] coords = new Coordinate[4];
123
                coords[0] = new Coordinate(p1.getX(), p1.getY());
124
                coords[1] = new Coordinate(p2.getX(), p2.getY());
125
                coords[2] = new Coordinate(p3.getX(), p3.getY());
126
                coords[3] = new Coordinate(p1.getX(), p1.getY());
127

    
128
                if (!RobustCGAlgorithms.isCCW(coords)) {
129
                        extent = (Math.PI * 2) - extent;
130
                } else {
131
                        extent = -extent;
132
                }
133

    
134
                //System.err.println("angle1:" + angle1);
135
                //System.err.println("angle2:" + getAngle(center, p2));
136
                //System.err.println("angle3:" + angle2);
137
                //System.err.println("extent:" + extent);
138
                double Radio = p1.distance(center);
139
                double xR = center.getX() - Radio;
140
                double yR = center.getY() - Radio;
141
                double w = 2.0 * Radio;
142
                double h = w;
143

    
144
                Rectangle2D.Double rBounds = new Rectangle2D.Double(xR, yR, w, h);
145
                Arc2D.Double resul = new Arc2D.Double(rBounds,
146
                                Math.toDegrees((Math.PI * 2) - angle1), Math.toDegrees(extent),
147
                                Arc2D.OPEN);
148

    
149
                return resul;
150
        }
151

    
152
        /**
153
         * Obtiene el punto que se encuentra a una distancia 'dist' de la recta
154
         * p1-p2 y se encuentra en la recta perpendicular que pasa por perpPoint
155
         *
156
         * @param p1 Punto de la recta p1-p2
157
         * @param p2 Punto de la recta p1-p2
158
         * @param perpPoint Punto de la recta perpendicular
159
         * @param dist Distancia del punto que se quiere obtener a la recta p1-p2
160
         *
161
         * @return DOCUMENT ME!
162
         */
163
        public static Point2D getPerpendicularPoint(Point2D p1, Point2D p2,
164
                Point2D perpPoint, double dist) {
165
                Point2D[] p = getPerpendicular(p1, p2, perpPoint);
166
                Point2D unit = getUnitVector(p[0], p[1]);
167

    
168
                return new Point2D.Double(perpPoint.getX() + (unit.getX() * dist),
169
                        perpPoint.getY() + (unit.getY() * dist));
170
        }
171

    
172
        /**
173
         * Obtiene el centro del c?rculo que pasa por los tres puntos que se pasan
174
         * como  par?metro
175
         *
176
         * @param p1 primer punto del c?rculo cuyo centro se quiere obtener
177
         * @param p2 segundo punto del c?rculo cuyo centro se quiere obtener
178
         * @param p3 tercer punto del c?rculo cuyo centro se quiere obtener
179
         *
180
         * @return Devuelve null si los puntos est?n alineados o no son 3 puntos
181
         *                    distintos
182
         */
183
        public static Point2D getCenter(Point2D p1, Point2D p2, Point2D p3) {
184
                if (p1.equals(p2) || p2.equals(p3) || p1.equals(p3)) {
185
                        return null;
186
                }
187

    
188
                Point2D[] perp1 = getPerpendicular(p1, p2,
189
                                new Point2D.Double((p1.getX() + p2.getX()) / 2,
190
                                        (p1.getY() + p2.getY()) / 2));
191
                Point2D[] perp2 = getPerpendicular(p2, p3,
192
                                new Point2D.Double((p2.getX() + p3.getX()) / 2,
193
                                        (p2.getY() + p3.getY()) / 2));
194

    
195
                return getIntersection(perp1[0], perp1[1], perp2[0], perp2[1]);
196
        }
197

    
198
        /**
199
         * Obtiene el centro del circulo que pasa por los puntos p1, p2 y p3
200
         *
201
         * @param p1
202
         * @param p2
203
         * @param p3
204
         *
205
         * @return Devuelve el punto o null si no hay ning?n c?rculo (puntos
206
         *                    alineados)
207
         */
208
        public static Point2D getCircleCenter(Point2D p1, Point2D p2, Point2D p3) {
209
                double xC;
210
                double yC;
211
                double w;
212
                double h;
213

    
214
                // Calculamos 2 secantes, tiramos perpendiculares por sus puntos
215
                // medios y obtenemos el centro. Luego calculamos el radio.
216
                // Puntos medios de los segmentos.
217
                double xm1;
218

    
219
                // Calculamos 2 secantes, tiramos perpendiculares por sus puntos
220
                // medios y obtenemos el centro. Luego calculamos el radio.
221
                // Puntos medios de los segmentos.
222
                double ym1;
223

    
224
                // Calculamos 2 secantes, tiramos perpendiculares por sus puntos
225
                // medios y obtenemos el centro. Luego calculamos el radio.
226
                // Puntos medios de los segmentos.
227
                double xm2;
228

    
229
                // Calculamos 2 secantes, tiramos perpendiculares por sus puntos
230
                // medios y obtenemos el centro. Luego calculamos el radio.
231
                // Puntos medios de los segmentos.
232
                double ym2;
233
                xm1 = (p1.getX() + p2.getX()) / 2.0;
234
                ym1 = (p1.getY() + p2.getY()) / 2.0;
235
                xm2 = (p2.getX() + p3.getX()) / 2.0;
236
                ym2 = (p2.getY() + p3.getY()) / 2.0;
237

    
238
                /*
239
                 * g.setColor(Color.GRAY); g.draw3DRect((int)xm1, (int) ym1, 1, 1,
240
                 * true); g.draw3DRect((int)xm2, (int) ym2, 1, 1, true);
241
                 */
242

    
243
                // Pendientes de las perpendiculares y constantes
244
                double mP1 = 0;
245

    
246
                /*
247
                 * g.setColor(Color.GRAY); g.draw3DRect((int)xm1, (int) ym1, 1, 1,
248
                 * true); g.draw3DRect((int)xm2, (int) ym2, 1, 1, true);
249
                 */
250

    
251
                // Pendientes de las perpendiculares y constantes
252
                double mP2 = 0;
253

    
254
                /*
255
                 * g.setColor(Color.GRAY); g.draw3DRect((int)xm1, (int) ym1, 1, 1,
256
                 * true); g.draw3DRect((int)xm2, (int) ym2, 1, 1, true);
257
                 */
258

    
259
                // Pendientes de las perpendiculares y constantes
260
                double A1;
261

    
262
                /*
263
                 * g.setColor(Color.GRAY); g.draw3DRect((int)xm1, (int) ym1, 1, 1,
264
                 * true); g.draw3DRect((int)xm2, (int) ym2, 1, 1, true);
265
                 */
266

    
267
                // Pendientes de las perpendiculares y constantes
268
                double A2;
269
                boolean bPerp1 = false;
270
                boolean bPerp2 = false;
271

    
272
                if ((p2.getY() - p1.getY()) == 0) {
273
                        A1 = ym1;
274
                        bPerp1 = true;
275
                } else {
276
                        mP1 = (p2.getX() - p1.getX()) / (p1.getY() - p2.getY());
277
                        A1 = ym1 - (xm1 * mP1);
278
                }
279

    
280
                if ((p2.getY() - p3.getY()) == 0) {
281
                        A2 = ym2;
282
                        bPerp2 = true;
283
                } else {
284
                        mP2 = (p3.getX() - p2.getX()) / (p2.getY() - p3.getY());
285
                        A2 = ym2 - (xm2 * mP2);
286
                }
287

    
288
                if (mP2 == mP1) {
289
                        return null; // Error, 3 puntos alineados. No puede pasar un arco
290
                } else {
291
                        xC = (A2 - A1) / (mP1 - mP2);
292

    
293
                        if (!bPerp1) {
294
                                yC = (xC * mP1) + A1;
295
                        } else {
296
                                yC = (xC * mP2) + A2;
297
                        }
298
                }
299

    
300
                return new Point2D.Double(xC, yC);
301
        }
302

    
303
        /**
304
         * Obtiene un c?rculo a partir de 3 puntos. Devuelve null si no se puede
305
         * crear el c?ruclo porque los puntos est?n alineados
306
         *
307
         * @param p1
308
         * @param p2
309
         * @param p3
310
         *
311
         * @return C?rculo
312
         */
313
        static public Arc2D createCircle(Point2D p1, Point2D p2, Point2D p3) //,
314
        // Graphics
315
        // g)
316
         {
317
                Point2D center = getCircleCenter(p1, p2, p3);
318

    
319
                double Radio = p1.distance(center);
320
                double xR = center.getX() - Radio;
321
                double yR = center.getY() - Radio;
322
                double w = 2.0 * Radio;
323
                double h = w;
324

    
325
                Rectangle2D.Double rBounds = new Rectangle2D.Double(xR, yR, w, h);
326
                Arc2D.Double resul = new Arc2D.Double(rBounds, 0.0, 360.0, Arc2D.OPEN);
327

    
328
                return resul;
329
        }
330

    
331
        /**
332
         * Obtiene el ?ngulo del vector que se pasa como par?metro con el vector
333
         * horizontal de izquierda a derecha
334
         *
335
         * @param start punto origen del vector
336
         * @param end punto destino del vector
337
         *
338
         * @return angulo en radianes
339
         */
340
        public static double getAngle(Point2D start, Point2D end) {
341
                double angle = Math.acos((end.getX() - start.getX()) / start.distance(
342
                                        end));
343

    
344
                if (start.getY() > end.getY()) {
345
                        angle = -angle;
346
                }
347

    
348
                if (angle < 0) {
349
                        angle += (2 * Math.PI);
350
                }
351

    
352
                return angle;
353
        }
354

    
355
        /**
356
         * Devuelve la distancia desde angle1 a angle2. Angulo en radianes de
357
         * diferencia entre angle1 y angle2 en sentido antihorario
358
         *
359
         * @param angle1 angulo en radianes. Debe ser positivo y no dar ninguna
360
         *                   vuelta a la circunferencia
361
         * @param angle2 angulo en radianes. Debe ser positivo y no dar ninguna
362
         *                   vuelta a la circunferencia
363
         *
364
         * @return distancia entre los ?ngulos
365
         */
366
        public static double angleDistance(double angle1, double angle2) {
367
                if (angle1 < angle2) {
368
                        return angle2 - angle1;
369
                } else {
370
                        return ((Math.PI * 2) - angle1) + angle2;
371
                }
372
        }
373

    
374
        /**
375
         * Devuelve el punto de la recta que viene dada por los puntos p1 y p2 a
376
         * una distancia radio de p1.
377
         *
378
         * @param p1 DOCUMENT ME!
379
         * @param p2 DOCUMENT ME!
380
         * @param radio DOCUMENT ME!
381
         *
382
         * @return DOCUMENT ME!
383
         */
384
        public static Point2D getPoint(Point2D p1, Point2D p2, double radio) {
385
                Point2D paux = new Point2D.Double(p2.getX() - p1.getX(),
386
                                p2.getY() - p1.getY());
387
                double v = Math.sqrt(Math.pow((double) paux.getX(), (double) 2) +
388
                                Math.pow((double) paux.getY(), (double) 2));
389
                paux = new Point2D.Double(paux.getX() / v, paux.getY() / v);
390

    
391
                Point2D aux1 = new Point2D.Double(p1.getX() + (radio * paux.getX()),
392
                                p1.getY() + (radio * paux.getY()));
393

    
394
                return aux1;
395
        }
396
        /**
397
         * Devuelve el punto a una distancia radio del punto p1 y aplicandole una ngulo an.
398
         * una distancia radio de p1.
399
         *
400
         * @param p1 DOCUMENT ME!
401
         * @param p2 DOCUMENT ME!
402
         * @param radio DOCUMENT ME!
403
         *
404
         * @return DOCUMENT ME!
405
         */
406
        public static Point2D getPoint(Point2D p1, double an, double radio) {
407
                double x=(radio*Math.cos(an))+p1.getX();
408
                double y=(radio*Math.sin(an))+p1.getY();
409
                
410
                Point2D p=new Point2D.Double(x,y);
411
                
412
                return p;
413
        }
414

    
415
        /**
416
         * Devuelve la menor distancia desde angle1 a angle2.
417
         *
418
         * @param angle1 angulo en radianes. Debe ser positivo y no dar ninguna
419
         *                   vuelta a la circunferencia
420
         * @param angle2 angulo en radianes. Debe ser positivo y no dar ninguna
421
         *                   vuelta a la circunferencia
422
         *
423
         * @return distancia entre los ?ngulos
424
         */
425
        public static double absoluteAngleDistance(double angle1, double angle2) {
426
                double d = Math.abs(angle1 - angle2);
427

    
428
                if (d < Math.PI) {
429
                        return d;
430
                } else {
431
                        if (angle1 < angle2) {
432
                                angle2 -= (Math.PI * 2);
433
                        } else {
434
                                angle1 -= (Math.PI * 2);
435
                        }
436

    
437
                        return Math.abs(angle1 - angle2);
438
                }
439
        }
440

    
441
        /**
442
         * Devuelve el punto de la intersecci?n entre las lineas p1-p2 y p3-p4.
443
         *
444
         * @param p1 punto de la recta p1-p2
445
         * @param p2 punto de la recta p1-p2
446
         * @param p3 punto de la recta p3-p4
447
         * @param p4 punto de la recta p3-p4
448
         *
449
         * @return DOCUMENT ME!
450
         *
451
         * @throws RuntimeException DOCUMENT ME!
452
         */
453
        public static Point2D getIntersection(Point2D p1, Point2D p2, Point2D p3,
454
                Point2D p4) {
455
                double m1 = Double.POSITIVE_INFINITY;
456

    
457
                if ((p2.getX() - p1.getX()) != 0) {
458
                        m1 = (p2.getY() - p1.getY()) / (p2.getX() - p1.getX());
459
                }
460

    
461
                double m2 = Double.POSITIVE_INFINITY;
462

    
463
                if ((p4.getX() - p3.getX()) != 0) {
464
                        m2 = (p4.getY() - p3.getY()) / (p4.getX() - p3.getX());
465
                }
466

    
467
                if ((m1 == Double.POSITIVE_INFINITY) &&
468
                                (m2 == Double.POSITIVE_INFINITY)) {
469
                        return null;
470
                }
471

    
472
                double b1 = p2.getY() - (m1 * p2.getX());
473

    
474
                double b2 = p4.getY() - (m2 * p4.getX());
475

    
476
                if ((m1 != Double.POSITIVE_INFINITY) &&
477
                                (m2 != Double.POSITIVE_INFINITY)) {
478
                        if (m1 == m2) {
479
                                return null;
480
                        }
481

    
482
                        double x = (b2 - b1) / (m1 - m2);
483

    
484
                        return new Point2D.Double(x, (m1 * x) + b1);
485
                } else if (m1 == Double.POSITIVE_INFINITY) {
486
                        double x = p1.getX();
487

    
488
                        return new Point2D.Double(x, (m2 * x) + b2);
489
                } else if (m2 == Double.POSITIVE_INFINITY) {
490
                        double x = p3.getX();
491

    
492
                        return new Point2D.Double(x, (m1 * x) + b1);
493
                }
494

    
495
                //no llega nunca
496
                throw new RuntimeException("BUG!");
497
        }
498

    
499
        /**
500
         * Devuelve un vector unitario en forma de punto a partir de dos puntos.
501
         *
502
         * @param p1 punto origen.
503
         * @param p2 punto destino.
504
         *
505
         * @return vector unitario.
506
         */
507
        public static Point2D getUnitVector(Point2D p1, Point2D p2) {
508
                Point2D paux = new Point2D.Double(p2.getX() - p1.getX(),
509
                                p2.getY() - p1.getY());
510
                double v = Math.sqrt(Math.pow((double) paux.getX(), (double) 2) +
511
                                Math.pow((double) paux.getY(), (double) 2));
512
                paux = new Point2D.Double(paux.getX() / v, paux.getY() / v);
513

    
514
                return paux;
515
        }
516

    
517
        /**
518
         * Devuelve true si los puntos que se pasan como par?metros est?n situados
519
         * en el mismo orden que las agujas del reloj o si por el contrario no lo
520
         * estan.
521
         *
522
         * @param p1 primer punto
523
         * @param p2 segundo punto
524
         * @param p3 tercer punto
525
         *
526
         * @return True si estan en el sentido de la agujas del reloj.
527
         */
528
        public static boolean isCCW(Point2D p1, Point2D p2, Point2D p3) {
529
                Coordinate[] coords = new Coordinate[4];
530
                coords[0] = new Coordinate(p1.getX(), p1.getY());
531
                coords[1] = new Coordinate(p2.getX(), p2.getY());
532
                coords[2] = new Coordinate(p3.getX(), p3.getY());
533
                coords[3] = new Coordinate(p1.getX(), p1.getY());
534

    
535
                return RobustCGAlgorithms.isCCW(coords);
536
        }
537

    
538
        /**
539
         * DOCUMENT ME!
540
         *
541
         * @param antp DOCUMENT ME!
542
         * @param lastp DOCUMENT ME!
543
         * @param interp DOCUMENT ME!
544
         * @param point DOCUMENT ME!
545
         *
546
         * @return DOCUMENT ME!
547
         */
548
        public static boolean isLowAngle(Point2D antp, Point2D lastp,
549
                Point2D interp, Point2D point) {
550
                ///double ob=lastp.distance(point);
551
                ///Point2D[] aux=getPerpendicular(lastp,interp,point);
552
                ///Point2D intersect=getIntersection(aux[0],aux[1],lastp,interp);
553
                ///double pb=intersect.distance(point);
554
                ///double a=Math.asin(pb/ob);
555
                Coordinate[] coords = new Coordinate[4];
556
                coords[0] = new Coordinate(lastp.getX(), lastp.getY());
557
                coords[1] = new Coordinate(interp.getX(), interp.getY());
558
                coords[2] = new Coordinate(point.getX(), point.getY());
559
                coords[3] = new Coordinate(lastp.getX(), lastp.getY());
560

    
561
                try {
562
                        double angle1 = getAngle(antp, lastp);
563
                        System.out.println("angle1= " + angle1);
564

    
565
                        double angle2 = getAngle(lastp, point);
566
                        System.out.println("angle2= " + angle2);
567

    
568
                        /*if (lastp.getX()<antp.getX()){
569
                           System.out.println("angleDiff 2 1= "+angleDistance(angle2,angle1));
570
                           System.out.println("angleDiff 1 2= "+angleDistance(angle1,angle2));
571
                           if (angleDistance(angle2,angle1)>Math.PI){
572
                        
573
                           if (RobustCGAlgorithms.isCCW(coords)) {
574
                                   System.out.println("izquierda,arriba,true");
575
                                   return true;
576
                           } else{
577
                                   System.out.println("izquierda,arriba,false");
578
                           }
579
                           }else {
580
                                   if (!RobustCGAlgorithms.isCCW(coords)) {
581
                                           System.out.println("izquierda,abajo,true");
582
                                           return true;
583
                                   } else{
584
                                           System.out.println("izquierda,abajo,false");
585
                                   }
586
                           }
587
                           }else if (lastp.getX()>antp.getX()){
588
                         */
589
                        System.out.println("angleDifl 2 1= " +
590
                                angleDistance(angle2, angle1));
591
                        System.out.println("angleDifl 1 2= " +
592
                                angleDistance(angle1, angle2));
593

    
594
                        if (angleDistance(angle2, angle1) > Math.PI) {
595
                                if (RobustCGAlgorithms.isCCW(coords)) {
596
                                        System.out.println("derecha,arriba,true");
597

    
598
                                        return true;
599
                                } else {
600
                                        System.out.println("derecha,arriba,false");
601
                                }
602
                        } else {
603
                                if (!RobustCGAlgorithms.isCCW(coords)) {
604
                                        System.out.println("derecha,abajo,true");
605

    
606
                                        return true;
607
                                } else {
608
                                        System.out.println("derecha,abajo,false");
609
                                }
610
                        }
611

    
612
                        //}
613
                } catch (Exception e) {
614
                        System.out.println("false");
615

    
616
                        return true;
617
                }
618

    
619
                return false;
620
        }
621

    
622
        /**
623
         * DOCUMENT ME!
624
         *
625
         * @param args DOCUMENT ME!
626
         */
627
        public static void main(String[] args) {
628
                System.out.println(getIntersection(new Point2D.Double(0, 0),
629
                                new Point2D.Double(2, 2), new Point2D.Double(3, 3),
630
                                new Point2D.Double(3, 4)));
631
                System.out.println(getIntersection(new Point2D.Double(2, 3),
632
                                new Point2D.Double(2, 2), new Point2D.Double(3, 3),
633
                                new Point2D.Double(3, 4)));
634
                System.out.println(getIntersection(new Point2D.Double(0, 0),
635
                                new Point2D.Double(2, 2), new Point2D.Double(1, 0),
636
                                new Point2D.Double(2, 3)));
637
                System.out.println(getIntersection(new Point2D.Double(0, 4),
638
                                new Point2D.Double(2, 4), new Point2D.Double(3, 3),
639
                                new Point2D.Double(0, 0)));
640
        }
641
}