From c1a0f17d5272255456af4be4e0aa5a7e697fcf11 Mon Sep 17 00:00:00 2001 From: rodri Date: Fri, 3 May 2024 15:29:15 +0000 Subject: clip: fix rectclipline. mixed up CLIP[TB] and the slope was being computed as an integer division, which caused artifacts. --- clip.c | 17 ++++++++++------- internal.h | 2 +- render.c | 3 ++- 3 files changed, 13 insertions(+), 9 deletions(-) diff --git a/clip.c b/clip.c index 82b15ea..18019fc 100644 --- a/clip.c +++ b/clip.c @@ -179,22 +179,25 @@ outcode(Point p, Rectangle r) /* * Cohen-Sutherland rectangle-line clipping */ -void +int rectclipline(Rectangle r, Point *p0, Point *p1) { int code0, code1; - int Δx; + int Δx, Δy; double m; Δx = p1->x - p0->x; - m = Δx == 0? 0: (p1->y - p0->y)/Δx; + Δy = p1->y - p0->y; + m = Δx == 0? 0: (double)Δy/Δx; for(;;){ code0 = outcode(*p0, r); code1 = outcode(*p1, r); - if(lineisinside(code0, code1) || lineisoutside(code0, code1)) - break; + if(lineisinside(code0, code1)) + return 0; + else if(lineisoutside(code0, code1)) + return -1; if(ptisinside(code0)){ swappt(p0, p1); @@ -207,11 +210,11 @@ rectclipline(Rectangle r, Point *p0, Point *p1) }else if(code0 & CLIPR){ p0->y += (r.max.x - p0->x)*m; p0->x = r.max.x; - }else if(code0 & CLIPB){ + }else if(code0 & CLIPT){ if(p0->x != p1->x && m != 0) p0->x += (r.min.y - p0->y)/m; p0->y = r.min.y; - }else if(code0 & CLIPT){ + }else if(code0 & CLIPB){ if(p0->x != p1->x && m != 0) p0->x += (r.max.y - p0->y)/m; p0->y = r.max.y; diff --git a/internal.h b/internal.h index a982f2c..6e66229 100644 --- a/internal.h +++ b/internal.h @@ -52,7 +52,7 @@ void fprintvattrs(int, Vertex*); /* clip */ int clipprimitive(Primitive*); -void rectclipline(Rectangle, Point*, Point*); +int rectclipline(Rectangle, Point*, Point*); /* util */ int min(int, int); diff --git a/render.c b/render.c index 4a7fb41..f7714c7 100644 --- a/render.c +++ b/render.c @@ -205,7 +205,8 @@ rasterize(Rastertask *task) p0 = Pt(prim.v[0].p.x, prim.v[0].p.y); p1 = Pt(prim.v[1].p.x, prim.v[1].p.y); /* clip it against our wr */ - rectclipline(task->wr, &p0, &p1); + if(rectclipline(task->wr, &p0, &p1) < 0) + break; /* transpose the points */ if(abs(p0.x-p1.x) < abs(p0.y-p1.y)){ -- cgit v1.2.3