All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.opentripplanner.visibility.VLPoint Maven / Gradle / Ivy

package org.opentripplanner.visibility;

import java.lang.Math;

/**
 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
 */
public class VLPoint implements Comparable, Cloneable {

    public double x, y;

    public VLPoint() {
        x = Double.NaN;
        y = Double.NaN;
    }

    public VLPoint(double x, double y) {
        this.x = x;
        this.y = y;
    }

    public VLPoint(VLPoint p) {
        x = p.x;
        y = p.y;
    }

    public VLPoint projection_onto(LineSegment line_segment_temp) {

        if (line_segment_temp.size() == 1)
            return line_segment_temp.first();
        // The projection of point_temp onto the line determined by
        // line_segment_temp can be represented as an affine combination
        // expressed in the form projection of Point =
        // theta*line_segment_temp.first +
        // (1.0-theta)*line_segment_temp.second. if theta is outside
        // the interval [0,1], then one of the LineSegment's endpoints
        // must be closest to calling Point.
        double theta = ((line_segment_temp.second().x - x)
                * (line_segment_temp.second().x - line_segment_temp.first().x) + (line_segment_temp
                .second().y - y) * (line_segment_temp.second().y - line_segment_temp.first().y))
                / (Math.pow(line_segment_temp.second().x - line_segment_temp.first().x, 2) + Math
                        .pow(line_segment_temp.second().y - line_segment_temp.first().y, 2));
        // std::cout << "\E[1;37;40m" << "Theta is: " << theta << "\x1b[0m"
        // << std::endl;
        if ((0.0 <= theta) && (theta <= 1.0))
            return line_segment_temp.first().times(theta)
                    .plus(line_segment_temp.second().times(1.0 - theta));
        // Else pick closest endpoint.
        if (distance(line_segment_temp.first()) < distance(line_segment_temp.second()))
            return line_segment_temp.first();
        return line_segment_temp.second();
    }

    public VLPoint projection_onto(Ray ray_temp) {

        // Construct a LineSegment parallel with the Ray which is so long,
        // that the projection of the the calling Point onto that
        // LineSegment must be the same as the projection of the calling
        // Point onto the Ray.
        double R = distance(ray_temp.base_point());
        LineSegment seg_approx = new LineSegment(ray_temp.base_point(), ray_temp.base_point().plus(
                new VLPoint(R * Math.cos(ray_temp.bearing().get()), R
                        * Math.sin(ray_temp.bearing().get()))));
        return projection_onto(seg_approx);
    }

    public VLPoint projection_onto(Polyline polyline_temp) {

        VLPoint running_projection = polyline_temp.get(0);
        double running_min = distance(running_projection);
        VLPoint point_temp;
        for (int i = 0; i <= polyline_temp.size() - 1; i++) {
            point_temp = projection_onto(new LineSegment(polyline_temp.get(i),
                    polyline_temp.get(i + 1)));
            if (distance(point_temp) < running_min) {
                running_projection = point_temp;
                running_min = distance(running_projection);
            }
        }
        return running_projection;
    }

    public VLPoint projection_onto_vertices_of(VLPolygon polygon_temp) {
        VLPoint running_projection = polygon_temp.get(0);
        double running_min = distance(running_projection);
        for (int i = 1; i <= polygon_temp.n() - 1; i++) {
            if (distance(polygon_temp.get(i)) < running_min) {
                running_projection = polygon_temp.get(i);
                running_min = distance(running_projection);
            }
        }
        return running_projection;
    }

    public VLPoint projection_onto_vertices_of(Environment environment_temp) {
        VLPoint running_projection = projection_onto_vertices_of(environment_temp.outer_boundary);
        double running_min = distance(running_projection);
        VLPoint point_temp;
        for (int i = 0; i < environment_temp.h(); i++) {
            point_temp = projection_onto_vertices_of(environment_temp.holes.get(i));
            if (distance(point_temp) < running_min) {
                running_projection = point_temp;
                running_min = distance(running_projection);
            }
        }
        return running_projection;
    }

