Statistics
| Revision:

gvsig-vectorediting / org.gvsig.vectorediting / trunk / org.gvsig.vectorediting / org.gvsig.vectorediting.lib / org.gvsig.vectorediting.lib.prov / org.gvsig.vectorediting.lib.prov.extendline / src / main / java / org / gvsig / vectorediting / lib / prov / extendline / operation / ExtendLineOperationUtils.java @ 2603

History | View | Annotate | Download (24.9 KB)

1
/**
2
 * gvSIG. Desktop Geographic Information System.
3
 *
4
 * Copyright ? 2007-2015 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 2
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.vectorediting.lib.prov.extendline.operation;
25

    
26
import java.util.HashMap;
27
import java.util.Map;
28
import org.gvsig.fmap.dal.exception.DataException;
29
import org.gvsig.fmap.dal.feature.Feature;
30
import org.gvsig.fmap.dal.feature.FeatureSelection;
31
import org.gvsig.fmap.geom.Geometry;
32
import org.gvsig.fmap.geom.Geometry.TYPES;
33
import org.gvsig.fmap.geom.GeometryException;
34
import org.gvsig.fmap.geom.GeometryLocator;
35
import org.gvsig.fmap.geom.GeometryManager;
36
import org.gvsig.fmap.geom.aggregate.MultiLine;
37
import org.gvsig.fmap.geom.aggregate.MultiPoint;
38
import org.gvsig.fmap.geom.exception.CreateGeometryException;
39
import org.gvsig.fmap.geom.operation.GeometryOperationException;
40
import org.gvsig.fmap.geom.operation.GeometryOperationNotSupportedException;
41
import org.gvsig.fmap.geom.primitive.Arc;
42
import org.gvsig.fmap.geom.primitive.Curve;
43
import org.gvsig.fmap.geom.primitive.Point;
44
import org.gvsig.fmap.geom.primitive.Primitive;
45
import org.gvsig.tools.dispose.DisposableIterator;
46

    
47
/**
48
 * @author llmarques
49
 *
50
 */
