/** Ported by David Turner from Visilibity, by Karl J. Obermeyer This port undoubtedly introduced a number of bugs (and removed some features). Bug reports should be directed to the OpenTripPlanner project, unless they can be reproduced in the original VisiLibity. This program 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 3 of the License, or (at your option) any later version. This program 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 program. If not, see <http://www.gnu.org/licenses/>. */ package org.opentripplanner.visibility; import java.util.ArrayList; import java.util.Collections; class Polyline { ArrayList<VLPoint> vertices = new ArrayList<VLPoint>(); VLPoint get(int i) { return vertices.get(i); } int size() { return vertices.size(); } double distance(VLPoint point_temp) { return point_temp.distance(this); } double length() { double length_temp = 0; for (int i = 1; i <= vertices.size() - 1; i++) length_temp += vertices.get(i - 1).distance(vertices.get(i)); return length_temp; } double diameter() { // Precondition: nonempty Polyline. assert (size() > 0); double running_max = 0; for (int i = 0; i < size() - 1; i++) { for (int j = i + 1; j < size(); j++) { if (get(i).distance(get(j)) > running_max) running_max = get(i).distance(get(j)); } } return running_max; } BoundingBox bbox() { // Precondition: nonempty Polyline. assert (vertices.size() > 0); BoundingBox bounding_box = new BoundingBox(); double x_min = vertices.get(0).x, x_max = vertices.get(0).x, y_min = vertices.get(0).y, y_max = vertices .get(0).y; for (int i = 1; i < vertices.size(); i++) { if (x_min > vertices.get(i).x) { x_min = vertices.get(i).x; } if (x_max < vertices.get(i).x) { x_max = vertices.get(i).x; } if (y_min > vertices.get(i).y) { y_min = vertices.get(i).y; } if (y_max < vertices.get(i).y) { y_max = vertices.get(i).y; } } bounding_box.x_min = x_min; bounding_box.x_max = x_max; bounding_box.y_min = y_min; bounding_box.y_max = y_max; return bounding_box; } void eliminate_redundant_vertices(double epsilon) { // Trivial case if (vertices.size() < 3) return; // Store new minimal length list of vertices ArrayList<VLPoint> vertices_temp = new ArrayList<VLPoint>(vertices.size()); // Place holders int first = 0; int second = 1; int third = 2; // Add first vertex vertices_temp.add(get(first)); while (third < vertices.size()) { // if second redundant if (new LineSegment(get(first), get(third)).distance(get(second)) <= epsilon) { // =>skip it second = third; third++; } // else second not redundant else { // =>add it. vertices_temp.add(get(second)); first = second; second = third; third++; } } // Add last vertex vertices_temp.add(vertices.get(vertices.size() - 1)); // Update list of vertices vertices = vertices_temp; } void reverse() { Collections.reverse(vertices); } public String toString() { String outs = ""; for (int i = 0; i < size(); i++) outs += get(i) + "\n"; return outs; } void append(Polyline polyline) { vertices.ensureCapacity(vertices.size() + polyline.vertices.size()); for (int i = 0; i < polyline.vertices.size(); i++) { vertices.add(polyline.vertices.get(i)); } } }