Search code examples
javascript3dlinerasterizing

How can you find the coordinates between two given points on a straight line(JavaScript)?


I want to get all the x,y,z coordinates between 2 given points, on a straight line. I need to be able to do this in JavaScript for checking whether a projectile collides in my game.

So, for example:

Point 1: (0,0,0) Point 2: (2,2,2) -> 0,0,0 - 1,1,1, 2,2,2

Edit, here is working code for anybody who is lost.

def ROUND(a):

return int(a + 0.5)

def drawDDA(x1,y1,z1,x2,y2,z2):

x,y,z = x1,y1,z1

length = (x2-x1) if (x2-x1) > (y2-y1) else (y2-y1) if (y2-y1) > (z2-z1) else (z2-z1)

dx = (x2-x1)/float(length)

dy = (y2-y1)/float(length)

dz = (z2-z1)/float(length)

print (ROUND(x),ROUND(y),ROUND(z))

for i in range(length):

    x += dx
    z += dz
    y += dy

    print(ROUND(x),ROUND(y),ROUND(z)) 

drawDDA(0,1,2,10,11,12)


Solution

  • Your current approach will need to deal with quadrants in 2D and octants in 3D which is pain in the ass. if you use DDA instead (which is very similar) you will get rid of that. So:

    P(t) = P0 + t*(P1-P0)
    t=<0.0,1.0
    

    This is also called Linear Interpolation. As there are infinite number of points P(t) between your two endpoints P0,P1 I assume you want just integer ones (representing PIXELS) so you need to select t with single "pixel" step and round or floor the coordinates of P(t). That is simple:

    dP = abs(P1-P0)
    dt = 1.0/max(dP.x,dP.y,dP.z)
    

    this is called line rasterization and can be also ported to integer arithmetics without the need for floats. The ported version looks like this:

    dP = abs(P1-P0)
    T = max(dP.x,dP.y,dP.z)
    t = {0,1,2,...,T}
    P(t) = P0 + (P1-P0)*t/T
    

    And even this can be improved by exchanging the *t/T by simple conditional increment/decrement inside loop like this:

    There are also different algorithms like Bresenham for this but DDA is faster on modern architectures and also much simpler and easily expandable to any dimensionality.