51
public class ExtendLineOperationUtils {
52

    
53
    /**
54
     * Use it to indicate start side should be extended
55
     */
56
    public static final String START_SIDE = "start";
57

    
58
    /**
59
     * Use it to indicate end side should be extended
60
     */
61
    public static final String END_SIDE = "end";
62

    
63
    /**
64
     * Number of projections computed to know intersection points.
65
     */
66
    private final static int PROJECTION_LIMIT = 100;
67

    
68
    /**
69
     * Number of steps to compute to know intersection points.
70
     */
71
    private final static int PROJECTION_STEPS = 10;
72

    
73
    private static Map<Integer, ExtendLineOperation> operations
74
            = new HashMap<Integer, ExtendLineOperation>();
75

    
76
    public ExtendLineOperationUtils() {
77
    }
78

    
79
    public static void register(ExtendLineOperation operation, int geometryType) {
80
        operations.put(geometryType, operation);
81
    }
82

    
83
    public static ExtendLineOperation getOperation(Primitive geom) {
84
        Integer type = geom.getGeometryType().getType();
85

    
86
        ExtendLineOperation operation = operations.get(type);
87

    
88
        return operation;
89
    }
90

    
91
    /**
92
     * Calculates the nearest intersection among curve and boundary objects
93
     * depending on side received as parameter.
94
     *
95
     * @param line to be extended
96
     * @param sideToExtend What side will be extend. Use
97
     * {@link ExtendLineOperationUtils#START_SIDE} and
98
     * {@link ExtendLineOperationUtils#END_SIDE}
99
     * @param boundaryObjects to calculate intersection points.
100
     * @return the nearest intersection point. Return Null if arc does not
101
     * intersect with any boundary object
102
     * @throws org.gvsig.fmap.geom.exception.CreateGeometryException
103
     * @throws org.gvsig.fmap.dal.exception.DataException
104
     * @throws
105
     * org.gvsig.fmap.geom.operation.GeometryOperationNotSupportedException
106
     * @throws org.gvsig.fmap.geom.operation.GeometryOperationException
107
     */
108
    public static Point curveIntersection(Curve line, String sideToExtend,
109
            FeatureSelection boundaryObjects) throws CreateGeometryException,
110
            DataException, GeometryOperationNotSupportedException,
111
            GeometryOperationException {
112

    
113
        Point initPoint = getExtremeSegmentInitPoint(line, sideToExtend);
114
        Point endPoint = getExtremeSegmentEndPoint(line, sideToExtend);
115

    
116
        return getIntersectionOfProjectedLine(initPoint, endPoint,
117
                boundaryObjects);
118
    }
119

    
120
    /**
121
     * Calculates the nearest intersection among curve and boundary objects
122
     * depending on side received as parameter.
123
     *
124
     * @param line to be extended
125
     * @param sideToExtend What side will be extend. Use
126
     * {@link ExtendLineOperationUtils#START_SIDE} and
127
     * {@link ExtendLineOperationUtils#END_SIDE}
128
     * @param boundaryObject to calculate intersection points.
129
     * @return the nearest intersection point. Return Null if arc does not
130
     * intersect with any boundary object
131
     * @throws org.gvsig.fmap.geom.exception.CreateGeometryException
132
     * @throws org.gvsig.fmap.dal.exception.DataException
133
     * @throws
134
     * org.gvsig.fmap.geom.operation.GeometryOperationNotSupportedException
135
     * @throws org.gvsig.fmap.geom.operation.GeometryOperationException
136
     */
137
    public static Point curveIntersection(Curve line, String sideToExtend,
138
            Geometry boundaryObject) throws GeometryException,
139
            DataException, GeometryOperationNotSupportedException,
140
            GeometryOperationException {
141

    
142
        Point initPoint = getExtremeSegmentInitPoint(line, sideToExtend);
143
        Point endPoint = getExtremeSegmentEndPoint(line, sideToExtend);
144

    
145
        return getIntersectionOfProjectedLine(initPoint, endPoint,
146
                boundaryObject);
147
    }
148

    
149
    private static Point getExtremeSegmentEndPoint(Curve line, String sideToExtend) {
150
        // Start side line is formed by second point and first point
151
        if (sideToExtend.equalsIgnoreCase(START_SIDE)) {
152
            return line.getVertex(0);
153
            // End side line is formed by penultimate point and last point
154
        } else if (sideToExtend.equalsIgnoreCase(END_SIDE)) {
155
            return line.getVertex(line.getNumVertices() - 1);
156
        }
157
        return null;
158
    }
159

    
160
    private static Point getExtremeSegmentInitPoint(Curve line, String sideToExtend) {
161
        // Start side line is formed by second point and first point
162
        if (sideToExtend.equalsIgnoreCase(START_SIDE)) {
163
            return line.getVertex(1);
164
            // End side line is formed by penultimate point and last point
165
        } else if (sideToExtend.equalsIgnoreCase(END_SIDE)) {
166
            return line.getVertex(line.getNumVertices() - 2);
167
        }
168
        return null;
169
    }
170

    
171
    /**
172
     * Calculates the nearest intersection point among arc and boundary objects
173
     * depending on side received as parameter.Strategy:
174
     *
175
     * 1- Create a full arc with the same center and radius of arc received by
176
     * parameter.2- Iterate over boundary objects.3- If some boundary object
177
     * intersects with full arc, calculates the distance to start point or end
178
     * point depending on side to be extend.4- Return the nearest intersection
179
     * point.
180
     *
181
     *
182
     * @param arcToBeExtended Arc to be extended
183
     * @param sideToExtend What side will be extend. Use
184
     * {@link ExtendLineOperationUtils#START_SIDE} and
185
     * {@link ExtendLineOperationUtils#END_SIDE}
186
     * @param boundaryObjects to calculate intersection points.
187
     * @return the nearest intersection point. Return Null if arc does not
188
     * intersect with any boundary object
189
     * @throws
190
     * org.gvsig.fmap.geom.operation.GeometryOperationNotSupportedException
191
     * @throws org.gvsig.fmap.geom.operation.GeometryOperationException
192
     * @throws org.gvsig.fmap.geom.exception.CreateGeometryException
193
     * @throws org.gvsig.fmap.dal.exception.DataException
194
     */
195
    public static Point arcIntersection(Arc arcToBeExtended,
196
            String sideToExtend, FeatureSelection boundaryObjects)
197
            throws GeometryOperationNotSupportedException,
198
            GeometryOperationException, CreateGeometryException, DataException {
199

    
200
        GeometryManager geoManager = GeometryLocator.getGeometryManager();
201
        int subtype = arcToBeExtended.getGeometryType().getSubType();
202

    
203
        Point center = arcToBeExtended.getCenterPoint();
204
        double radius = center.distance(arcToBeExtended.getInitPoint());
205

    
206
        Point intersection = null;
207

    
208
        double minDistance = Double.POSITIVE_INFINITY;
209

    
210
        Arc tmpArc = (Arc) geoManager.create(TYPES.ARC, subtype);
211
        tmpArc.setPoints(center, radius, 0, Math.PI * 2);
212

    
213
        DisposableIterator it = boundaryObjects.fastIterator();
214
        while (it.hasNext()) {
215
            Feature feature = (Feature) it.next();
216
            Geometry geometry = feature.getDefaultGeometry();
217
            if (tmpArc.intersects(geometry)) {
218
                Geometry intersectionGeometry = tmpArc.intersection(geometry);
219

    
220
                if (intersectionGeometry instanceof MultiPoint) {
221
                    MultiPoint intersectionMultiPoint
222
                            = (MultiPoint) intersectionGeometry;
223

    
224
                    for (int i = 0; i < intersectionMultiPoint
225
                            .getPrimitivesNumber(); i++) {
226
                        Point point = intersectionMultiPoint.getPointAt(i);
227
                        double distance = Double.POSITIVE_INFINITY;
228

    
229
                        if (sideToExtend.equalsIgnoreCase(START_SIDE)) {
230
                            distance
231
                                    = point.distance(arcToBeExtended.getInitPoint());
232
                        } else if (sideToExtend.equalsIgnoreCase(END_SIDE)) {
233
                            distance
234
                                    = point.distance(arcToBeExtended.getEndPoint());
235
                        }
236

    
237
                        if (distance < minDistance) {
238
                            intersection = point;
239
                            minDistance = distance;
240
                        }
241
                    }
242
                } else if (intersectionGeometry instanceof Point) {
243
                    Point intersectionPoint = (Point) intersectionGeometry;
244
                    double distance = Double.POSITIVE_INFINITY;
245

    
246
                    if (sideToExtend.equalsIgnoreCase("start")) {
247
                        distance
248
                                = intersectionPoint.distance(arcToBeExtended
249
                                        .getInitPoint());
250
                    } else if (sideToExtend.equalsIgnoreCase("end")) {
251
                        distance
252
                                = intersectionPoint.distance(arcToBeExtended
253
                                        .getEndPoint());
254
                    }
255

    
256
                    if (distance < minDistance) {
257
                        intersection = intersectionPoint;
258
                        minDistance = distance;
259
                    }
260
                }
261
            }
262
        }
263
        it.dispose();
264
        return intersection;
265
    }
266

    
267
    /**
268
     * Calculates the nearest intersection point among arc and boundary objects
269
     * depending on side received as parameter.Strategy:
270
     *
271
     * 1- Create a full arc with the same center and radius of arc received by
272
     * parameter.2- Iterate over boundary objects.3- If some boundary object
273
     * intersects with full arc, calculates the distance to start point or end
274
     * point depending on side to be extend.4- Return the nearest intersection
275
     * point.
276
     *
277
     *
278
     * @param arcToBeExtended Arc to be extended
279
     * @param sideToExtend What side will be extend. Use
280
     * {@link ExtendLineOperationUtils#START_SIDE} and
281
     * {@link ExtendLineOperationUtils#END_SIDE}
282
     * @param boundaryObject to calculate intersection points.
283
     * @return the nearest intersection point. Return Null if arc does not
284
     * intersect with any boundary object
285
     * @throws
286
     * org.gvsig.fmap.geom.operation.GeometryOperationNotSupportedException
287
     * @throws org.gvsig.fmap.geom.operation.GeometryOperationException
288
     * @throws org.gvsig.fmap.geom.exception.CreateGeometryException
289
     * @throws org.gvsig.fmap.dal.exception.DataException
290
     */
291
    public static Point arcIntersection(Arc arcToBeExtended,
292
            String sideToExtend, Geometry boundaryObject)
293
            throws GeometryOperationNotSupportedException,
294
            GeometryOperationException, CreateGeometryException, DataException {
295

    
296
        GeometryManager geoManager = GeometryLocator.getGeometryManager();
297
        int subtype = arcToBeExtended.getGeometryType().getSubType();
298

    
299
        Point center = arcToBeExtended.getCenterPoint();
300
        double radius = center.distance(arcToBeExtended.getInitPoint());
301

    
302
        Point intersection = null;
303

    
304
//        double minDistance = Double.POSITIVE_INFINITY;
305

    
306
        Arc tmpArc = (Arc) geoManager.create(TYPES.ARC, subtype);
307
        tmpArc.setPoints(center, radius, 0, Math.PI * 2);
308

    
309
        double distance = Double.POSITIVE_INFINITY;
310
        double minDistance = Double.POSITIVE_INFINITY;
311
        if (tmpArc.intersects(boundaryObject)) {
312
            Geometry intersectionGeometry = tmpArc.intersection(boundaryObject);
313

    
314
            if (intersectionGeometry instanceof MultiPoint) {
315
                MultiPoint intersectionMultiPoint
316
                        = (MultiPoint) intersectionGeometry;
317

    
318
                for (int i = 0; i < intersectionMultiPoint
319
                        .getPrimitivesNumber(); i++) {
320
                    Point point = intersectionMultiPoint.getPointAt(i);
321

    
322
                    if (sideToExtend.equalsIgnoreCase(START_SIDE)) {
323
                        distance
324
                                = point.distance(arcToBeExtended.getInitPoint());
325
                    } else if (sideToExtend.equalsIgnoreCase(END_SIDE)) {
326
                        distance
327
                                = point.distance(arcToBeExtended.getEndPoint());
328
                    }
329

    
330
                    if (distance < minDistance) {
331
                        intersection = point;
332
                        minDistance = distance;
333
                    }
334
                }
335
            } else if (intersectionGeometry instanceof Point) {
336
                Point intersectionPoint = (Point) intersectionGeometry;
337

    
338
                intersection = intersectionPoint;
339
            }
340
        }
341
        return intersection;
342
    }
343

    
344
    // FIXME: remove this method when geometry library has this utility method
345
    public static double getAngle(Point start, Point end)
346
            throws GeometryOperationNotSupportedException,
347
            GeometryOperationException {
348
        double angle
349
                = Math.acos((end.getX() - start.getX()) / start.distance(end));
350

    
351
        if (start.getY() > end.getY()) {
352
            angle = -angle;
353
        }
354

    
355
        if (angle < 0) {
356
            angle += (2 * Math.PI);
357
        }
358

    
359
        return angle;
360
    }
361

    
362
    /**
363
     * Gets intersection among the line formed by initPoint and endPoint and
364
     * boundary objects.If line or its projection does not intersect with any
365
     * boundary object return null.Strategy:
366
     *
367
     * 1- Get module of line to determine if an intersection point already be
368
     * vertex of line.If the distance between intersection point and start point
369
     * of line is less than module indicates that intersection point already be
370
     * curve point.2- Project line with the line parametric equation. 3- Iterate
371
     * over boundary objects. 4- Check if boundary object does not contains end
372
     * point of projected line. 5- If projected line intersects with any
373
     * boundary object, get the nearest intersection point 6- Return it.
374
     *
375
     *
376
     * @param initPoint of curve to extend
377
     * @param endPoint end point of curve to extend
378
     * @param boundaryObjects to calculate intersection points.
379
     * @return the nearest intersection point. Return Null if arc does not
380
     * intersect with any boundary object
381
     * @throws
382
     * org.gvsig.fmap.geom.operation.GeometryOperationNotSupportedException
383
     * @throws org.gvsig.fmap.geom.operation.GeometryOperationException
384
     * @throws org.gvsig.fmap.dal.exception.DataException
385
     * @throws org.gvsig.fmap.geom.exception.CreateGeometryException
386
     */
387
    public static Point getIntersectionOfProjectedLine(Point initPoint,
388
            Point endPoint, FeatureSelection boundaryObjects)
389
            throws GeometryOperationNotSupportedException,
390
            GeometryOperationException, DataException, CreateGeometryException {
391

    
392
        GeometryManager geoManager = GeometryLocator.getGeometryManager();
393
        int subtype = initPoint.getGeometryType().getSubType();
394

    
395
        double module = initPoint.distance(endPoint);
396

    
397
        double minDistance = Double.POSITIVE_INFINITY;
398
        Point intersectionPoint = null;
399

    
400
        double x, y;
401
        double x1 = initPoint.getX();
402
        double y1 = initPoint.getY();
403
        double x2 = endPoint.getX();
404
        double y2 = endPoint.getY();
405

    
406
        for (int t = 1; t < PROJECTION_LIMIT; t += 10) {
407
            x = (x2 - x1) * t + x1;
408
            y = (y2 - y1) * t + y1;
409

    
410
            DisposableIterator it = boundaryObjects.fastIterator();
411
            while (it.hasNext()) {
412
                Feature feature = (Feature) it.next();
413
                Geometry geometry = feature.getDefaultGeometry();
414
                Point projectedPoint = geoManager.createPoint(x, y, subtype);
415

    
416
                if (!geometry.contains(projectedPoint)) {
417
                    Curve tmpLine = geoManager.createLine(subtype);
418
                    tmpLine.setPoints(initPoint, projectedPoint);
419

    
420
                    if (tmpLine.intersects(geometry)) {
421

    
422
                        Geometry intersecionGeometry
423
                                = geometry.intersection(tmpLine);
424

    
425
                        if (intersecionGeometry instanceof Point) {
426

    
427
                            double distance
428
                                    = ((Point) intersecionGeometry)
429
                                            .distance(initPoint);
430

    
431
                            if (distance < minDistance && distance > (module + 0.01)) {
432
                                intersectionPoint = (Point) intersecionGeometry;
433
                                minDistance = distance;
434
                            }
435

    
436
                        } else if (intersecionGeometry instanceof MultiPoint) {
437

    
438
                            MultiPoint intersectionMultiPoint
439
                                    = (MultiPoint) intersecionGeometry;
440

    
441
                            for (int i = 0; i < intersectionMultiPoint
442
                                    .getPrimitivesNumber(); i++) {
443

    
444
                                double distance
445
                                        = intersectionMultiPoint.getPointAt(i)
446
                                                .distance(initPoint);
447

    
448
                                if (distance < minDistance && distance > (module + 0.01)) {
449
                                    intersectionPoint
450
                                            = intersectionMultiPoint.getPointAt(i);
451
                                    minDistance = distance;
452
                                }
453
                            }
454
                        } else if (intersecionGeometry instanceof Curve) {
455

    
456
                            Curve intersectionCurve
457
                                    = (Curve) intersecionGeometry;
458

    
459
                            for (int i = 0; i < intersectionCurve
460
                                    .getNumVertices(); i++) {
461

    
462
                                double distance
463
                                        = intersectionCurve.getVertex(i).distance(
464
                                                endPoint);
465

    
466
                                if (distance < minDistance && distance > (module + 0.01)) {
467
                                    intersectionPoint
468
                                            = intersectionCurve.getVertex(i);
469
                                    minDistance = distance;
470
                                }
471
                            }
472
                        }
473
                    }
474
                }
475
            }
476
            it.dispose();
477
            if (intersectionPoint != null) {
478
                break;
479
            }
480
        }
481
        return intersectionPoint;
482
    }
483

    
484
    /**
485
     * Gets intersection among the line formed by initPoint and endPoint and
486
     * boundary object.If line or its projection does not intersect with
487
     * boundary object return null.Strategy:
488
     *
489
     * 1- Get module of line to determine if an intersection point already be
490
     * vertex of line.If the distance between intersection point and start point
491
     * of line is less than module indicates that intersection point already be
492
     * curve point.2- Project line with the line parametric equation. 3- Check
493
     * if boundary object does not contains end point of projected line. 5- If
494
     * projected line intersects with boundary object, get the nearest
495
     * intersection point 6- Return it.
496
     *
497
     *
498
     * @param initPoint of curve to extend
499
     * @param endPoint end point of curve to extend
500
     * @param boundaryObject to calculate intersection points.
501
     * @return the nearest intersection point. Return Null if arc does not
502
     * intersect with any boundary object
503
     * @throws
504
     * org.gvsig.fmap.geom.operation.GeometryOperationNotSupportedException
505
     * @throws org.gvsig.fmap.geom.operation.GeometryOperationException
506
     * @throws org.gvsig.fmap.dal.exception.DataException
507
     * @throws org.gvsig.fmap.geom.exception.CreateGeometryException
508
     */
509
    public static Point getIntersectionOfProjectedLine(Point initPoint,
510
            Point endPoint, Geometry boundaryObject)
511
            throws GeometryOperationNotSupportedException,
512
            GeometryOperationException, DataException, GeometryException {
513

    
514
        GeometryManager geoManager = GeometryLocator.getGeometryManager();
515
        int subtype = initPoint.getGeometryType().getSubType();
516

    
517
        double module = initPoint.distance(endPoint);
518

    
519
        double minDistance = Double.POSITIVE_INFINITY;
520
        Point intersectionPoint = null;
521

    
522
        double x, y;
523
        double x1 = initPoint.getX();
524
        double y1 = initPoint.getY();
525
        double x2 = endPoint.getX();
526
        double y2 = endPoint.getY();
527

    
528
        double projectionLimit = 2 * endPoint.distance(boundaryObject);
529
        double step = projectionLimit/PROJECTION_STEPS;
530

    
531
        for (double t = 1; t < projectionLimit; t += step) {
532
            x = (x2 - x1) * t + x1;
533
            y = (y2 - y1) * t + y1;
534

    
535
            Point projectedPoint = geoManager.createPoint(x, y, subtype);
536
            MultiLine boundaryObjectLines=  boundaryObject.toLines();
537
            if (!boundaryObjectLines.contains(projectedPoint)) {
538
                Curve tmpLine = geoManager.createLine(subtype);
539
                tmpLine.setPoints(initPoint, projectedPoint);
540

    
541
                if (tmpLine.intersects(boundaryObject)) {
542

    
543
                    Geometry intersecionGeometry
544
                            = boundaryObjectLines.intersection(tmpLine);
545

    
546
                    if (intersecionGeometry instanceof Point) {
547

    
548
                        double distance
549
                                = ((Point) intersecionGeometry)
550
                                        .distance(initPoint);
551

    
552
                        if (distance < minDistance && distance > (module + 0.01)) {
553
                            intersectionPoint = (Point) intersecionGeometry;
554
                            minDistance = distance;
555
                        }
556

    
557
                    } else if (intersecionGeometry instanceof MultiPoint) {
558

    
559
                        MultiPoint intersectionMultiPoint
560
                                = (MultiPoint) intersecionGeometry;
561

    
562
                        for (int i = 0; i < intersectionMultiPoint
563
                                .getPrimitivesNumber(); i++) {
564

    
565
                            double distance
566
                                    = intersectionMultiPoint.getPointAt(i)
567
                                            .distance(initPoint);
568

    
569
                            if (distance < minDistance && distance > (module + 0.01)) {
570
                                intersectionPoint
571
                                        = intersectionMultiPoint.getPointAt(i);
572
                                minDistance = distance;
573
                            }
574
                        }
575
                    } else if (intersecionGeometry instanceof Curve) {
576

    
577
                        Curve intersectionCurve
578
                                = (Curve) intersecionGeometry;
579

    
580
                        for (int i = 0; i < intersectionCurve
581
                                .getNumVertices(); i++) {
582

    
583
                            double distance
584
                                    = intersectionCurve.getVertex(i).distance(
585
                                            endPoint);
586

    
587
                            if (distance < minDistance && distance > (module + 0.01)) {
588
                                intersectionPoint
589
                                        = intersectionCurve.getVertex(i);
590
                                minDistance = distance;
591
                            }
592
                        }
593
                    }
594
                }
595
            } else {
596
                intersectionPoint = projectedPoint;
597
            }
598
            if (intersectionPoint != null) {
599
                break;
600
            }
601
        }
602
        return intersectionPoint;
603
    }
604

    
605
}