Brief description of class still missing. More...
#include <Segment.h>
Public Types | |
enum | RelativePosition { Skew, Crossing, Parallel, Aligned, Continuous, SmallOverlap, StrongOverlap } |
Public Member Functions | |
Point | directionVector () const |
QVector< Segment > | distanceTo (const Segment &seg, RelativePosition &relPos) const |
bool | includes (const Point &p, double precision=1e-10) const |
bool | intersects (const Segment &seg, Point &p) const |
bool | isSimilar (const Segment &o, double precision) const |
double | length () const |
bool | operator< (const Segment &o) const |
bool | parallelTo (const Segment &o) const |
Point | point (int index) const |
Segment () | |
Segment (const Point &p1, const Point &p2) | |
Segment (double x1, double y1, double z1, double x2, double y2, double z2) | |
Segment (const Segment &o) | |
void | set (const Point &p1, const Point &p2) |
void | set (double x1, double y1, double z1, double x2, double y2, double z2) |
Brief description of class still missing.
Full description of class still missing
QGpCoreTools::Segment::Segment | ( | ) | [inline] |
{}
QGpCoreTools::Segment::Segment | ( | const Point & | p1, |
const Point & | p2 | ||
) | [inline] |
{set(p1,p2);}
QGpCoreTools::Segment::Segment | ( | double | x1, |
double | y1, | ||
double | z1, | ||
double | x2, | ||
double | y2, | ||
double | z2 | ||
) | [inline] |
{set(x1, y1, z1,
x2, y2, z2);}
QGpCoreTools::Segment::Segment | ( | const Segment & | o | ) |
Point QGpCoreTools::Segment::directionVector | ( | ) | const |
References QGpCoreTools::Point::distanceTo(), and TRACE.
Referenced by parallelTo().
{ TRACE; Point p=_point[1]; p-=_point[0]; p/=Point().distanceTo(p); return p; }
QVector< Segment > QGpCoreTools::Segment::distanceTo | ( | const Segment & | seg, |
RelativePosition & | relPos | ||
) | const |
Based on http://geomalgorithms.com/a07-_distance.html
The length of the returned segment is the distance between the two segments. The end points are the closest points on the two segments.
relPos is set according relative position of segments:
Two segments are returned in the case of Parallel. They limit the overlapping range. In all other cases, a single segment is returned.
References Aligned, Continuous, Crossing, isSimilar(), QGpCoreTools::Point::isSimilar(), length(), Parallel, parallelTo(), QGpCoreTools::Point::scalarProduct(), Skew, SmallOverlap, StrongOverlap, and TRACE.
{ TRACE; QVector<Segment> res; Point u=_point[1]; u-=_point[0]; Point v=seg._point[1]; v-=seg._point[0]; Point w0=_point[0]; w0-=seg._point[0]; double a=u.scalarProduct(u); double b=u.scalarProduct(v); double c=v.scalarProduct(v); double d=u.scalarProduct(w0); double e=v.scalarProduct(w0); double denom=a*c-b*b; if(denom/(a*c)<1e-10) { // Parallel segments, negative value are theoretically impossible Segment s[4]; s[0]=linkSegment(0.0, d/b, _point[0], u, seg._point[0], v); s[1]=linkSegment(1.0, (a+d)/b, _point[0], u, seg._point[0], v); s[2]=linkSegment(-d/a, 0.0, _point[0], u, seg._point[0], v); s[3]=linkSegment((b-d)/a, 1.0, _point[0], u, seg._point[0], v); double minLength=INFINITY; for(int i=0; i<4; i++) { double l=s[i].length(); if(fabs(l-minLength)<1e-2) { res.append(s[i]); } else if(l<minLength) { minLength=l; res.clear(); res.append(s[i]); } } if(minLength<1e-10) { // Adjacent or Overlap if(_point[0].isSimilar(seg._point[0], 1e-2) || _point[0].isSimilar(seg._point[1], 1e-2) || _point[1].isSimilar(seg._point[0], 1e-2) || _point[1].isSimilar(seg._point[1], 1e-2)) { relPos=Continuous; } else { if(minLength<0.2*length() && minLength<0.2*seg.length()) { relPos=SmallOverlap; } else { relPos=StrongOverlap; } } } else { // Parallel or Aligned if(parallelTo(res.first())) { relPos=Aligned; } else { relPos=Parallel; qSort(res); for(int i=res.count()-1; i>0; i--) { if(res.at(i).isSimilar(res.at(i-1), 1e-2)) { res.remove(i); } } switch(res.count()) { case 0: ASSERT(false); break; case 1: relPos=Continuous; // Not really if considering only segments // Just means that there is no overlap break; case 2: break; default: ASSERT(false); break; } } } } else { denom=1.0/denom; Segment s=linkSegment((b*e-c*d)*denom, (a*e-b*d)*denom, _point[0], u, seg._point[0], v); if(s.length()<1e-10) { relPos=Crossing; } else { relPos=Skew; } res.append(s); } return res; }
bool QGpCoreTools::Segment::includes | ( | const Point & | p, |
double | precision = 1e-10 |
||
) | const |
Returns true if p is located on the segment (1e-10 precision)
References QGpCoreTools::Parallelepiped::includes(), TRACE, QGpCoreTools::Point2D::x(), QGpCoreTools::Point2D::y(), and QGpCoreTools::Point::z().
{ TRACE; if(!_limits.includes(p)) return false; Point u=_point[1]; u-=_point[0]; double k; if(u.x()!=0.0) { k=(p.x()-_point[0].x())/u.x(); if(fabs(p.y()-(k*u.y()+_point[0].y()))<precision && fabs(p.z()-(k*u.z()+_point[0].z()))<precision) { return true; } } if(u.y()!=0.0) { k=(p.y()-_point[0].y())/u.y(); if(fabs(p.x()-(k*u.x()+_point[0].x()))<precision && fabs(p.z()-(k*u.z()+_point[0].z()))<precision) { return true; } } if(u.z()!=0.0) { k=(p.z()-_point[0].z())/u.z(); if(fabs(p.x()-(k*u.x()+_point[0].x()))<precision && fabs(p.y()-(k*u.y()+_point[0].y()))<precision) { return true; } } return false; }
bool QGpCoreTools::Segment::intersects | ( | const Segment & | seg, |
Point & | p | ||
) | const |
Returns true if this segment intersects segment seg. The intersection point is returned in p.
References QGpCoreTools::Parallelepiped::includes(), TRACE, QGpCoreTools::Point2D::x(), QGpCoreTools::Point2D::y(), and QGpCoreTools::Point::z().
{ TRACE; Point u1=_point[1]; u1-=_point[0]; Point u2=seg._point[1]; u2-=seg._point[0]; double d, k; d=u2.x()*u1.y()-u2.y()*u1.x(); if(d!=0.0) { k=(u1.x()*(seg._point[0].y()-_point[0].y())-u1.y()*(seg._point[0].x()-_point[0].x()))/d; p=u2*k+seg._point[0]; } else { d=u2.x()*u1.z()-u2.z()*u1.x(); if(d!=0.0) { k=(u1.x()*(seg._point[0].z()-_point[0].z())-u1.z()*(seg._point[0].x()-_point[0].x()))/d; p=u2*k+seg._point[0]; } else { d=u2.y()*u1.z()-u2.z()*u1.y(); if(d!=0.0) { k=(u1.y()*(seg._point[0].z()-_point[0].z())-u1.z()*(seg._point[0].y()-_point[0].y()))/d; p=u2*k+seg._point[0]; } else { return false; } } } if(_limits.includes(p) && seg._limits.includes(p)) return true; else return false; }
bool QGpCoreTools::Segment::isSimilar | ( | const Segment & | o, |
double | precision | ||
) | const |
References QGpCoreTools::Point::isSimilar().
Referenced by distanceTo().
double QGpCoreTools::Segment::length | ( | ) | const [inline] |
Referenced by distanceTo().
{return _point[0].distanceTo(_point[1]);}
bool QGpCoreTools::Segment::operator< | ( | const Segment & | o | ) | const |
{ if(_point[0]<o._point[0]) { return true; } else if(_point[0]>o._point[0]) { return false; } else { return _point[1]<o._point[1]; } }
bool QGpCoreTools::Segment::parallelTo | ( | const Segment & | o | ) | const |
References directionVector(), and QGpCoreTools::Point::isSimilar().
Referenced by distanceTo().
{ Point u=directionVector(); Point v=o.directionVector(); return u.isSimilar(v, 1e-5) || u.isSimilar(v*-1, 1e-5); }
Point QGpCoreTools::Segment::point | ( | int | index | ) | const [inline] |
Referenced by QGpCoreTools::Matrix4x4::operator*().
{return _point[index];}
void QGpCoreTools::Segment::set | ( | const Point & | p1, |
const Point & | p2 | ||
) |
void QGpCoreTools::Segment::set | ( | double | x1, |
double | y1, | ||
double | z1, | ||
double | x2, | ||
double | y2, | ||
double | z2 | ||
) |
References QGpCoreTools::Parallelepiped::setLimits(), and TRACE.