Алгоритм Брезенхэма для рисования линии на Javascript
В дополнение вот к этому коду для работы с пикселями и рисования окружности на канве HTML по алгоритму Брезенхэма, его же классическое попиксельное рисование линии. Может пригодиться в паре задачек...
Для проверки того, что алгоритм рисования устойчив, через секунду после отрисовки 10 случайно созданных на канве линий перекрашиваются красным цветом и затем канва попиксельно проверяется на то, что на ней нет не-чёрных и не-красных пикселов. В коде закомментирована генерация "плохого" пикселя, если раскомментировать, функция redrawTest
должна прореагировать и выдать сообщение во всплывающем окне. Обновить страницу, чтобы увидеть "перекрашивание" заново, можно клавишей F5
.
Вот пример в работе и листинг, который можно сохранить в виде файла .html
в кодировке Юникода UTF-8.
<!DOCTYPE html> <html> <head> <meta charset="utf-8"/> <title>Bresenham line in Javascript</title> <style type="text/css"> html, body { margin: 0; padding: 0; overflow: hidden; } </style> </head> <body> <div align="center"> <canvas id="lineCanvas" width="500" height="500" style="background-color: black;"> <font color="#808080">Извините, Ваш браузер не поддерживает тег canvas</font> </canvas> </div> <script type="text/javascript"> function Lines () { var imageData, canvas, ctx; //Данные рисунка, канва, контекст this.getPixel = function (x, y) { //Метод для чтения цвета пиксела var index = (y * imageData.width + x) * 4; return { R: imageData.data[index+0], G: imageData.data[index+1], B: imageData.data[index+2], A: imageData.data[index+3] }; } this.putPixel = function (x, y, c) {//Метод для установки цвета пиксела var index = (y * imageData.width + x) * 4; imageData.data[index+0] = c.R; imageData.data[index+1] = c.G; imageData.data[index+2] = c.B; imageData.data[index+3] = c.A; } //Подготовка образа по размеру канвы canvas = document.getElementById ('lineCanvas'); ctx = canvas.getContext ('2d'); imageData = ctx.createImageData (canvas.width,canvas.height); //Рисование линии методом Брезенхэма this.line = function (x0, y0, x1, y1, C) { // из точки (x0,y0) в (x1,y1), C - цвет 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) { putPixel(x0,y0,C); if ((x0==x1) && (y0==y1)) break; var e2 = 2*err; if (e2 >-dy){ err -= dy; x0 += sx; } if (e2 < dx){ err += dx; y0 += sy; } } } var L = new Array (); for (var i=0; i<10; i++) { //Рисуем 10 случайных линий var x0 = Math.floor(Math.random()*canvas.width); var y0 = Math.floor(Math.random()*canvas.height); var x1 = Math.floor(Math.random()*canvas.width); var y1 = Math.floor(Math.random()*canvas.height); var C = { R: Math.floor(Math.random()*256), G: Math.floor(Math.random()*256), B: Math.floor(Math.random()*256), A: 255 }; line (x0, y0, x1, y1, C); //и сохраняем координаты их в массив: L.push ( { X0:x0,Y0:y0,X1:x1,Y1:y1 } ); } ctx.putImageData (imageData, 0, 0); //и выводим их //Через 1 сек. проходим по всем пикселам рисунков красным цветом window.setTimeout('redrawTest()',1000); this.redrawTest = function () { // Повторное перекрашивание красным и проверка for (var i=0; i<10; i++) { var Red = { R: 255, G: 0, B: 0, A: 255 }; line (L[i].X0, L[i].Y0, L[i].X1, L[i].Y1, Red); } ctx.putImageData (imageData, 0, 0); //Специально ставим "плохой" пиксел: /* putPixel (10, 10, {R:222, G:111, B:222, A:255}); ctx.putImageData (imageData, 0, 0); */ //Проверям, что нет пикселов, которые не чёрные или красные: for (var x = 0; x < imageData.width; x++ ) { for (var y = 0; y < imageData.height; y++ ) { var c = getPixel (x,y); if (c.R!=0 && c.R!=255 || c.G!=0 || c.B!=0) { //если есть такой - сообщение об ошибке alert ('Bad pixel ('+c.R+','+c.G+','+c.B+','+c.A+') at ('+x+','+y+')'); } } } } } //Конец основной функции window.addEventListener("load", Lines); //Вызов после загрузки страницы </script> <noscript> <div align="center"> Извините, для работы приложения нужен включённый Javascript </div> </noscript> </body></html>
22.12.2018, 16:02 [2859 просмотров]