Quantum/well/canvas.cpp

93 lines
2.6 KiB
C++
Raw Permalink Normal View History

2023-12-16 16:17:02 +01:00
#include "libwasm.h"
#include "canvas.h"
int round (const double a) {
return int (a + 0.5);
}
Canvas::Canvas(const int w, const int h) : width(w), height(h),
outpixel(0u), current(0xFF000000), matrix (1.0, 0.0, 0.0, -1.0, 0.5 * (real) w, 0.5 * (real) (h)) {
data = new Color [w * h];
}
Canvas::~Canvas() {
delete [] data;
}
void Canvas::fill (const Color & c) {
for (int y=0; y<height; y++) {
for (int x=0; x<width; x++) {
at (x, y) = c;
}
}
}
Color & Canvas::at (const int x, const int y) {
if (!bound(x, y)) return outpixel;
const int result = x + y * width;
return data [result];
}
bool Canvas::bound (const int x, const int y) const {
if (x < 0) return false;
if (y < 0) return false;
if (x >= width) return false;
if (y >= height) return false;
return true;
}
void Canvas::line (const int xp, const int yp, const int xe, const int ye, const bool doted) {
bool dot = true;
int x1 = xp, y1 = yp;
const int x2 = xe, y2 = ye;
bool done = false;
int mx = 0, my = 0;
// Determine direction and distance
const int xd = (x1 < x2) ? 1 : -1;
const int yd = (y1 < y2) ? 1 : -1;
const int xl = (x1 < x2) ? (x2 - x1) : (x1 - x2);
const int yl = (y1 < y2) ? (y2 - y1) : (y1 - y2);
while (!done) {
if (x1 == x2 && y1 == y2) done = true;
if (dot) at(x1,y1) = current; // Plot pixel
if (doted) dot = !dot;
mx += xl;
if (x1 != x2 && mx > yl) x1 += xd, mx -= yl;
my += yl;
if (y1 != y2 && my > xl) y1 += yd, my -= xl;
}
}
void Canvas::rect (const int x0, const int y0, const int x1, const int y1) {
for (int y=y0; y<y1; y++) {
for (int x=x0; x<x1; x++) {
at(x, y) = current;
}
}
}
void Canvas::line (const FPoint & begin, const FPoint & end, const bool doted) {
const FPoint b (matrix * begin);
const FPoint e (matrix * end );
const int x0 = (const int) round (b.x);
const int y0 = (const int) round (b.y);
const int x1 = (const int) round (e.x);
const int y1 = (const int) round (e.y);
// printf("%d:%d - %d:%d\n", x0, y0, x1, y1);
line (x0, y0, x1, y1, doted);
}
void Canvas::circ (const FPoint & center, const real radius) {
if (radius == 0) return;
double x = radius, y = 0.0;
const double dx = 1.0 / radius;
const double ms = radius * 6.3;
real count = 0.0;
// kruh se da nakreslit i bez sin a cos, rychle ale trochu nepresne
for (;;) {
x += y * dx; y -= x * dx;
const FPoint e (center.x + x, center.y + y);
const FPoint t (matrix * e);
at ((int) round (t.x), (int) round (t.y)) = current;
count += 1.0;
if (count > ms) break;
}
}
void Canvas::setMatrix (const Matrix& m) {
matrix = m;
}