Added Liang-Barsky Line Clipping

This commit is contained in:
Raphael Coeffic
2021-05-22 16:57:04 +02:00
parent e7b6fa412c
commit 67ede465aa
2 changed files with 96 additions and 1 deletions
+94 -1
View File
@@ -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);
+2
View File
@@ -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;