|
|
4df9cd |
|
|
|
4df9cd |
|
|
|
d5090c |
#include <tools assistants="" guidelineline.h=""></tools>
|
|
|
4df9cd |
|
|
|
4df9cd |
// TnzCore includes
|
|
|
4df9cd |
#include "tgl.h"
|
|
|
4df9cd |
|
|
|
4df9cd |
|
|
|
4df9cd |
//*****************************************************************************************
|
|
|
4df9cd |
// TGuidelineLineBase implementation
|
|
|
4df9cd |
//*****************************************************************************************
|
|
|
4df9cd |
|
|
|
8074a5 |
TGuidelineLineBase::TGuidelineLineBase(bool enabled, double magnetism, const TPointD &p0, const TPointD &p1):
|
|
|
8074a5 |
TGuideline(enabled, magnetism), p0(p0), p1(p1) { }
|
|
|
4df9cd |
|
|
|
4df9cd |
TPointD
|
|
|
4df9cd |
TGuidelineLineBase::calcDirection(const TPointD &p0, const TPointD &p1) {
|
|
|
4df9cd |
TPointD d = p1 - p0;
|
|
|
4df9cd |
double k = norm2(d);
|
|
|
362052 |
return k > TConsts::epsilon*TConsts::epsilon ? d*(1.0/sqrt(k)) : TPointD();
|
|
|
4df9cd |
}
|
|
|
4df9cd |
|
|
|
c7854d |
|
|
|
c7854d |
static bool
|
|
|
3f8ca2 |
fitX(double &x0, double &y0, double &x1, double &y1, double minx, double maxx) {
|
|
|
c7854d |
double dx = x1 - x0;
|
|
|
c7854d |
if (fabs(dx) < TConsts::epsilon) return false;
|
|
|
c7854d |
double k = (y1 - y0)/dx;
|
|
|
c7854d |
if (dx > 0.0) {
|
|
|
c7854d |
y0 += k*(minx - x0); x0 = minx;
|
|
|
c7854d |
y1 += k*(maxx - x1); x1 = maxx;
|
|
|
c7854d |
} else {
|
|
|
c7854d |
y0 += k*(maxx - x0); x0 = maxx;
|
|
|
c7854d |
y1 += k*(minx - x1); x1 = minx;
|
|
|
c7854d |
}
|
|
|
c7854d |
return true;
|
|
|
c7854d |
}
|
|
|
c7854d |
|
|
|
3f8ca2 |
static bool
|
|
|
3f8ca2 |
truncateX(double &x0, double &y0, double &x1, double &y1, double minx, double maxx) {
|
|
|
3f8ca2 |
if (x0 <= minx && x1 <= minx) return false;
|
|
|
3f8ca2 |
if (x0 >= maxx && x1 >= maxx) return false;
|
|
|
3f8ca2 |
double dx = x1 - x0;
|
|
|
3f8ca2 |
if (fabs(dx) < TConsts::epsilon) return true;
|
|
|
3f8ca2 |
double k = (y1 - y0)/dx;
|
|
|
3f8ca2 |
if (dx > 0.0) {
|
|
|
3f8ca2 |
if (x0 < minx) { y0 += k*(minx - x0); x0 = minx; }
|
|
|
3f8ca2 |
if (x1 > maxx) { y1 += k*(maxx - x1); x1 = maxx; }
|
|
|
3f8ca2 |
} else {
|
|
|
3f8ca2 |
if (x0 > maxx) { y0 += k*(maxx - x0); x0 = maxx; }
|
|
|
3f8ca2 |
if (x1 < minx) { y1 += k*(minx - x1); x1 = minx; }
|
|
|
3f8ca2 |
}
|
|
|
3f8ca2 |
return true;
|
|
|
3f8ca2 |
}
|
|
|
3f8ca2 |
|
|
|
c7854d |
bool
|
|
|
4df9cd |
TGuidelineLineBase::truncateInfiniteLine(const TRectD &bounds, TPointD &p0, TPointD &p1) {
|
|
|
c7854d |
if (bounds.isEmpty()) return false;
|
|
|
4df9cd |
TPointD d = p0 - p1;
|
|
|
4df9cd |
TDimensionD size = bounds.getSize();
|
|
|
7c7225 |
if (fabs(d.x)*size.ly > fabs(d.y)*size.lx) {
|
|
|
4df9cd |
// horizontal
|
|
|
3f8ca2 |
if (!fitX (p0.x, p0.y, p1.x, p1.y, bounds.x0, bounds.x1)) return false;
|
|
|
3f8ca2 |
if (!truncateX(p0.y, p0.x, p1.y, p1.x, bounds.y0, bounds.y1)) return false;
|
|
|
4df9cd |
} else {
|
|
|
4df9cd |
// vertical
|
|
|
3f8ca2 |
if (!fitX (p0.y, p0.x, p1.y, p1.x, bounds.y0, bounds.y1)) return false;
|
|
|
3f8ca2 |
if (!truncateX(p0.x, p0.y, p1.x, p1.y, bounds.x0, bounds.x1)) return false;
|
|
|
c7854d |
}
|
|
|
c7854d |
return true;
|
|
|
c7854d |
}
|
|
|
c7854d |
|
|
|
c7854d |
bool
|
|
|
7c7225 |
TGuidelineLineBase::truncateRay(const TRectD &bounds, TPointD &p0, TPointD &p1) {
|
|
|
c7854d |
if (bounds.isEmpty()) return false;
|
|
|
7c7225 |
|
|
|
f278a5 |
// restrict bounds by p0
|
|
|
f278a5 |
// slightly expand this restriction to include vert and hor rays
|
|
|
f278a5 |
TRectD b(bounds);
|
|
|
f278a5 |
if (p0.x <= p1.x) { if (b.x0 < p0.x - TConsts::epsilon) b.x0 = p0.x - TConsts::epsilon; }
|
|
|
f278a5 |
else { if (b.x1 > p0.x + TConsts::epsilon) b.x1 = p0.x + TConsts::epsilon; }
|
|
|
f278a5 |
if (p0.y <= p1.y) { if (b.y0 < p0.y - TConsts::epsilon) b.y0 = p0.y - TConsts::epsilon; }
|
|
|
f278a5 |
else { if (b.y1 > p0.y + TConsts::epsilon) b.y1 = p0.y + TConsts::epsilon; }
|
|
|
7c7225 |
|
|
|
7c7225 |
if (b.isEmpty()) return false;
|
|
|
7c7225 |
return truncateInfiniteLine(b, p0, p1);
|
|
|
7c7225 |
}
|
|
|
7c7225 |
|
|
|
7c7225 |
bool
|
|
|
7c7225 |
TGuidelineLineBase::truncateLine(const TRectD &bounds, TPointD &p0, TPointD &p1) {
|
|
|
f278a5 |
// restrict bounds by p0 and p1
|
|
|
f278a5 |
// slightly expand this restriction to include vert and hor lines
|
|
|
f278a5 |
TRectD b( std::min(p0.x, p1.x) - TConsts::epsilon,
|
|
|
f278a5 |
std::min(p0.y, p1.y) - TConsts::epsilon,
|
|
|
f278a5 |
std::max(p0.x, p1.x) + TConsts::epsilon,
|
|
|
f278a5 |
std::max(p0.y, p1.y) + TConsts::epsilon );
|
|
|
f278a5 |
b *= bounds;
|
|
|
3f8ca2 |
if (b.isEmpty()) return false;
|
|
|
c7854d |
return truncateInfiniteLine(b, p0, p1);
|
|
|
4df9cd |
}
|
|
|
4df9cd |
|
|
|
4df9cd |
void
|
|
|
7c7225 |
TGuidelineLineBase::drawLine(const TPointD &p0, const TPointD &p1, bool restrict0, bool restrict1, bool active, bool enabled) const {
|
|
|
249386 |
TAffine4 modelview, projection;
|
|
|
4df9cd |
glGetDoublev(GL_MODELVIEW_MATRIX, modelview.a);
|
|
|
249386 |
glGetDoublev(GL_PROJECTION_MATRIX, projection.a);
|
|
|
4df9cd |
|
|
|
249386 |
TAffine matrix = (projection*modelview).get2d();
|
|
|
4df9cd |
TPointD pp0 = matrix*p0;
|
|
|
4df9cd |
TPointD pp1 = matrix*p1;
|
|
|
7c7225 |
const TRectD oneBox(-1.0, -1.0, 1.0, 1.0);
|
|
|
7c7225 |
if ( restrict0 && restrict1 ? !truncateLine(oneBox, pp0, pp1)
|
|
|
7c7225 |
: restrict0 ? !truncateRay (oneBox, pp0, pp1)
|
|
|
7c7225 |
: restrict1 ? !truncateRay (oneBox, pp1, pp0) // pp1 first
|
|
|
7c7225 |
: !truncateInfiniteLine(oneBox, pp0, pp1) ) return;
|
|
|
4df9cd |
|
|
|
249386 |
double pixelSize = sqrt(tglGetPixelSize2());
|
|
|
4df9cd |
TAffine matrixInv = matrix.inv();
|
|
|
c7854d |
drawSegment(matrixInv*pp0, matrixInv*pp1, pixelSize, active, enabled);
|
|
|
4df9cd |
}
|
|
|
4df9cd |
|
|
|
4df9cd |
|
|
|
4df9cd |
//*****************************************************************************************
|
|
|
4df9cd |
// TGuidelineLine implementation
|
|
|
4df9cd |
//*****************************************************************************************
|
|
|
4df9cd |
|
|
|
8074a5 |
TGuidelineLine::TGuidelineLine(bool enabled, double magnetism, const TPointD &p0, const TPointD &p1):
|
|
|
8074a5 |
TGuidelineLineBase(enabled, magnetism, p0, p1),
|
|
|
4df9cd |
dir(calcDirection(p0, p1)),
|
|
|
4df9cd |
dist(norm(p1 - p0)) { }
|
|
|
4df9cd |
|
|
|
4df9cd |
TTrackPoint
|
|
|
4df9cd |
TGuidelineLine::transformPoint(const TTrackPoint &point) const {
|
|
|
4df9cd |
TTrackPoint p(point);
|
|
|
4df9cd |
p.position = p0 + dir * std::max(0.0, std::min(dist, ((p.position - p0)*dir)));
|
|
|
4df9cd |
return p;
|
|
|
4df9cd |
}
|
|
|
4df9cd |
|
|
|
4df9cd |
void
|
|
|
8074a5 |
TGuidelineLine::draw(bool active, bool enabled) const
|
|
|
7c7225 |
{ drawLine(p0, p1, true, true, active, enabled); }
|
|
|
4df9cd |
|
|
|
4df9cd |
|
|
|
4df9cd |
//*****************************************************************************************
|
|
|
4df9cd |
// TGuidelineInfiniteLine implementation
|
|
|
4df9cd |
//*****************************************************************************************
|
|
|
4df9cd |
|
|
|
8074a5 |
TGuidelineInfiniteLine::TGuidelineInfiniteLine(bool enabled, double magnetism, const TPointD &p0, const TPointD &p1):
|
|
|
8074a5 |
TGuidelineLineBase(enabled, magnetism, p0, p1),
|
|
|
4df9cd |
dir(calcDirection(p0, p1)) { }
|
|
|
4df9cd |
|
|
|
4df9cd |
TTrackPoint
|
|
|
4df9cd |
TGuidelineInfiniteLine::transformPoint(const TTrackPoint &point) const {
|
|
|
4df9cd |
TTrackPoint p(point);
|
|
|
4df9cd |
p.position = p0 + dir * ((p.position - p0)*dir);
|
|
|
4df9cd |
return p;
|
|
|
4df9cd |
}
|
|
|
4df9cd |
|
|
|
4df9cd |
void
|
|
|
8074a5 |
TGuidelineInfiniteLine::draw(bool active, bool enabled) const
|
|
|
7c7225 |
{ drawLine(p0, p1, false, false, active, enabled); }
|
|
|
4df9cd |
|
|
|
4df9cd |
|
|
|
4df9cd |
//*****************************************************************************************
|
|
|
4df9cd |
// TGuidelineRay implementation
|
|
|
4df9cd |
//*****************************************************************************************
|
|
|
4df9cd |
|
|
|
8074a5 |
TGuidelineRay::TGuidelineRay(bool enabled, double magnetism, const TPointD &p0, const TPointD &p1):
|
|
|
8074a5 |
TGuidelineLineBase(enabled, magnetism, p0, p1),
|
|
|
4df9cd |
dir(calcDirection(p0, p1)) { }
|
|
|
4df9cd |
|
|
|
4df9cd |
TTrackPoint
|
|
|
4df9cd |
TGuidelineRay::transformPoint(const TTrackPoint &point) const {
|
|
|
4df9cd |
TTrackPoint p(point);
|
|
|
4df9cd |
p.position = p0 + dir * std::max(0.0, ((p.position - p0)*dir));
|
|
|
4df9cd |
return p;
|
|
|
4df9cd |
}
|
|
|
4df9cd |
|
|
|
4df9cd |
void
|
|
|
8074a5 |
TGuidelineRay::draw(bool active, bool enabled) const
|
|
|
7c7225 |
{ drawLine(p0, p1, true, false, active, enabled); }
|
|
|
4df9cd |
|