mirror of
https://github.com/UpsilonNumworks/Upsilon.git
synced 2026-01-19 00:37:25 +01:00
101 lines
2.7 KiB
C++
101 lines
2.7 KiB
C++
#include <kandinsky/line.h>
|
|
#include <kandinsky/pixel.h>
|
|
#include <assert.h>
|
|
|
|
void KDDrawLine(KDPoint p1, KDPoint p2, KDColor c) {
|
|
// Find the largest gap
|
|
KDPoint left, right;
|
|
if (p2.x > p1.x) {
|
|
left = p1;
|
|
right = p2;
|
|
} else {
|
|
left = p2;
|
|
right = p1;
|
|
}
|
|
KDPoint top, bottom;
|
|
if (p2.y > p1.y) {
|
|
top = p1;
|
|
bottom = p2;
|
|
} else {
|
|
top = p2;
|
|
bottom = p1;
|
|
}
|
|
assert(right.x >= left.x);
|
|
assert(bottom.y >= top.y);
|
|
|
|
KDCoordinate deltaX = 2*(right.x - left.x);
|
|
KDCoordinate deltaY = 2*(bottom.y - top.y);
|
|
|
|
KDPoint p, alwaysTranslate, conditionalTranslate;
|
|
KDCoordinate scanLength, error, minusError, plusError;
|
|
|
|
if (deltaX >= deltaY) {
|
|
p = left;
|
|
scanLength = right.x - left.x;
|
|
error = right.x - left.x;
|
|
minusError = deltaY;
|
|
plusError = deltaX;
|
|
alwaysTranslate = KDPointMake(1,0);
|
|
conditionalTranslate = KDPointMake(0, (right.y >= left.y ? 1 : -1));
|
|
} else {
|
|
p = top;
|
|
scanLength = bottom.y - top.y;
|
|
error = bottom.y - top.y;
|
|
minusError = deltaX;
|
|
plusError = deltaY;
|
|
alwaysTranslate = KDPointMake(0,1);
|
|
conditionalTranslate = KDPointMake((bottom.x >= top.x ? 1 : -1), 0);
|
|
}
|
|
|
|
KDCoordinate scanCounter = 0;
|
|
while (scanCounter++ < scanLength) {
|
|
KDSetPixel(p, c);
|
|
p = KDPointTranslate(p, alwaysTranslate);
|
|
error = error - minusError;
|
|
if (error <= 0) {
|
|
p = KDPointTranslate(p, conditionalTranslate);
|
|
error = error + plusError;
|
|
}
|
|
}
|
|
}
|
|
/*
|
|
#include <cmath>
|
|
#include <stdlib.h>
|
|
|
|
void KDDrawAntiAliasedLine(KDPoint p1, KDPoint p2, KDCoordinate width, KDColor frontColor, KDColor backColor) {
|
|
int x0 = p1.x;
|
|
int y0 = p1.y;
|
|
int x1 = p2.x;
|
|
int y1 = p2.y;
|
|
float wd = width;
|
|
|
|
int dx = abs(x1-x0), sx = x0 < x1 ? 1 : -1;
|
|
int dy = abs(y1-y0), sy = y0 < y1 ? 1 : -1;
|
|
int err = dx-dy, e2, x2, y2; // error value e_xy
|
|
float ed = dx+dy == 0 ? 1 : sqrt((float)dx*dx+(float)dy*dy);
|
|
|
|
for (wd = (wd+1)/2; ; ) { // pixel loop
|
|
KDPoint p = {.x = x0, .y = y0};
|
|
KDColor color = KDColorMix(KDColorRed, KDColorWhite, (abs(err-dx+dy)/ed-wd+1));
|
|
KDSetPixel(p, color);
|
|
e2 = err; x2 = x0;
|
|
if (2*e2 >= -dx) { // x step
|
|
for (e2 += dy, y2 = y0; e2 < ed*wd && (y1 != y2 || dx > dy); e2 += dx) {
|
|
y2 += sy;
|
|
p = {.x = x0, .y = y2};
|
|
color = KDColorMix(KDColorRed, KDColorWhite, (abs(err-dx+dy)/ed-wd+1));
|
|
setPixelColor(x0, y2 += sy, max(0,255*(abs(e2)/ed-wd+1)));
|
|
}
|
|
if (x0 == x1) break;
|
|
e2 = err; err -= dy; x0 += sx;
|
|
}
|
|
if (2*e2 <= dy) { // y step
|
|
for (e2 = dx-e2; e2 < ed*wd && (x1 != x2 || dx < dy); e2 += dy)
|
|
setPixelColor(x2 += sx, y0, max(0,255*(abs(e2)/ed-wd+1)));
|
|
if (y0 == y1) break;
|
|
err += dx; y0 += sy;
|
|
}
|
|
}
|
|
}
|
|
*/
|