Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get all pixel coordinates between 2 points

I want to get all the x,y coordinates between 2 given points, on a straight line. While this seems like such an easy task, I can't seem to get my head around it.

So, for example:

  • Point 1: (10,5)
  • Point 2: (15,90)
like image 339
skerit Avatar asked Nov 21 '12 10:11

skerit


3 Answers

Based on the wiki article, here's my JS code which handles both high and low lines:

const drawLine = (x0, y0, x1, y1) => {
  const lineLow = (x0, y0, x1, y1) => {
    const dx = x1 - x0
    let dy = y1 - y0
    let yi = 1

    if (dy < 0) {
      yi = -1
      dy = -dy
    }

    let D = 2 * dy - dx
    let y = y0

    for (let x = x0; x < x1; x++) {
      drawPoint(x, y)

      if (D > 0) {
        y = y + yi
        D = D - 2 * dx
      }

      D = D + 2 * dy
    }
  }

  const lineHigh = (x0, y0, x1, y1) => {
    let dx = x1 - x0
    const dy = y1 - y0
    let xi = 1

    if (dx < 0) {
      xi = -1
      dx = -dx
    }

    let D = 2 * dx - dy
    let x = x0

    for (let y = y0; y < y1; y++) {
      drawPoint(x, y)

      if (D > 0) {
        x = x + xi
        D = D - 2 * dy
      }

      D = D + 2 * dx
    }
  }

  const { abs } = Math

  if (abs(y1 - y0) < abs(x1 - x0)) {
    if (x0 > x1) {
      lineLow(x1, y1, x0, y0)
    } else {
      lineLow(x0, y0, x1, y1)
    }
  } else {
    if (y0 > y1) {
      lineHigh(x1, y1, x0, y0)
    } else {
      lineHigh(x0, y0, x1, y1)
    }
  }
}
like image 176
haxpanel Avatar answered Nov 16 '22 16:11

haxpanel


Edit: The solution below only applies from a geometrical point of view. Drawing on a screen is different than theoretical geometry, you should listen to the people suggesting Bresenham's algorithm.


Given, two points, and knowing that the line's equation is y = m*x + b, where m is the slope and b the intercept, you can calculate m and b and then apply the equation to all the values of the X axis between your A and B points:

var A = [10, 5];
var B = [15, 90];

function slope(a, b) {
    if (a[0] == b[0]) {
        return null;
    }

    return (b[1] - a[1]) / (b[0] - a[0]);
}

function intercept(point, slope) {
    if (slope === null) {
        // vertical line
        return point[0];
    }

    return point[1] - slope * point[0];
}

var m = slope(A, B);
var b = intercept(A, m);

var coordinates = [];
for (var x = A[0]; x <= B[0]; x++) {
    var y = m * x + b;
    coordinates.push([x, y]);
}

console.log(coordinates); // [[10, 5], [11, 22], [12, 39], [13, 56], [14, 73], [15, 90]]
like image 44
Victor Stanciu Avatar answered Nov 16 '22 16:11

Victor Stanciu


Given the point A(10, 5) and B(15, 90) and C(x, y) in AB we have:

(x - 10) / (y - 5) = (15 - 10) / (90 - 5)

What you can do is to iterate from x=10 to x=15 and calculate the corresponding y. Since x and y are integers, some times you have to round the result (or skip it).

like image 31
tungd Avatar answered Nov 16 '22 14:11

tungd