JSFiddle - React, Tailwind, and code Playground

HTML

<div id="d"></div>

JavaScript

var map = window.map = [
  'xxxxxxxxxxxxxxx',
  'x      x  x   x',
  'x  xx xxx   x x',
  'x         x   x',
  'xxxxxxxxxxxxxxx',
].join('').split('').map(function (s) {
    // spaces are open, xes are a random texture
    if (s === ' ') return 0;
    return 1;
  });

// map
var width = 15;
var height = 5;

// position
var x = 1.5
var y = 1.5
var heading = 30        / 180 * Math.PI;

    var c = cast(x, y, heading);
document.querySelector('#d').innerHTML = [c.x, c.y, c.ex, c.ey].join('&nbsp;&nbsp;&nbsp;');
    
    
function cast(px, py, angle) {
  if (px < 0 || px > width || py < 0 || py > height || map[Math.floor(px) + Math.floor(py) * width]) {
    return {x: Math.floor(px), y: Math.floor(py), ex: px, ey:py};
  }

  // delta of moving one unit forward on a line at angle
  var dx = Math.cos(angle);
  var dy = Math.sin(angle);
  if (Math.abs(dx) < 0.0000001) dx = 0;
  if (Math.abs(dy) < 0.0000001) dy = 0;

  for (var i = 0; i < 18; ++i) {
    var restx = px % 1;
    if (dx > 0) restx = 1 - restx;
    if (restx === 0) restx = 1;
    var ustepsx = Math.abs(restx / dx);

    var resty = py % 1;
    if (dy > 0) resty = 1 - resty;
    if (resty === 0) resty = 1;
    var ustepsy = Math.abs(resty / dy);

    var dir = ustepsx < ustepsy;

    // rounding ensures we dont get screwed too hard by floating point errors
    if (dir) {
      if (dx) px = Math.round(px + ustepsx * dx);
      if (dy) py += ustepsx * dy;
    } else {
      if (dx) px += ustepsy * dx;
      if (dy) py = Math.round(py + ustepsy * dy);
    }

    var x = Math.floor(px);
    var y = Math.floor(py);

    var bx = x + (dir && dx < 0 ? -1 : 0);
    var by = y + (!dir && dy < 0 ? -1 : 0);
    if (map[bx + by * width]) return {x: bx, y: by, ex: px, ey:py};

    // corner case, repeat check
    if (px === x && py === y) {
      var cx = x + (!dir && dx < 0 ? -1 : 0);
      var cy = y + (dir && dy < 0 ? -1 : 0);
      if (map[cx + cy * width]) return {x: cx, y: cy, ex: px, ey:py};
    }

    // oob
    if...