Added Liang-Barsky Line Clipping
This commit is contained in:
+94
-1
@@ -331,7 +331,97 @@ void BitmapBuffer::drawVerticalLine(coord_t x, coord_t y, coord_t h, uint8_t pat
|
||||
}
|
||||
}
|
||||
|
||||
void BitmapBuffer::drawLine(coord_t x1, coord_t y1, coord_t x2, coord_t y2, uint8_t pat, LcdFlags flags)
|
||||
//
|
||||
// Liang-barsky clipping algo
|
||||
//
|
||||
static float lb_max(float arr[], int n)
|
||||
{
|
||||
float m = 0;
|
||||
for (int i = 0; i < n; ++i)
|
||||
if (m < arr[i]) m = arr[i];
|
||||
return m;
|
||||
}
|
||||
|
||||
// this function gives the minimum
|
||||
static float lb_min(float arr[], int n)
|
||||
{
|
||||
float m = 1;
|
||||
for (int i = 0; i < n; ++i)
|
||||
if (m > arr[i]) m = arr[i];
|
||||
return m;
|
||||
}
|
||||
|
||||
bool BitmapBuffer::liangBarskyClipper(coord_t& x1, coord_t& y1, coord_t& x2, coord_t& y2)
|
||||
{
|
||||
// defining variables
|
||||
float p1 = -(x2 - x1);
|
||||
float p2 = -p1;
|
||||
float p3 = -(y2 - y1);
|
||||
float p4 = -p3;
|
||||
|
||||
float q1 = x1 - xmin;
|
||||
float q2 = xmax - x1;
|
||||
float q3 = y1 - ymin;
|
||||
float q4 = ymax - y1;
|
||||
|
||||
float posarr[5], negarr[5];
|
||||
int posind = 1, negind = 1;
|
||||
posarr[0] = 1;
|
||||
negarr[0] = 0;
|
||||
|
||||
if ((p1 == 0 && q1 < 0) || (p2 == 0 && q2 < 0) || (p3 == 0 && q3 < 0) ||
|
||||
(p4 == 0 && q4 < 0)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (p1 != 0) {
|
||||
float r1 = q1 / p1;
|
||||
float r2 = q2 / p2;
|
||||
if (p1 < 0) {
|
||||
negarr[negind++] = r1; // for negative p1, add it to negative array
|
||||
posarr[posind++] = r2; // and add p2 to positive array
|
||||
} else {
|
||||
negarr[negind++] = r2;
|
||||
posarr[posind++] = r1;
|
||||
}
|
||||
}
|
||||
if (p3 != 0) {
|
||||
float r3 = q3 / p3;
|
||||
float r4 = q4 / p4;
|
||||
if (p3 < 0) {
|
||||
negarr[negind++] = r3;
|
||||
posarr[posind++] = r4;
|
||||
} else {
|
||||
negarr[negind++] = r4;
|
||||
posarr[posind++] = r3;
|
||||
}
|
||||
}
|
||||
|
||||
float xn1, yn1, xn2, yn2;
|
||||
float rn1, rn2;
|
||||
rn1 = lb_max(negarr, negind); // maximum of negative array
|
||||
rn2 = lb_min(posarr, posind); // minimum of positive array
|
||||
|
||||
if (rn1 > rn2) { // reject
|
||||
return false;
|
||||
}
|
||||
|
||||
xn1 = x1 + p2 * rn1;
|
||||
yn1 = y1 + p4 * rn1; // computing new points
|
||||
|
||||
xn2 = x1 + p2 * rn2;
|
||||
yn2 = y1 + p4 * rn2;
|
||||
|
||||
x1 = coord_t(xn1);
|
||||
y1 = coord_t(yn1);
|
||||
x2 = coord_t(xn2);
|
||||
y2 = coord_t(yn2);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void BitmapBuffer::drawLine(coord_t x1, coord_t y1, coord_t x2, coord_t y2,
|
||||
uint8_t pat, LcdFlags flags)
|
||||
{
|
||||
// Offsets
|
||||
x1 += offsetX;
|
||||
@@ -339,6 +429,9 @@ void BitmapBuffer::drawLine(coord_t x1, coord_t y1, coord_t x2, coord_t y2, uint
|
||||
x2 += offsetX;
|
||||
y2 += offsetY;
|
||||
|
||||
if (!liangBarskyClipper(x1, y1, x2, y2))
|
||||
return;
|
||||
|
||||
// No 'opacity' here, only 'color'
|
||||
pixel_t color = COLOR_VAL(flags);
|
||||
|
||||
|
||||
@@ -426,6 +426,8 @@ class BitmapBuffer: public BitmapBufferBase<pixel_t>
|
||||
}
|
||||
|
||||
void drawHorizontalLineAbs(coord_t x, coord_t y, coord_t w, uint8_t pat, LcdFlags flags, uint8_t opacity);
|
||||
|
||||
bool liangBarskyClipper(coord_t& x1, coord_t& y1, coord_t& x2, coord_t& y2);
|
||||
};
|
||||
|
||||
extern BitmapBuffer * lcd;
|
||||
|
||||
Reference in New Issue
Block a user