Drawing Lines

X1: Y1:

X2: Y2:

Algorithm


HTML CODE

 
<!DOCTYPE html>
<html>
<head>
<script src="https://cdn.rawgit.com/google/code-prettify/master/loader/run_prettify.js"></script>
<script type="text/javascript" src="lineCanvas.js"> </script>

</head>
<body>
<h1>Drawing Lines</h1>

<script>
var canvas1 = new lineCanvas(300, 300);

canvas1.Redisplay();
</script>

<p>
X1:
<input
      type="text" 
      maxLength = "3"
      size = "3"
      id="x1", onchange="canvas1.SetVar('x1')">
Y1:
<input
      type="text" 
      maxLength = "3"
      size = "3"
      id="y1", onchange="canvas1.SetVar('y1')">
<p>
X2:
<input
      type="text" 
      maxLength = "3"
      size = "3"
      id="x2", onchange="canvas1.SetVar('x2')">
Y2:
<input
      type="text" 
      maxLength = "3"
      size = "3"
      id="y2", onchange="canvas1.SetVar('y2')">
<p>
<script>
canvas1.FixInterface();
</script>
Algorithm
<select id="algo" onchange="canvas1.SetAlgorithm(this.value); canvas1.Redisplay()">
    <option value="0">Brute Force</option>
    <option value="1">DDA</option>
    <option value="2">Bresenham's</option>
</select>
<p>
<button type="button" id="Redraw" onclick="canvas1.Redisplay()">Redraw</button>
</pre>

lineCanvas.js

 
var BRUTE = '0';
var DDA = '1';
var BRESSENHAMS = '2';

function lineCanvas(width, height, locID) {

    if (width == undefined || width < 0) {
       width = 300;
    }

    if (height == undefined || height < 0) {
       height = 300;
    }

    var canvas = document.createElement('canvas')
        canvas.height = height;
        canvas.width = width;

    if(locID == undefined) {
        document.body.appendChild(canvas);
    } else {
        div = document.getElementById(locID);
        if (null == div) {
            document.body.appendChild(canvas);
        } else {
            div.appendChild(canvas);
        }
    }

    document.body.appendChild(canvas);

    this.width = width;
    this.height = height;
    this.clearColor = "#ffffff";
    this.ctx =  canvas.getContext("2d");

    this.x1 = Math.floor(this.width * .1);
    this.y1 = Math.floor(this.height * .1);
    this.x2 = Math.floor(this.width * .9);
    this.y2 = Math.floor(this.height * .9);

    this.algorithm = BRUTE;

    return this;
}

lineCanvas.prototype = {

    SetClearColor: function(color) {
        this.clearColor = color;
        return;
    },

    Clear: function() {
        this.ctx.fillStyle=this.clearColor;
        this.ctx.fillRect(0,0,this.width,this.height);

        return;
    },

    SetVar: function(id) {
       var node  = document.getElementById(id);
       var value = parseInt(node.value);
 
       if (id == "x1") {
          this.x1= Clamp(0, this.width, value);
       } else if (id == "x2") {
          this.x2= Clamp(0, this.width, value);
       } else if (id == "y1") {
          this.y1= Clamp(0, this.height, value);
       } else if (id == "y2") {
          this.y2= Clamp(0, this.height, value);
       }
       this.FixPoints();
       this.FixInterface();
    },

    FixPoints: function() {
       if (this.x1 > this.x2) {
         
          t = this.x1;
	  this.x1 = this.x2;
	  this.x2  = t;

          t = this.y1;
	  this.y1 = this.y2;
	  this.y2  = t;

       }

       return;
    },

   FixInterface: function() {
       var node;

       node = document.getElementById("x1");
       node.value = this.x1;

       node  = document.getElementById("x2");
       node.value = this.x2;

       node = document.getElementById("y1");
       node.value = this.y1;

       node  = document.getElementById("y2");
       node.value = this.y2;
    },

    SetAlgorithm: function(algorithm) {
        this.algorithm = algorithm;
	return;
    },

    PlotPoint: function(x,y) {
        y = this.height-y;
        this.ctx.fillStyle="#ff0000";
	this.ctx.fillRect(x,y,2,2);
    },

    BruteForce: function() {
        var x,y;
	var m;

        if (this.x1 == this.x2) {
	   console.log(Math.min(this.y1, this.y2), Math.max(this.y1,this.y2));
	   for(y =Math.min(this.y1, this.y2); y <= Math.max(this.y1,this.y2)
	                                      ; y++) {
	     this.PlotPoint(this.x1, y); 
	   }
	} else  {
	   m = (this.y1-this.y2)/(this.x1-this.x2)
	}

	for(x=this.x1; x<=this.x2; x++) {
	   y = Math.round(this.y1 + m * (x-this.x1));
	   this.PlotPoint(x,y);
	}
	return;
    },

    DDALine: function() {

        var dx, dy;
	var x,y;
	var ys, ye;
	var m;


	dx = this.x2-this.x1;
	dy = this.y2-this.y1;

        if (dx == 0) {
	    ys = Math.min(this.y1, this.y2);
	    ye = Math.max(this.y1, this.y2);
	   for(y=ys; y <= ye; y++) {
	       this.PlotPoint(this.x1,y);
	   }
	}

	if (Math.abs(dx) >= Math.abs(dy)) {
	    y = this.y1;
	    for(x=this.x1;x<= this.x2;x++) {
	       this.PlotPoint(x,y);
	       y = y+dy/dx;
	    }
	} else {
	   if (this.y1 < this.y2) {
	      x = this.x1;
	      ys = this.y1;
	      ye = this.y2;
	      m = dx/dy;
	   } else {
	      x = this.x2;
	      ys = this.y2;
	      ye = this.y1;
	      m = -dx/dy;
	   }

	   for(y = ys; y <= ye; y++) {
	       this.PlotPoint(Math.round(x),y);
	       x = x+m;
	   }
	}

	return;
    },

    Bresenhams() {
        var dx, dy, d;
	var x,y;

        dy = this.y2-this.y1;
	dx = this.x2-this.x1;

	if (dy > dx || dy<0) {
	  console.log("Bresenham's only implemented for slope between 0 and 1");
	  return;
	}

	d = 0
	y = this.y1;
	A = -2 * dx;
	B = 2 * dy;
	for(x = this.x1; x <= this.x2; x++) {
	    this.PlotPoint(x,y);
	    if (d >= 0) {
	       d += A;
	       y++;
	    }
	    d += B;
	}

	return;
    },

    Redisplay: function() {
	this.Clear();

	switch (this.algorithm) {
	   case BRUTE:  this.BruteForce(); break;
	   case DDA:  this.DDALine(); break;
	   case BRESSENHAMS:  this.Bresenhams(); break;
	   default: console.log("Unknown alogorithm", this.algorithm);
	}
	
        return;
    }
};


function Clamp(low, high, value) {
   if (value < low) {
      value = low;
   }

   if (value > high) {
       value = high;
   }

   return value;
}