1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84
|
/////////////////////////////////////////////////////////////
// //
// Copyright (c) 2003-2011 by The University of Queensland //
// Earth Systems Science Computational Centre (ESSCC) //
// http://www.uq.edu.au/esscc //
// //
// Primary Business: Brisbane, Queensland, Australia //
// Licensed under the Open Software License version 3.0 //
// http://www.opensource.org/licenses/osl-3.0.php //
// //
/////////////////////////////////////////////////////////////
#include "LineSegment.h"
/*!
constructor
\param P0 1st end point
\param P1 2nd end point
\warning doesn't check P0!=P1
*/
LineSegment::LineSegment(const Vec3& P0,const Vec3& P1)
{
Pos=P0;
U=(P1-P0).unit();
N.X()=U.Y();
N.Y()=-U.X();
N.Z()=0.0;
m_len=(P1-P0).norm();
}
/*!
distance between a point and the line segment
\param P the position of the point
*/
double LineSegment::sep(const Vec3& P)
{
double res;
double du=(P-Pos)*U;
if((0<=du) && (du <=m_len)){// nearest point inside segment
res=fabs((P-Pos)*N);
} else { // nearest point outside -> get distance to closest endpoint
double d1=(P-Pos).norm();
double d2=(P-(Pos+m_len*U)).norm();
res = (d1<d2) ? d1 : d2;
}
return res;
}
/*!
returns if the connecting line between two points intersects the line segment
\param P1 1st point
\param P2 2nd point
*/
bool LineSegment::intersect(const Vec3& P1,const Vec3& P2)
{
bool res=false;
Vec3 U2=(P2-P1).unit();
// setup params
double x1=U.X();
double y1=U.Y();
double x2=U2.X();
double y2=U2.Y();
double c=P1.X()-Pos.X();
double d=P1.Y()-Pos.Y();
// solve EQS
double s=y2*x1-x2*y1;
if(s!=0.0){ // if s==0 -> parallel segments -> no intersection
double b=(c*y1-d*x1)/s;
double a=(c*y2-d*x2)/s;
res=((0<=a) && (a<=m_len) && (0<=b) && (b<=(P2-P1).norm()));
}
return res;
}
|