/**
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;
class Ray {
private Angle bearing;
private VLPoint base_point;
public double distance(VLPoint point_temp)
{
return point_temp.distance(
point_temp.projection_onto(this) );
}
public Angle bearing() {
return bearing;
}
public VLPoint base_point() {
return base_point;
}
public Ray(VLPoint base_point_temp, VLPoint bearing_point)
{
assert( !( base_point_temp.equals(bearing_point) ) );
base_point = base_point_temp;
bearing = new Angle( bearing_point.y-base_point_temp.y,
bearing_point.x-base_point_temp.x );
}
public Ray(VLPoint base_point_temp, Angle bearing_temp) {
base_point = base_point_temp;
bearing = bearing_temp;
}
public boolean equals(Object o)
{
if (!(o instanceof Ray)) {
return false;
}
Ray ray2 = (Ray) o;
if( base_point().equals( ray2.base_point)
&& bearing().equals(ray2.bearing ))
return true;
else
return false;
}
LineSegment intersection( LineSegment line_segment_temp,
double epsilon)
{
//First construct a LineSegment parallel with the Ray which is so
//long, that its intersection with line_segment_temp will be
//equal to the intersection of this with line_segment_temp.
double R = base_point().distance( line_segment_temp)
+ line_segment_temp.length();
LineSegment seg_approx =
new LineSegment( base_point, base_point.plus(
new VLPoint( R*Math.cos(bearing.get()),
R*Math.sin(bearing.get()) )) );
LineSegment intersect_seg = line_segment_temp.intersection(
seg_approx,
epsilon);
//Make sure point closer to ray_temp's base_point is listed first.
if( intersect_seg.size() == 2
&& intersect_seg.first().distance( base_point() ) >
intersect_seg.second().distance( base_point() ) ){
intersect_seg.reverse();
}
return intersect_seg;
}
}