1

I'm trying to implement bresenham algorithm for a line here is what I did:

https://jsfiddle.net/noatendler/u2vnz5La/1/

for some reason the line isn't in the exact point where I pressed I went over the algorithm and it looks fine.. the points I'm getting from showCoords() function are ok too..

I know this is slimier to http://stackoverflow.com/questions/4672279/bresenham-algorithm-in-javascript but I want to understand where I went wrong...

does anyone know the reason when sometime the line is not straight to the clicking point?

user193239
  • 109
  • 2
  • 2
  • 12
  • You are not really using Bresenhams algorithm but your own ideas. The point of the Bresenham aölgorithm is that it works with integers, which are faster and more exact than adding floating point numbers. – Adder Apr 12 '17 at 08:29
  • @user193239, I edit code to have a better browser compatibility (event added dynamically) – Camille Apr 12 '17 at 08:43

1 Answers1

2

You need to take in account margin, border and offset size.

var c = document.getElementById("myCanvas");
// Add click event dynamically for browser compatibility
c.addEventListener('click',showCoords);
var ctx = c.getContext("2d");
ctx.fillStyle = "blue";

var x1, y1, x2, y2;
var isFirst = 0;

function getRealPosX(clientX) {
    // If border, remove it
    if (c.style['border-left-width']) {
        // As border size have 'px' at the end, remove non-numeric
        clientX -= parseInt(c.style['border-left-width'].replace(/[^0-9\.]/g, ''), 10);
    }
    // If margin, remove it
    if (c.style.marginLeft) {
        // As margin size have 'px' at the end, remove non-numeric
        clientX -= parseInt(c.style.marginLeft.replace(/[^0-9\.]/g, ''), 10);
    }
    // If offset, remove it
    if (c.offsetLeft) {
      clientX -= c.offsetLeft ;
    }
    return clientX;
}

function getRealPosY(clientY) {
    if (c.style['border-top-width']) {
        clientY -= parseInt(c.style['border-top-width'].replace(/[^0-9\.]/g, ''), 10);
    }
    if (c.style.marginTop) {
        clientY -= parseInt(c.style.marginTop.replace(/[^0-9\.]/g, ''), 10);
    }
    if (c.offsetTop) {
        clientY -= c.offsetTop
    }
    return clientY;
}


function showCoords(event) {

    //if it is the first click save it x1,y1
    if (isFirst == 0) {
        x1 = getRealPosX(event.clientX);
        y1 = getRealPosY(event.clientY);
        isFirst = 1;
    }
    //if it is the second click save x2, y2
    else {
        x2 = getRealPosX(event.clientX);
        y2 = getRealPosY(event.clientY);

        //console.log("x1:" + x1 + " y1:" + y1);
        //console.log("x2:" + x2 + " y2:" + y2);

        Drawme(x1, y1, x2, y2);

        //x1=0; x2=0; y1=0; y2=0;
        isFirst = 0; //set it as 0 so the next click would be x1, y1
    }
}

function Drawme(x1, y1, x2, y2) {

    // if it is the same point
    if (x1 == x2 && y1 == y2) {
        ctx.fillRect(x1, y1, 1, 1);
        return;
    }

    var dx = x2 - x1;
    var dy = y2 - y1;

    var steps = Math.max(Math.abs(dx), Math.abs(dy));
    var Xincrement = dx / steps;
    var Yincrement = dy / steps;

    //console.log("Xincrement:" + Xincrement + " Yincrement:" + Yincrement);

    var x = x1,
    y = y1;
    for (var v = 0; v < Math.round(steps); v++) {
        ctx.fillRect(x, y, 1, 1);
        x = x + Xincrement;
        y = y + Yincrement;
    }
}
<canvas id="myCanvas" width="200" height="200" style="border:1px solid #d3d3d3;"></canvas>
Camille
  • 2,439
  • 1
  • 14
  • 32