Class NonEncroachingSplitPointFinder

 1 /*
 2  * Copyright (c) 2016 Vivid Solutions.
 3  *
 4  * All rights reserved. This program and the accompanying materials
 5  * are made available under the terms of the Eclipse Public License 2.0
 6  * and Eclipse Distribution License v. 1.0 which accompanies this distribution.
 7  * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v20.html
 8  * and the Eclipse Distribution License is available at
 9  *
10  * http://www.eclipse.org/org/documents/edl-v10.php.
11  */
12  
13 package org.locationtech.jts.triangulate;
14  
15  
16 import org.locationtech.jts.geom.Coordinate;
17 import org.locationtech.jts.geom.LineSegment;
18  
19 /**
20  * A strategy for finding constraint split points which attempts to maximise the length of the split
21  * segments while preventing further encroachment. (This is not always possible for narrow angles).
22  * 
23  * @author Martin Davis
24  */
25 public class NonEncroachingSplitPointFinder implements ConstraintSplitPointFinder {
26  
27     public NonEncroachingSplitPointFinder() {}
28  
29     /**
30      * A basic strategy for finding split points when nothing extra is known about the geometry of
31      * the situation.
32      * 
33      * @param seg the encroached segment
34      * @param encroachPt the encroaching point
35      * @return the point at which to split the encroached segment
36      */
37     public Coordinate findSplitPoint(Segment seg, Coordinate encroachPt) {
38         LineSegment lineSeg = seg.getLineSegment();
39         double segLen = lineSeg.getLength();
40         double midPtLen = segLen / 2;
41         SplitSegment splitSeg = new SplitSegment(lineSeg);
42  
43         Coordinate projPt = projectedSplitPoint(seg, encroachPt);
44         /**
45          * Compute the largest diameter (length) that will produce a split segment which is not
46          * still encroached upon by the encroaching point (The length is reduced slightly by a
47          * safety factor)
48          */
49         double nonEncroachDiam = projPt.distance(encroachPt) * 2 * 0.8// .99;
50         double maxSplitLen = nonEncroachDiam;
51         if (maxSplitLen > midPtLen) {
52             maxSplitLen = midPtLen;
53         }
54         splitSeg.setMinimumLength(maxSplitLen);
55  
56         splitSeg.splitAt(projPt);
57  
58         return splitSeg.getSplitPoint();
59     }
60  
61     /**
62      * Computes a split point which is the projection of the encroaching point on the segment
63      * 
64      * @param seg
65      * @param encroachPt
66      * @return a split point on the segment
67      */
68     public static Coordinate projectedSplitPoint(Segment seg, Coordinate encroachPt) {
69         LineSegment lineSeg = seg.getLineSegment();
70         Coordinate projPt = lineSeg.project(encroachPt);
71         return projPt;
72     }
73 }
74