    public VLPoint projection_onto_boundary_of(VLPolygon polygon_temp) {

        VLPoint running_projection = polygon_temp.get(0);
        double running_min = distance(running_projection);
        VLPoint point_temp;
        for (int i = 0; i <= polygon_temp.n() - 1; i++) {
            point_temp = projection_onto(new LineSegment(polygon_temp.get(i),
                    polygon_temp.get(i + 1)));
            if (distance(point_temp) < running_min) {
                running_projection = point_temp;
                running_min = distance(running_projection);
            }
        }
        return running_projection;
    }

    public VLPoint projection_onto_boundary_of(Environment environment_temp) {

        VLPoint running_projection = projection_onto_boundary_of(environment_temp.outer_boundary);
        double running_min = distance(running_projection);
        VLPoint point_temp;
        for (int i = 0; i < environment_temp.h(); i++) {
            point_temp = projection_onto_boundary_of(environment_temp.holes.get(i));
            if (distance(point_temp) < running_min) {
                running_projection = point_temp;
                running_min = distance(running_projection);
            }
        }
        return running_projection;
    }

    public boolean on_boundary_of(VLPolygon polygon_temp, double epsilon) {

        if (distance(projection_onto_boundary_of(polygon_temp)) <= epsilon) {
            return true;
        }
        return false;
    }

    public boolean on_boundary_of(Environment environment_temp, double epsilon) {

        if (distance(projection_onto_boundary_of(environment_temp)) <= epsilon) {
            return true;
        }
        return false;
    }

    public boolean in(LineSegment line_segment_temp, double epsilon) {

        if (distance(line_segment_temp) < epsilon)
            return true;
        return false;
    }

    public boolean in_relative_interior_of(LineSegment line_segment_temp, double epsilon) {

        return in(line_segment_temp, epsilon) && distance(line_segment_temp.first()) > epsilon
                && distance(line_segment_temp.second()) > epsilon;
    }

    public void set_y(double y) {
        this.y = y;
    }

    public void set_x(double x) {
        this.x = x;
    }

    public boolean in(VLPolygon polygon_temp)

    {
        return in(polygon_temp, 0);
    }

    public boolean in(VLPolygon polygon_temp, double epsilon) {

        int n = polygon_temp.vertices.size();
        if (on_boundary_of(polygon_temp, epsilon))
            return true;
        // Then check the number of times a ray emanating from the Point
        // crosses the boundary of the Polygon. An odd number of
        // crossings indicates the Point is in the interior of the
        // Polygon. Based on
        // http://www.ecse.rpi.edu/Homepages/wrf/Research/Short_Notes/pnpoly.html

        boolean c = false;
        for (int i = 0, j = n - 1; i < n; j = i++) {
            if ((((polygon_temp.get(i).y <= y) && (y < polygon_temp.get(j).y)) || ((polygon_temp
                    .get(j).y <= y) && (y < polygon_temp.get(i).y)))
                    && (x < (polygon_temp.get(j).x - polygon_temp.get(i).x)
                            * (y - polygon_temp.get(i).y)
                            / (polygon_temp.get(j).y - polygon_temp.get(i).y)
                            + polygon_temp.get(i).x))
                c = !c;
        }
        return c;
    }

    public boolean in(Environment environment_temp, double epsilon) {
        // On outer boundary?
        if (on_boundary_of(environment_temp, epsilon))
            return true;
        // Not in outer boundary?
        if (!in(environment_temp.outer_boundary, epsilon))
            return false;
        // In hole?
        for (int i = 0; i < environment_temp.h(); i++)
            if (in(environment_temp.holes.get(i)))
                return false;
        // Must be in interior.
        return true;
    }

    public boolean is_endpoint_of(LineSegment line_segment_temp, double epsilon) {

        if (distance(line_segment_temp.first()) <= epsilon
                || distance(line_segment_temp.second()) <= epsilon)
            return true;
        return false;
    }

    // these mean that points are not immutable (aieee!) - DT

