Class SplitSegment

 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 import org.locationtech.jts.geom.Coordinate;
16 import org.locationtech.jts.geom.LineSegment;
17  
18 /**
19  * Models a constraint segment which can be split in two in various ways, 
20  * according to certain geometric constraints.
21  * 
22  * @author Martin Davis
23  */
24 public class SplitSegment {
25     /**
26      * Computes the {@link Coordinate} that lies a given fraction along the line defined by the
27      * reverse of the given segment. A fraction of <code>0.0</code> returns the end point of the
28      * segment; a fraction of <code>1.0</code> returns the start point of the segment.
29      * 
30      * @param seg the LineSegment
31      * @param segmentLengthFraction the fraction of the segment length along the line
32      * @return the point at that distance
33      */
34     private static Coordinate pointAlongReverse(LineSegment seg, double segmentLengthFraction) {
35         Coordinate coord = new Coordinate();
36         coord.x = seg.p1.x - segmentLengthFraction * (seg.p1.x - seg.p0.x);
37         coord.y = seg.p1.y - segmentLengthFraction * (seg.p1.y - seg.p0.y);
38         return coord;
39     }
40  
41     private LineSegment seg;
42     private double      segLen;
43     private Coordinate  splitPt;
44     private double      minimumLen = 0.0;
45  
46     public SplitSegment(LineSegment seg) {
47         this.seg = seg;
48         segLen = seg.getLength();
49     }
50  
51     public void setMinimumLength(double minLen) {
52         minimumLen = minLen;
53     }
54  
55     public Coordinate getSplitPoint() {
56         return splitPt;
57     }
58  
59     public void splitAt(double length, Coordinate endPt) {
60         double actualLen = getConstrainedLength(length);
61         double frac = actualLen / segLen;
62         if (endPt.equals2D(seg.p0))
63             splitPt = seg.pointAlong(frac);
64         else
65             splitPt = pointAlongReverse(seg, frac);
66     }
67  
68     public void splitAt(Coordinate pt) {
69         // check that given pt doesn't violate min length
70         double minFrac = minimumLen / segLen;
71         if (pt.distance(seg.p0) < minimumLen) {
72             splitPt = seg.pointAlong(minFrac);
73             return;
74         }
75         if (pt.distance(seg.p1) < minimumLen) {
76             splitPt = pointAlongReverse(seg, minFrac);
77             return;
78         }
79         // passes minimum distance check - use provided point as split pt
80         splitPt = pt;
81     }
82  
83     private double getConstrainedLength(double len) {
84         if (len < minimumLen)
85             return minimumLen;
86         return len;
87     }
88  
89 }
90