LibGfx: Add draw_triangle() for drawing filled triangles

This commit is contained in:
Stephan Unverwerth 2020-04-18 00:13:22 +02:00 committed by Andreas Kling
parent 2b7fc08db3
commit acd4676803
Notes: sideshowbarker 2024-07-19 07:31:21 +09:00
2 changed files with 69 additions and 0 deletions

View file

@ -330,6 +330,74 @@ void Painter::draw_bitmap(const Point& p, const GlyphBitmap& bitmap, Color color
}
}
void Painter::draw_triangle(const Point& a, const Point& b, const Point& c, Color color)
{
RGBA32 rgba = color.value();
Point p0(a);
Point p1(b);
Point p2(c);
if (p0.y() > p1.y())
swap(p0, p1);
if (p0.y() > p2.y())
swap(p0, p2);
if (p1.y() > p2.y())
swap(p1, p2);
auto clip = clip_rect();
if (p0.y() >= clip.bottom())
return;
if (p2.y() < clip.top())
return;
float dx01 = (float)(p1.x() - p0.x()) / (p1.y() - p0.y());
float dx02 = (float)(p2.x() - p0.x()) / (p2.y() - p0.y());
float dx12 = (float)(p2.x() - p1.x()) / (p2.y() - p1.y());
float x01 = p0.x();
float x02 = p0.x();
int top = p0.y();
if (top < clip.top()) {
x01 += dx01 * clip.top() - top;
x02 += dx02 * clip.top() - top;
top = clip.top();
}
for (int y = top; y < p1.y() && y < clip.bottom(); ++y) {
int start = x01 > x02 ? max((int)x02, clip.left()) : max((int)x01, clip.left());
int end = x01 > x02 ? min((int)x01, clip.right()) : min((int)x02, clip.right());
auto* scanline = m_target->scanline(y);
for (int x = start; x < end; x++) {
scanline[x] = rgba;
}
x01 += dx01;
x02 += dx02;
}
x02 = p0.x() + dx02 * (p1.y() - p0.y());
float x12 = p1.x();
top = p1.y();
if (top < clip.top()) {
x02 += dx02 * clip.top() - top;
x12 += dx12 * clip.top() - top;
top = clip.top();
}
for (int y = top; y < p2.y() && y < clip.bottom(); ++y) {
int start = x12 > x02 ? max((int)x02, clip.left()) : max((int)x12, clip.left());
int end = x12 > x02 ? min((int)x12, clip.right()) : min((int)x02, clip.right());
auto* scanline = m_target->scanline(y);
for (int x = start; x < end; x++) {
scanline[x] = rgba;
}
x02 += dx02;
x12 += dx12;
}
}
void Painter::blit_scaled(const Rect& dst_rect_raw, const Gfx::Bitmap& source, const Rect& src_rect, float hscale, float vscale)
{
auto dst_rect = Rect(dst_rect_raw.location(), dst_rect_raw.size()).translated(translation());

View file

@ -51,6 +51,7 @@ public:
void draw_rect(const Rect&, Color, bool rough = false);
void draw_bitmap(const Point&, const CharacterBitmap&, Color = Color());
void draw_bitmap(const Point&, const GlyphBitmap&, Color = Color());
void draw_triangle(const Point&, const Point&, const Point&, Color);
void draw_ellipse_intersecting(const Rect&, Color, int thickness = 1);
void set_pixel(const Point&, Color);
void draw_line(const Point&, const Point&, Color, int thickness = 1, bool dotted = false);