    public void snap_to_vertices_of(VLPolygon polygon_temp, double epsilon) {

        VLPoint point_temp = new VLPoint(projection_onto_vertices_of(polygon_temp));
        if (distance(point_temp) <= epsilon) {
            x = point_temp.x;
            y = point_temp.y;
        }
    }

    public void snap_to_vertices_of(Environment environment_temp, double epsilon) {

        VLPoint point_temp = new VLPoint(projection_onto_vertices_of(environment_temp));
        if (distance(point_temp) <= epsilon) {
            x = point_temp.x;
            y = point_temp.y;
        }
    }

    public void snap_to_boundary_of(VLPolygon polygon_temp, double epsilon) {

        VLPoint point_temp = new VLPoint(projection_onto_boundary_of(polygon_temp));
        if (distance(point_temp) <= epsilon) {
            x = point_temp.x;
            y = point_temp.y;
        }
    }

    public void snap_to_boundary_of(Environment environment_temp, double epsilon) {

        VLPoint point_temp = new VLPoint(projection_onto_boundary_of(environment_temp));
        {
            if (distance(point_temp) <= epsilon) {
                x = point_temp.x;
                y = point_temp.y;
            }
        }
    }

    public boolean equals(Object o) {
        if (!(o instanceof VLPoint)) {
            return false;
        }
        VLPoint point2 = (VLPoint) o;
        return x == point2.x && y == point2.y;
    }

    public int compareTo(VLPoint point2) {

        if (x < point2.x)
            return -1;
        else if (x == point2.x) {
            if (y < point2.y) {
                return -1;
            } else if (y == point2.y) {
                return 0;
            }
            return 1;
        }
        return 1;
    }

    public VLPoint plus(VLPoint point2) {
        return new VLPoint(x + point2.x, y + point2.y);
    }

    public VLPoint minus(VLPoint point2) {
        return new VLPoint(x - point2.x, y - point2.y);
    }

    public VLPoint times(VLPoint point2) {
        return new VLPoint(x * point2.x, y * point2.y);
    }

    public VLPoint times(double scalar) {
        return new VLPoint(scalar * x, scalar * y);
    }

    public double cross(VLPoint point2) {

        // The area of the parallelogram created by the Points viewed as vectors.
        return x * point2.y - point2.x * y;
    }

    public double distance(VLPoint point2) {
        return Math.sqrt(Math.pow(x - point2.x, 2) + Math.pow(y - point2.y, 2));
    }

    public double distance(LineSegment line_segment_temp) {
        return distance(projection_onto(line_segment_temp));
    }

    public double distance(Ray ray_temp) {
        return distance(projection_onto(ray_temp));
    }

    public double distance(Polyline polyline_temp) {

        double running_min = distance(polyline_temp.get(0));
        double distance_temp;
        for (int i = 0; i < polyline_temp.size() - 1; i++) {
            distance_temp = distance(new LineSegment(polyline_temp.get(i), polyline_temp.get(i + 1)));
            if (distance_temp < running_min)
                running_min = distance_temp;
        }
        return running_min;
    }

    public double boundary_distance(VLPolygon polygon_temp) {

        double running_min = distance(polygon_temp.get(0));
        double distance_temp;
        for (int i = 0; i <= polygon_temp.n(); i++) {
            distance_temp = distance(new LineSegment(polygon_temp.get(i), polygon_temp.get(i + 1)));
            if (distance_temp < running_min)
                running_min = distance_temp;
        }
        return running_min;
    }

    public double boundary_distance(Environment environment_temp) {
        double running_min = distance(environment_temp.get(0).get(0));
        double distance_temp;
        for (int i = 0; i <= environment_temp.h(); i++) {
            distance_temp = boundary_distance(environment_temp.get(i));
            if (distance_temp < running_min)
                running_min = distance_temp;
        }
        return running_min;
    }

    public String toString() {
        return "\n" + x + ", " + y;
    }

    public VLPoint clone() {
        return new VLPoint(x, y);
    }

    public int hashCode() {
        return new Double(x).hashCode() + new Double(y).hashCode();
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy