surface: hallazgo 2 — drawLine con Bresenham en enteros
El bucle usaba floats con comparación de igualdad exacta (x1==x2 && y1==y2) como condición de parada, con incrementos ±1.0f acumulados: bug latente. Convertidos los endpoints de entrada con std::lround y reescrito el algoritmo con ints. Firma pública float preservada para no tocar callers. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -211,37 +211,38 @@ void Surface::drawRectBorder(const SDL_FRect* rect, Uint8 color) { // NOLINT(re
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Dibuja una linea
|
// Dibuja una linea (Bresenham en enteros)
|
||||||
void Surface::drawLine(float x1, float y1, float x2, float y2, Uint8 color) { // NOLINT(readability-convert-member-functions-to-static)
|
void Surface::drawLine(float x1, float y1, float x2, float y2, Uint8 color) { // NOLINT(readability-convert-member-functions-to-static)
|
||||||
// Calcula las diferencias
|
int ix1 = static_cast<int>(std::lround(x1));
|
||||||
float dx = std::abs(x2 - x1);
|
int iy1 = static_cast<int>(std::lround(y1));
|
||||||
float dy = std::abs(y2 - y1);
|
const int IX2 = static_cast<int>(std::lround(x2));
|
||||||
|
const int IY2 = static_cast<int>(std::lround(y2));
|
||||||
|
|
||||||
// Determina la dirección del incremento
|
const int DX = std::abs(IX2 - ix1);
|
||||||
float sx = (x1 < x2) ? 1 : -1;
|
const int DY = std::abs(IY2 - iy1);
|
||||||
float sy = (y1 < y2) ? 1 : -1;
|
const int SX = (ix1 < IX2) ? 1 : -1;
|
||||||
|
const int SY = (iy1 < IY2) ? 1 : -1;
|
||||||
|
|
||||||
float err = dx - dy;
|
const int SURF_W = static_cast<int>(surface_data_->width);
|
||||||
|
const int SURF_H = static_cast<int>(surface_data_->height);
|
||||||
|
Uint8* data_ptr = surface_data_->data.get();
|
||||||
|
|
||||||
|
int err = DX - DY;
|
||||||
while (true) {
|
while (true) {
|
||||||
// Asegúrate de no dibujar fuera de los límites de la superficie
|
if (ix1 >= 0 && ix1 < SURF_W && iy1 >= 0 && iy1 < SURF_H) {
|
||||||
if (x1 >= 0 && x1 < surface_data_->width && y1 >= 0 && y1 < surface_data_->height) {
|
data_ptr[ix1 + (iy1 * SURF_W)] = color;
|
||||||
surface_data_->data.get()[static_cast<size_t>(x1 + (y1 * surface_data_->width))] = color;
|
|
||||||
}
|
}
|
||||||
|
if (ix1 == IX2 && iy1 == IY2) {
|
||||||
// Si alcanzamos el punto final, salimos
|
|
||||||
if (x1 == x2 && y1 == y2) {
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
int e2 = 2 * err;
|
int e2 = 2 * err;
|
||||||
if (e2 > -dy) {
|
if (e2 > -DY) {
|
||||||
err -= dy;
|
err -= DY;
|
||||||
x1 += sx;
|
ix1 += SX;
|
||||||
}
|
}
|
||||||
if (e2 < dx) {
|
if (e2 < DX) {
|
||||||
err += dx;
|
err += DX;
|
||||||
y1 += sy;
|
iy1 += SY;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user