javascript algorithm bresenham

Algoritmo Bresenham en Javascript



algorithm (1)

Necesito un algoritmo rápido para calcular coordenadas para una línea entre dos puntos. Traté de encontrar una buena implementación de Bresenham en JavaScript, pero hay demasiadas publicaciones bastante confusas. En wikipedia, here la forma más rápida y simple (sin divisiones y cálculo de errores para ambas direcciones) se presenta en un pseudocódigo como este:

function line(x0, y0, x1, y1) dx := abs(x1-x0) dy := abs(y1-y0) if x0 < x1 then sx := 1 else sx := -1 if y0 < y1 then sy := 1 else sy := -1 err := dx-dy loop setPixel(x0,y0) if x0 = x1 and y0 = y1 exit loop e2 := 2*err if e2 > -dy then err := err - dy x0 := x0 + sx if e2 < dx then err := err + dx y0 := y0 + sy end loop

¿Conoces una implementación de JavaScript Bresenham simple y robusta basada en este pseudocódigo?

EDITAR

¡Gracias a todos! Esto es con lo que vine al final:

function calcStraightLine (startCoordinates, endCoordinates) { var coordinatesArray = new Array(); // Translate coordinates var x1 = startCoordinates.left; var y1 = startCoordinates.top; var x2 = endCoordinates.left; var y2 = endCoordinates.top; // Define differences and error check var dx = Math.abs(x2 - x1); var dy = Math.abs(y2 - y1); var sx = (x1 < x2) ? 1 : -1; var sy = (y1 < y2) ? 1 : -1; var err = dx - dy; // Set first coordinates coordinatesArray.push(new Coordinates(y1, x1)); // Main loop while (!((x1 == x2) && (y1 == y2))) { var e2 = err << 1; if (e2 > -dy) { err -= dy; x1 += sx; } if (e2 < dx) { err += dx; y1 += sy; } // Set coordinates coordinatesArray.push(new Coordinates(y1, x1)); } // Return the result return coordinatesArray; }


Reescribiendo su pseudocódigo suministrado en JavaScript:

function line(x0, y0, x1, y1){ var dx = Math.abs(x1-x0); var dy = Math.abs(y1-y0); var sx = (x0 < x1) ? 1 : -1; var sy = (y0 < y1) ? 1 : -1; var err = dx-dy; while(true){ setPixel(x0,y0); // Do what you need to for this if ((x0==x1) && (y0==y1)) break; var e2 = 2*err; if (e2 >-dy){ err -= dy; x0 += sx; } if (e2 < dx){ err += dx; y0 += sy; } } }

Tenga en cuenta que la comparación directa de flotantes puede fallar a medida que avanza (aunque no debería al avanzar por cantidades enteras, puede ser que si el punto final no es entero), así que en lugar de comparar directamente los puntos finales, puede usar un épsilon:

if (Math.abs(x0-x1)<0.0001 && Math.abs(y0-y1)<0.0001) break;

Sin embargo, esto necesariamente lo hará más lento, así que solo haga esto si está tratando con números enteros.