包括:二直線是否相交及交點、線段與直線是否相交、點通過直線的對稱點、點到直線的距離。
// RtLine.h: interface for the CRtLine class.
//
//////////////////////////////////////////////////////////////////////
#if !defined(AFX_RTLINE_H__7BD6B35E_17E9_4258_A70C_1099AA129DD6__INCLUDED_)
#define AFX_RTLINE_H__7BD6B35E_17E9_4258_A70C_1099AA129DD6__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#include "RtVector.h"
#include "RtPoint.h"
// a * x + b * y + c = 0
template<class T>
class CRtLine
{
public:
//constructor
CRtLine()
{}
CRtLine( const double a, const double b, const double c ): mvd_a( a ), mvd_b( b ), mvd_c( c )
{
}
CRtLine( CRtPoint<T>& start, CRtPoint<T>& stop )
{
setData( start, stop );
}
CRtLine( CRtVector<T>& vector )
{
setData( vector[0], vector[1] );
}
//copy constructor
CRtLine( const CRtLine& in)
{
mvd_a = in.mvd_a;
mvd_b = in.mvd_b;
mvd_c = in.mvd_c;
}
//desconstructor
virtual ~CRtLine()
{}
//operators overload:
//line Equality, epsilon used due to numerical imprecision
bool operator == ( const CRtLine& in )
{
return ( src0.mvd_a == src1.mvd_a ) && ( src0.mvd_b == src1.mvd_b ) && ( src0.mvd_c == src1.mvd_c );
}
//evaluate to line
const CRtLine& operator = (const CRtLine& in)
{
mvd_a = in.mvd_a;
mvd_b = in.mvd_b;
mvd_c = in.mvd_c;
return *this;
}
//the two straight lines intersect
bool Intersect( CRtLine& in, CRtPoint<double>& out );
//Intersects with the straight line segment
bool Intersect( CRtVector<T>& in, CRtPoint<double>& out );
//Point on a straight line symmetry point
CRtPoint<T> SymmetryPoint( CRtPoint<T>& in );
//Points to the straight line distance from
double DistancePoint( CRtPoint<T>& in , CRtPoint<double>& out);
private:
//Calculation of member variables
void setData( CRtPoint<T>& start, CRtPoint<T>& stop )
{
int sign = (mvd_a = stop[1] - start[1]) < 0 ? -1 : 1;
mvd_a *= sign;
mvd_b = sign * ( start[0] - stop[0] );
mvd_c = sign * ( start[1] * stop[0] - start[0] * stop[1] );
}
private:
double mvd_a;
double mvd_b;
double mvd_c;
};
//If the two straight lines intersect, return true, and return to the intersection of p
template<class T>
bool CRtLine<T>::Intersect( CRtLine& in, CRtPoint<double>& out )
{
double d = mvd_a * in.mvd_b - in.mvd_a * mvd_b;
if( fabs(d) < MINERR ) return false; //non-intersect
double data[2];
data[0] = ( in.mvd_c * mvd_b - mvd_c * in.mvd_b ) / d;
data[1] = ( in.mvd_a * mvd_c - mvd_a * in.mvd_c ) / d;
out.SetData(data);
return true;
}
//Intersects with the straight line segment
template<class T>
bool CRtLine<T>::Intersect( CRtVector<T>& in, CRtPoint<double>& out )
{
if( ( mvd_a * in[0][0] + mvd_b * in[0][1] + mvd_c ) * ( mvd_a * in[1][0] + mvd_b * in[1][1] + mvd_c ) > 0 )
return false;
return Intersect(CRtLine<T>(in),out);
}
//Point on a straight line symmetry point
template<class T>
CRtPoint<T> CRtLine<T>::SymmetryPoint( CRtPoint<T>& in )
{
T data[2];
data[0] = ( ( pow( mvd_b, 2 ) - pow( mvd_a, 2) ) * in[0] - 2 * mvd_a * mvd_b * in[1] - 2 * mvd_a * mvd_c )
/ ( pow( mvd_b, 2 ) + pow( mvd_a, 2));
data[1] = ( ( pow( mvd_b, 2 ) - pow( mvd_a, 2) ) * in[1] - 2 * mvd_a * mvd_b * in[0] - 2 * mvd_b * mvd_c )
/ ( pow( mvd_b, 2 ) + pow( mvd_a, 2));
return CRtPoint<T>(data);
}
/******************************************************************************
Points to the straight line distance from and return to the pedal of point
A straight line: Ax + By + C = 0 Dian (x0, y0) to the straight line "distance" as follows:
A * x0 + B * y0 + C
d = -------------------
A * A + B * B
This "distance" are symbols that point in a straight line at the top or the bottom, take the absolute value of said Euclidean distance.
Point (x0, y0) to the pedal line (x1, y1) to meet the
Ax1 + By1 + C = 0
(y0-y1) / (x0-x1) = B / A
Solution was:
B * B * x - A * B * y-AC
x1 = ------------------
A * A + B * B
-A * B + A * A * y - B * C
y1 = -------------------
A * A + B * B
======================================
Three-dimensional case: http://hi.baidu.com/irmosgarden/blog/item/25bfd433b097d946ad4b5f7b.html
*******************************************************************************/
template<class T>
double CRtLine<T>::DistancePoint( CRtPoint<T>& in , CRtPoint<double>& out)
{
double data[2];
data[0] = ( pow(mvd_b, 2) * in[0] - mvd_a * mvd_b * in[1] - mvd_a * mvd_c )
/( pow(mvd_a, 2) + pow(mvd_b, 2) );
data[1] = ( pow(mvd_a, 2) * in[1] - mvd_a * mvd_b * in[0] - mvd_b * mvd_c )
/( pow(mvd_a, 2) + pow(mvd_b, 2) );
out.SetData(data);
return ( mvd_a * in[0] + mvd_b * in[1] + mvd_c ) / ( pow(mvd_a, 2) + pow(mvd_b, 2) );
}
#endif // !defined(AFX_RTLINE_H__7BD6B35E_17E9_4258_A70C_1099AA129DD6__INCLUDED_)