/* * The JTS Topology Suite is a collection of Java classes that * implement the fundamental operations required to validate a given * geo-spatial data set to a known topological specification. * * Copyright (C) 2001 Vivid Solutions * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * For more information, contact: * * Vivid Solutions * Suite #1A * 2328 Government Street * Victoria BC V8T 5G5 * Canada * * (250)385-6040 * www.vividsolutions.com */ package com.revolsys.geometry.operation.distance; import com.revolsys.geometry.model.Geometry; import com.revolsys.geometry.model.LineString; import com.revolsys.geometry.model.Point; import com.revolsys.geometry.model.coordinates.LineSegmentUtil; import com.revolsys.util.MathUtil; /** * Represents a sequence of facets (points or line segments) * of a {@link Geometry} * specified by a subsequence of a {@link LineString}. * * @author Martin Davis * */ public class LineFacetSequence implements FacetSequence { private final LineString line; private final int start; private final int vertexCount; /** * Creates a new sequence for a single point from a LineString. * * @param line the sequence holding the points in the facet sequence * @param start the index of the point */ public LineFacetSequence(final LineString line, final int start) { this(line, start, start + 1); } /** * Creates a new section based on a LineString. * * @param line the sequence holding the points in the section * @param start the index of the start point * @param end the index of the end point + 1 */ public LineFacetSequence(final LineString line, final int start, final int end) { this.line = line; this.start = start; this.vertexCount = end - start; } private double computeLineLineDistance(final FacetSequence facetSeq) { // both linear - compute minimum segment-segment distance double minDistance = Double.MAX_VALUE; final int lastVertexIndex1 = getVertexCount() - 1; for (int vertexIndex1 = 0; vertexIndex1 < lastVertexIndex1; vertexIndex1++) { final double line1x1 = getX(vertexIndex1); final double line1y1 = getY(vertexIndex1); final double line1x2 = getX(vertexIndex1 + 1); final double line1y2 = getY(vertexIndex1 + 1); final int lastVertexIndex2 = facetSeq.getVertexCount() - 1; for (int vertexIndex2 = 0; vertexIndex2 < lastVertexIndex2; vertexIndex2++) { final double line2x1 = facetSeq.getX(vertexIndex1); final double line2y1 = facetSeq.getY(vertexIndex1); final double line2x2 = facetSeq.getX(vertexIndex1 + 1); final double line2y2 = facetSeq.getY(vertexIndex1 + 1); final double dist = LineSegmentUtil.distanceLineLine(line1x1, line1y1, line1x2, line1y2, line2x1, line2y1, line2x2, line2y2); if (dist == 0.0) { return 0.0; } else if (dist < minDistance) { minDistance = dist; } } } return minDistance; } @Override public double distance(final FacetSequence facetSeq) { final boolean isPoint = isPoint(); final boolean isPointOther = facetSeq.isPoint(); if (isPoint) { final double x = getX(0); final double y = getY(0); if (isPointOther) { final double x2 = facetSeq.getX(0); final double y2 = facetSeq.getY(0); return MathUtil.distance(x, x, x2, y2); } else { return PointFacetSequence.computePointLineDistance(x, y, facetSeq); } } else if (isPointOther) { final double x = facetSeq.getX(0); final double y = facetSeq.getY(0); return PointFacetSequence.computePointLineDistance(x, y, this); } else { return computeLineLineDistance(facetSeq); } } @Override public double getCoordinate(final int vertexIndex, final int axisIndex) { return this.line.getCoordinateFast(this.start + vertexIndex, axisIndex); } @Override public Point getPoint(final int index) { return this.line.getPoint(this.start + index); } @Override public int getVertexCount() { return this.vertexCount; } @Override public double getX(final int vertexIndex) { return this.line.getX(this.start + vertexIndex); } @Override public double getY(final int vertexIndex) { return this.line.getY(this.start + vertexIndex); } @Override public boolean isPoint() { return this.vertexCount == 1; } }