diff options
author | rodri <rgl@antares-labs.eu> | 2024-08-02 17:57:42 +0000 |
---|---|---|
committer | rodri <rgl@antares-labs.eu> | 2024-08-02 17:57:42 +0000 |
commit | 50f15bac90638da401d27229969dc502c75d1320 (patch) | |
tree | 2f8bf3b8df50292938d5bca01eb3c0ef3ff1f12f /clip.c | |
parent | 3bf0f4fdcf9e1a61881c20ee8162924f952ba8e0 (diff) | |
download | libgraphics-50f15bac90638da401d27229969dc502c75d1320.tar.gz libgraphics-50f15bac90638da401d27229969dc502c75d1320.tar.bz2 libgraphics-50f15bac90638da401d27229969dc502c75d1320.zip |
fix line interpolation during rasterization.
vertex attributes were not being updated after clipping
with their corresponding work rectangles, nor when
reordering the points before rasterization, which caused
serious artifacts.
Diffstat (limited to 'clip.c')
-rw-r--r-- | clip.c | 34 |
1 files changed, 31 insertions, 3 deletions
@@ -193,11 +193,37 @@ outcode(Point p, Rectangle r) return code; } +/* lerp vertex attributes to match the new positions */ +void +adjustverts(Point *p0, Point *p1, Vertex *v0, Vertex *v1) +{ + Vertex v[2]; + Point3 dp; + Point Δp; + double len, perc; + + dp = subpt3(v1->p, v0->p); + len = hypot(dp.x, dp.y); + + Δp = subpt(Pt(v0->p.x, v0->p.y), *p0); + perc = len == 0? 0: hypot(Δp.x, Δp.y)/len; + lerpvertex(&v[0], v0, v1, perc); + + Δp = subpt(Pt(v0->p.x, v0->p.y), *p1); + perc = len == 0? 0: hypot(Δp.x, Δp.y)/len; + lerpvertex(&v[1], v0, v1, perc); + + delvattrs(v0); + delvattrs(v1); + *v0 = dupvertex(&v[0]); + *v1 = dupvertex(&v[1]); +} + /* * Cohen-Sutherland rectangle-line clipping */ int -rectclipline(Rectangle r, Point *p0, Point *p1) +rectclipline(Rectangle r, Point *p0, Point *p1, Vertex *v0, Vertex *v1) { int code0, code1; int Δx, Δy; @@ -211,14 +237,16 @@ rectclipline(Rectangle r, Point *p0, Point *p1) code0 = outcode(*p0, r); code1 = outcode(*p1, r); - if(lineisinside(code0, code1)) + if(lineisinside(code0, code1)){ + adjustverts(p0, p1, v0, v1); return 0; - else if(lineisoutside(code0, code1)) + }else if(lineisoutside(code0, code1)) return -1; if(ptisinside(code0)){ swappt(p0, p1); swapi(&code0, &code1); + swapvertex(v0, v1); } if(code0 & CLIPL){ |