001: /*
002: * The Unified Mapping Platform (JUMP) is an extensible, interactive GUI
003: * for visualizing and manipulating spatial features with geometry and attributes.
004: *
005: * Copyright (C) 2003 Vivid Solutions
006: *
007: * This program is free software; you can redistribute it and/or
008: * modify it under the terms of the GNU General Public License
009: * as published by the Free Software Foundation; either version 2
010: * of the License, or (at your option) any later version.
011: *
012: * This program is distributed in the hope that it will be useful,
013: * but WITHOUT ANY WARRANTY; without even the implied warranty of
014: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
015: * GNU General Public License for more details.
016: *
017: * You should have received a copy of the GNU General Public License
018: * along with this program; if not, write to the Free Software
019: * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
020: *
021: * For more information, contact:
022: *
023: * Vivid Solutions
024: * Suite #1A
025: * 2328 Government Street
026: * Victoria BC V8T 5G5
027: * Canada
028: *
029: * (250)385-6040
030: * www.vividsolutions.com
031: */
032:
033: package com.vividsolutions.jump.geom;
034:
035: import com.vividsolutions.jts.geom.*;
036:
037: /**
038: * Utility functions for {@link LineSegment}s.
039: * <p>
040: * <i>Note:
041: * Eventually some of these functions may be moved into the JTS LineSegment class.</i>
042: */
043: public class LineSegmentUtil {
044: /**
045: * Projects one line segment onto another and returns the resulting
046: * line segment.
047: * The returned line segment will be a subset of
048: * the target line line segment. This subset may be null, if
049: * the segments are oriented in such a way that there is no projection.
050: *
051: * @param tgt the line segment to be projected onto
052: * @param seg the line segment to project
053: * @return the projected line segment, or <code>null</code> if there is no overlap
054: */
055: public static LineSegment project(LineSegment tgt, LineSegment seg) {
056: double pf0 = tgt.projectionFactor(seg.p0);
057: double pf1 = tgt.projectionFactor(seg.p1);
058:
059: // check if segment projects at all
060: if ((pf0 >= 1.0) && (pf1 >= 1.0)) {
061: return null;
062: }
063:
064: if ((pf0 <= 0.0) && (pf1 <= 0.0)) {
065: return null;
066: }
067:
068: Coordinate newp0 = tgt.project(seg.p0);
069:
070: if (pf0 < 0.0) {
071: newp0 = tgt.p0;
072: }
073:
074: if (pf0 > 1.0) {
075: newp0 = tgt.p1;
076: }
077:
078: Coordinate newp1 = tgt.project(seg.p1);
079:
080: if (pf1 < 0.0) {
081: newp1 = tgt.p0;
082: }
083:
084: if (pf1 > 1.0) {
085: newp1 = tgt.p1;
086: }
087:
088: return new LineSegment(newp0, newp1);
089: }
090:
091: /**
092: * Computes the Hausdorff distance between two LineSegments.
093: * To compute the Hausdorff distance, it is sufficient to compute
094: * the distance from one segment's endpoints to the other segment
095: * and choose the maximum.
096: *
097: * @param seg0
098: * @param seg1
099: * @return the Hausdorff distance between the segments
100: */
101: public static double hausdorffDistance(LineSegment seg0,
102: LineSegment seg1) {
103: double hausdorffDist = seg0.distance(seg1.p0);
104: double dist;
105: dist = seg0.distance(seg1.p1);
106:
107: if (dist > hausdorffDist) {
108: hausdorffDist = dist;
109: }
110:
111: dist = seg1.distance(seg0.p0);
112:
113: if (dist > hausdorffDist) {
114: hausdorffDist = dist;
115: }
116:
117: dist = seg1.distance(seg0.p1);
118:
119: if (dist > hausdorffDist) {
120: hausdorffDist = dist;
121: }
122:
123: return hausdorffDist;
124: }
125:
126: /**
127: * Converts a LineSegment to a LineString.
128: * @param factory a factory used to create the LineString
129: * @param seg the LineSegment to convert
130: * @return a new LineString based on the segment
131: */
132: public static LineString asGeometry(GeometryFactory factory,
133: LineSegment seg) {
134: Coordinate[] coord = { new Coordinate(seg.p0),
135: new Coordinate(seg.p1) };
136: LineString line = factory.createLineString(coord);
137:
138: return line;
139: }
140:
141: //Is this the same as LineSegment's #closestPoint method? If so, this method
142: //should be removed. [Jon Aquino]
143: /*
144: public static Coordinate OLDclosestPoint(LineSegment seg, Coordinate p) {
145: double factor = seg.projectionFactor(p);
146:
147: if ((factor > 0) && (factor < 1)) {
148: return seg.project(p);
149: }
150:
151: double dist0 = seg.p0.distance(p);
152: double dist1 = seg.p1.distance(p);
153:
154: if (dist0 < dist1) {
155: return seg.p0;
156: }
157:
158: return seg.p1;
159: }
160: */
161: }
|