Linkgraph GUI: Replace line visibility detection algorithm

Previous algorithm had excessive false-positive rate
pull/59/head
Jonathan G Rennison 6 years ago
parent 29470dba23
commit 560a049316

@ -166,12 +166,64 @@ inline bool LinkGraphOverlay::IsPointVisible(Point pt, const DrawPixelInfo *dpi,
*/
inline bool LinkGraphOverlay::IsLinkVisible(Point pta, Point ptb, const DrawPixelInfo *dpi, int padding) const
{
return !((pta.x < dpi->left - padding && ptb.x < dpi->left - padding) ||
(pta.y < dpi->top - padding && ptb.y < dpi->top - padding) ||
(pta.x > dpi->left + dpi->width + padding &&
ptb.x > dpi->left + dpi->width + padding) ||
(pta.y > dpi->top + dpi->height + padding &&
ptb.y > dpi->top + dpi->height + padding));
const int left = dpi->left - padding;
const int right = dpi->left + dpi->width + padding;
const int top = dpi->top - padding;
const int bottom = dpi->top + dpi->height + padding;
// Cut-down CohenSutherland algorithm
const unsigned char INSIDE = 0; // 0000
const unsigned char LEFT = 1; // 0001
const unsigned char RIGHT = 2; // 0010
const unsigned char BOTTOM = 4; // 0100
const unsigned char TOP = 8; // 1000
int x0 = pta.x;
int y0 = pta.y;
int x1 = ptb.x;
int y1 = ptb.y;
auto out_code = [&](int x, int y) -> unsigned char {
unsigned char out = INSIDE;
if (x < left) {
out |= LEFT;
} else if (x > right) {
out |= RIGHT;
}
if (y < top) {
out |= TOP;
} else if (y > bottom) {
out |= BOTTOM;
}
return out;
};
unsigned char c0 = out_code(x0, y0);
unsigned char c1 = out_code(x1, y1);
while (true) {
if (c0 == 0 || c1 == 0) return true;
if ((c0 & c1) != 0) return false;
if (c0 & TOP) { // point 0 is above the clip window
x0 = x0 + (int)(((int64) (x1 - x0)) * ((int64) (top - y0)) / ((int64) (y1 - y0)));
y0 = top;
} else if (c0 & BOTTOM) { // point 0 is below the clip window
x0 = x0 + (int)(((int64) (x1 - x0)) * ((int64) (bottom - y0)) / ((int64) (y1 - y0)));
y0 = bottom;
} else if (c0 & RIGHT) { // point 0 is to the right of clip window
y0 = y0 + (int)(((int64) (y1 - y0)) * ((int64) (right - x0)) / ((int64) (x1 - x0)));
x0 = right;
} else if (c0 & LEFT) { // point 0 is to the left of clip window
y0 = y0 + (int)(((int64) (y1 - y0)) * ((int64) (left - x0)) / ((int64) (x1 - x0)));
x0 = left;
}
c0 = out_code(x0, y0);
}
NOT_REACHED();
}
/**

Loading…
Cancel
Save