// Catalano Math Library
// The Catalano Framework
//
// Copyright © Diego Catalano, 2012-2016
// diego.catalano at live.com
//
// Copyright © Andrew Kirillov, 2005-2009
// andrew.kirillov@aforgenet.com
//
// 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
//
package Catalano.Math.Geometry;
import Catalano.Core.FloatPoint;
import Catalano.Core.IntPoint;
/**
*
* @author Diego Catalano
*/
public class Line {
private float k,b;
public Line(IntPoint start, IntPoint end) {
if (start.equals(end)) {
try {
throw new Exception("Start point of the line cannot be the same as its end point.");
} catch (Exception e) {
e.printStackTrace();
}
}
float d = end.x - start.x;
//d = d == 0 ? Float.POSITIVE_INFINITY : d;
k = ( end.y - start.y ) / d;
b = Float.isInfinite(k) ? start.x : start.y - k * start.x;
}
public Line(float slope, float intercept) {
this.k = slope;
this.b = intercept;
}
private Line( float radius, float theta, boolean unused ){
theta *= (float) ( Math.PI / 180 );
float sine = (float) Math.sin( theta ), cosine = (float) Math.cos( theta );
FloatPoint pt1 = new FloatPoint( radius * cosine, radius * sine );
// -1/tan, to get the slope of the line, and not the slope of the normal
k = -cosine / sine;
if ( !Float.isInfinite( k ) )
{
b = pt1.y - k * pt1.x;
}
else
{
b = Math.abs( radius );
}
}
private Line( IntPoint point, float theta ){
theta *= (float) ( Math.PI / 180 );
k = (float) ( -1.0f / Math.tan( theta ) );
if ( !Float.isInfinite( k ) )
{
b = point.y - k * point.x;
}
else
{
b = point.x;
}
}
public boolean isVertical(){
return Float.isInfinite(k);
}
public boolean isHorizontal(){
return k == 0;
}
public float getSlope(){
return k;
}
public float getIntercept(){
return b;
}
public static Line FromPoints(IntPoint p1, IntPoint p2){
return new Line(p1, p2);
}
public static Line FromSlopeIntercept(float slope, float intercept){
return new Line(slope, intercept);
}
public static Line FromRTheta(float radius, float theta){
return new Line(radius, theta, false);
}
public static Line FromPointTheta(IntPoint p, float theta){
return new Line(p, theta);
}
public float GetAngleBetweenLines( Line secondLine ){
float k2 = secondLine.k;
boolean isVertical1 = isVertical();
boolean isVertical2 = secondLine.isVertical();
// check if lines are parallel
if ( ( k == k2 ) || ( isVertical1 && isVertical2 ) )
return 0;
float angle = 0;
if ( ( !isVertical1 ) && ( !isVertical2 ) ){
float tanPhi = ( ( k2 > k ) ? ( k2 - k ) : ( k - k2 ) ) / ( 1 + k * k2 );
angle = (float) Math.atan( tanPhi );
}
else{
// one of the lines is parallel to Y axis
if ( isVertical1 ){
angle = (float) ( Math.PI / 2 - Math.atan( k2 ) * Math.signum( k2 ) );
}
else{
angle = (float) ( Math.PI / 2 - Math.atan( k ) * Math.signum( k ) );
}
}
// convert radians to degrees
angle *= (float) ( 180.0 / Math.PI );
if ( angle < 0 ){
angle = -angle;
}
return angle;
}
public float DistanceToPoint( IntPoint point ){
float distance;
if ( !isVertical() )
{
float div = (float) Math.sqrt( k * k + 1 );
distance = Math.abs( ( k * point.x + b - point.y ) / div );
}
else
{
distance = Math.abs( b - point.x );
}
return distance;
}
}
Ads help maintain this website.