Advertisement
Guest User

wuline_bresenham

a guest
Oct 20th, 2019
88
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 9.00 KB | None | 0 0
  1. <!DOCTYPE>
  2. <html>
  3. <head>
  4. <title>Computer Graphics - Task 2.1</title>
  5. <meta charset="UTF-8">
  6. <script type="text/javascript">
  7.  
  8. var context, bresenhamContext, wulineContext; //We hold the contexts in a global variable
  9.  
  10. function onLoad() { //This will be called once the page is loaded
  11. context = document.getElementById('myCanvas').getContext('2d');
  12. bresenhamContext = document.getElementById('myBresenhamCanvas').getContext('2d');
  13. wulineContext = document.getElementById('myWuLineCanvas').getContext('2d');
  14.  
  15. //We will generate a number of lines to draw
  16. var lines = [];
  17. var angle;
  18. for (angle = -Math.PI / 2; angle <= Math.PI / 2; angle += Math.PI / 10) {
  19. lines.push([
  20. [Math.round(-100 * Math.cos(angle)) + 100, Math.round(-100 * Math.sin(angle)) + 100],
  21. [Math.round(100 * Math.cos(angle)) + 100, Math.round(100 * Math.sin(angle)) + 100]
  22. ])
  23. }
  24. //Those lines will always start from the left
  25.  
  26. //Let's draw those lines
  27.  
  28. var line;
  29. for (line in lines) {
  30. drawLine(lines[line][0], lines[line][1]);
  31. drawBresenhamLine(lines[line][0], lines[line][1], 1);
  32. drawWuLine(lines[line][0], lines[line][1], 0);
  33. }
  34. }
  35.  
  36. /**
  37. * This function draw the lines using standard canvas path drawing. It draw smooth lines.
  38. */
  39. function drawLine(startPosition, endPosition) {
  40. context.beginPath();
  41. context.moveTo(startPosition[0], startPosition[1]);
  42. context.lineTo(endPosition[0], endPosition[1]);
  43. context.stroke();
  44. }
  45.  
  46. /**
  47. * This functions will draw lines with the Bresenham line drawing algorithm. The lines will not be smooth.
  48. */
  49. function drawBresenhamLine(startPosition, endPosition, context) {
  50. var deltaX = endPosition[0] - startPosition[0]; //Change in the X direction
  51. var deltaY = endPosition[1] - startPosition[1]; //Change in the Y direction
  52. var error = 0;
  53. var deltaError;
  54. var black = [0, 0, 0];
  55.  
  56. if (Math.abs(deltaX) >= Math.abs(deltaY)) { //Change in X is greater than change in Y. Non-steep line.
  57. deltaError = deltaY / deltaX; //The slope
  58.  
  59. if (deltaError < 0) { //Ascending line, positive change in x direction results in negative change in y.
  60.  
  61. y = startPosition[1]; //Initial y is from the start position
  62.  
  63. for (x = startPosition[0]; x <= endPosition[0]; x++) { //We iterate over all the x values, because those change the quickest.
  64. putPixel(x, y, black, context); //Write the pixel
  65. error += deltaError; //Sum our error
  66.  
  67. if (error <= -0.5) { //Error is greater than half a pixel
  68. y -= 1.0; //Decrease the y coordinate (ascending line, y coordinate decreases)
  69. error += 1.0 //We moved 1 pixel with y -= 1.0, error is now 1 unit less.
  70. }
  71. }
  72. } else { //Descending line
  73. // --Task--
  74. //Similar logic here, but now the line is descending, so the y coordinates and the errorDelta will increase
  75. y = startPosition[1]; //Initial y is from the start position
  76.  
  77. for (x = startPosition[0]; x <= endPosition[0]; x++) { //We iterate over all the x values, because those change the quickest.
  78. putPixel(x, y, black, context); //Write the pixel
  79. error += deltaError; //Sum our error
  80.  
  81. if (error >= 0.5) { //Error is greater than half a pixel
  82. y += 1.0; //Decrease the y coordinate (ascending line, y coordinate decreases)
  83. error -= 1.0 //We moved 1 pixel with y -= 1.0, error is now 1 unit less.
  84. }
  85. }
  86.  
  87. }
  88. } else { //Steep line
  89. //Use the inversed slope
  90. deltaError = deltaX / deltaY;
  91. /**
  92. * --Task--
  93. * For steep lines the y coordinate will change more than x.
  94. * First consider the descending steep lines. The logic will be similar as before.
  95. * Then consider the ascending steep lines. There the start y-coordinate is greater than the end y-coordinate.
  96. */
  97.  
  98. if (deltaError >= 0) { //Ascending line, positive change in x direction results in negative change in y.
  99.  
  100. x = startPosition[0]; //Initial y is from the start position
  101.  
  102. for (y = startPosition[1]; y <= endPosition[1]; y++) { //We iterate over all the x values, because those change the quickest.
  103. putPixel(x, y, black, context); //Write the pixel
  104. error += deltaError; //Sum our error
  105.  
  106. if (error >= 0.5) { //Error is greater than half a pixel
  107. x += 1.0; //Decrease the y coordinate (ascending line, y coordinate decreases)
  108. error -= 1.0; //We moved 1 pixel with y -= 1.0, error is now 1 unit less.
  109. }
  110. }
  111. } else { //Descending line
  112.  
  113. // --Task--
  114. //Similar logic here, but now the line is descending, so the y coordinates and the errorDelta will increase
  115. x = endPosition[0]; //Initial y is from the start position
  116.  
  117. for (y = endPosition[1]; y <= startPosition[1]; y++) { //We iterate over all the x values, because those change the quickest.
  118. putPixel(x, y, black, context); //Write the pixel
  119. error += deltaError; //Sum our error
  120.  
  121. if (error <= -0.5) { //Error is greater than half a pixel
  122. x -= 1.0; //Decrease the y coordinate (ascending line, y coordinate decreases)
  123. error += 1.0; //We moved 1 pixel with y -= 1.0, error is now 1 unit less.
  124. }
  125. }
  126.  
  127. }
  128.  
  129. }
  130. }
  131.  
  132. function ipart(x){
  133. return Math.floor(x);
  134. }
  135. // fractional part of x
  136. function fpart(x){
  137. return x - Math.floor(x);
  138. }
  139. function rfpart(x){
  140. return 1 - fpart(x);
  141. }
  142.  
  143. // Wu Line measurement(Chrome Performance Timings): ... milliseconds compared to Bresenhams Line which was ... milliseconds
  144. function drawWuLine(startPosition, endPosition, context){
  145.  
  146. x0 = startPosition[0];
  147. y0 = startPosition[1];
  148. x1 = endPosition[0];
  149. y1 = endPosition[1];
  150.  
  151. dx = x1 - x0;
  152. dy = y1 - y0;
  153.  
  154. if (Math.abs(dy) > Math.abs(dx)) {
  155. steep = true;
  156. }else {
  157. steep = false;
  158. }
  159.  
  160. if (steep) {
  161. [y0, x0] = [x0, y0];
  162. [y1, x1] = [x1, y1];
  163. [dy, dx] = [dx, dy];
  164. }
  165. if (x0 > x1) {
  166. [x1, x0] = [x0, x1];
  167. [y1, y0] = [y0, y1];
  168. }
  169.  
  170. var gradient = dy / dx;
  171. if (dx == 0.0){
  172. gradient = 1.0;
  173. }
  174.  
  175. xend = Math.round(x0);
  176. yend = y0 + gradient * (xend - x0);
  177. xgap = rfpart(x0 + 0.5);
  178.  
  179. var xpxl1 = xend;
  180. var ypxl1 = ipart(yend);
  181.  
  182. if (steep) {
  183. putPixel(ypxl1 , xpxl1, rfpart(yend) * xgap, context);
  184. putPixel(ypxl1 + 1, xpxl1, fpart(yend) * xgap, context);
  185. }else{
  186. putPixel(xpxl1, ypxl1 , rfpart(yend) * xgap, context);
  187. putPixel(xpxl1, ypxl1 + 1, fpart(yend) * xgap, context);
  188. }
  189.  
  190. intery = yend + gradient;
  191.  
  192. xend = Math.round(x1);
  193. yend = y1 + gradient * (xend - x1);
  194. xgap = fpart(x1 + 0.5);
  195.  
  196. var xpxl2 = xend;
  197. var ypxl2 = ipart(yend);
  198.  
  199. if (steep) {
  200. putPixel(ypxl2 , xpxl2, rfpart(yend) * xgap, context);
  201. putPixel(ypxl2 + 1, xpxl2, fpart(yend) * xgap, context);
  202. }else{
  203. putPixel(xpxl2, ypxl2 , rfpart(yend) * xgap, context);
  204. putPixel(xpxl2, ypxl2 + 1, fpart(yend) * xgap, context);
  205. }
  206.  
  207. if (steep){
  208. for (i = xpxl1 + 1; i <= xpxl2 - 1; i++) {
  209. putPixel(ipart(intery) , i, rfpart(intery), context);
  210. putPixel(ipart(intery) + 1, i, fpart(intery), context);
  211. intery = intery + gradient;
  212. }
  213. }else {
  214. for (j = xpxl1 + 1; j <= xpxl2 - 1; j++) {
  215. putPixel(j, ipart(intery) , rfpart(intery), context);
  216. putPixel(j, ipart(intery) + 1, fpart(intery), context);
  217. intery = intery + gradient;
  218.  
  219. }
  220. }
  221.  
  222.  
  223. }
  224. function putPixel(x, y, color, c) {
  225. /* //You could do:
  226. var imageData = bresenhamContext.createImageData(1,1); //We create new data for the Bresenham canvas context
  227. imageData.data[0] = color[0];
  228. imageData.data[1] = color[1];
  229. imageData.data[2] = color[2];
  230. imageData.data[3] = 255
  231. bresenhamContext.putImageData(imageData, x, y); //Put this data to the Bresenham context
  232. */
  233. //But this is faster:
  234. //http://jsperf.com/setting-canvas-pixel
  235. if (c == 1){
  236. bresenhamContext.fillStyle = 'rgb(' + Math.round(color[0]) + ',' + Math.round(color[1]) + ',' + Math.round(color[2]) + ')';
  237. bresenhamContext.fillRect(x, y, 1, 1);
  238. }else{
  239.  
  240. wulineContext.fillStyle = 'rgba(' + 0 + ',' + 0 + ',' + 0 + ',' + color + ')';
  241. wulineContext.fillRect(x, y, 1, 1);
  242. }
  243.  
  244. }
  245.  
  246. </script>
  247. <style type="text/css">
  248. canvas {
  249. border: 1px solid black;
  250. margin: 2px;
  251. float: left;
  252. }
  253. </style>
  254. </head>
  255. <body onload="onLoad()">
  256. <canvas width="200" height="200" id="myCanvas"></canvas>
  257. <canvas width="200" height="200" id="myBresenhamCanvas"></canvas>
  258. <canvas width="200" height="200" id="myWuLineCanvas"></canvas>
  259. </body>
  260. </html>
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement