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 */ pointAlongReverse(LineSegment seg, double segmentLengthFraction)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 SplitSegment(LineSegment seg)46 public SplitSegment(LineSegment seg) { 47 this.seg = seg; 48 segLen = seg.getLength(); 49 } 50 setMinimumLength(double minLen)51 public void setMinimumLength(double minLen) { 52 minimumLen = minLen; 53 } 54 getSplitPoint()55 public Coordinate getSplitPoint() { 56 return splitPt; 57 } 58 splitAt(double length, Coordinate endPt)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 splitAt(Coordinate pt)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 getConstrainedLength(double len)83 private double getConstrainedLength(double len) { 84 if (len < minimumLen) 85 return minimumLen; 86 return len; 87 } 88 89 } 90