Why doesn't parseFloat() fix NaN (Javascript)?

88 views Asked by At

EDIT: Here is a reproducible example. When complete, this program will take two points on the surface of a 510x510x510 cube and connect them by the shortest path.

function getSign(a) { // Detects whether a number is positive, negative, or zero.
  if (a) {
    return a / Math.abs(a);
  } else {
    return 0;
  }
}

function findFace(x, y, z) { // Detects which face of the cube a given set of coordinates is on. One input must be set to 255 or -255.
  var returnArray = new Array();
  for (var i = 0; i < arguments.length; i++) {
    if (Math.abs(arguments[i]) == 255) {
      returnArray.push((i + 1) * getSign(arguments[i]));
    }
  }
  return returnArray;
}

function matchFaces(x1, y1, z1, x2, y2, z2) { // Detects whether two sets of coordinates are on the same face, adjacent faces, or opposite faces of the cube.
  var array1 = findFace(x1, y1, z1);
  var array2 = findFace(x2, y2, z2);
  var returnArray = new Array();
  var adj = false;
  for (var i = 0; i < array1.length; i++) {
    if (array2.indexOf(array1[i]) > -1) {
      returnArray.push(array1[i]);
    } else if (array2.indexOf(0 - array1[i]) == -1) {
      adj = true;
    }
  }
  if (returnArray.length < 1) {
    returnArray.push(0);
  }
  if (adj) {
    for (i = 0; i < array1.length; i++) {
      returnArray.push(array1[i]);
    }
    for (i = 0; i < array2.length; i++) {
      returnArray.push(array2[i]);
    }
  } else if (returnArray[0] == 0) {
    returnArray.push(0);
    returnArray.push(array1[0]);
  }
  return returnArray;
}

function buildPathSameFace(x1, y1, x2, y2, isPositive) { // Connects two points on the same face of the cube.
  var returnArray = new Array();
  var pathLength = Math.abs(x2 - x1);
  var pathWidth = Math.abs(y2 - y1);
var longStep = (getSign(x2 - x1)) * pathLength / Math.max(pathLength, pathWidth);
var shortStep = (getSign(y2 - y1)) * pathWidth / Math.max(pathLength, pathWidth);
var longSide = x1;
var shortSide = y1;
for (var i = 0; i < pathLength; i++) {
  returnArray.push([longSide, shortSide, 255 * (2 * isPositive - 1)]);
  longSide += longStep;
  shortSide += shortStep;
}
return returnArray;
}

function buildPathAdjFaces(x1, y1, y2, z2, posStart, posEnd) { // Connects two points on adjacent faces of the cube.
  var startLeg = 255 - x1 * getSign(x1) * (posEnd * 2 - 1);
  var endLeg = 255 - z2 * getSign(z2) * (posStart * 2 - 1);
  var pathLength = startLeg + endLeg;
  var pathWidth = Math.abs(y2 - y1);
  var hingePoint = y1 + pathWidth * startLeg / pathLength * getSign(y2 - y1);
  var returnArray = buildPathSameFace(x1, y1, 255 * posEnd, hingePoint, posStart);
  var endArray = buildPathSameFace(255 * (posStart * 2 - 1), hingePoint, z2, y2, posEnd);
  for (var i = 0; i < endArray.length; i++) {
    returnArray.push([endArray[i][2], endArray[i][1], endArray[i][0]]);
  }
  return returnArray;
}

function buildPathOppFaces(x1, y1, x2, y2, isPositive) { // Connects two points on opposite faces of the cube.
  var starts = [255 - x1, 255 + x1, 255 - y1, 255 + y1];
  var ends = [255 - x2, 255 + x2, 255 - y2, 255 + y2];
  var startLeg = 255;
  var endLeg = 255;
  var counter = -1;
  for (var i = 0; i < starts.length; i++) {
    if (Math.abs(starts[i]) + Math.abs(ends[i]) < startLeg + endLeg) {
      startLeg = Math.abs(starts[i]);
      endLeg = Math.abs(ends[i]);
      counter = i;
    }
  }
  var longSide = x1;
  var shortSide = y1;
  var goalLong = x2;
  var goalShort = y2;
  if (counter > 1) {
    longSide = y1;
    shortSide = x1;
    goalLong = y2;
    goalShort = x2;
  }
  var pathLength = startLeg + 510 + endLeg;
  var pathWidth = Math.abs(goalShort - shortSide);
  var hingeA = shortSide + pathWidth * startLeg / pathLength * getSign(goalShort - shortSide);
  var hingeB = goalShort - pathWidth * endLeg / pathLength * getSign(goalShort - shortSide);
  var returnArray = buildPathSameFace(longSide, shortSide, 255 * (1 - (counter % 2) * 2) * getSign(longSide), hingeA, isPositive);
  var transitArray = buildPathSameFace(255 * isPositive, hingeA, 0 - 255 * isPositive, hingeB, ((counter % 2 - 1) * getSign(longSide) + 1) / 2);
  for (i = 0; i < transitArray.length; i++) {
    returnArray.push(transitArray[i]);
  }
  var endArray = buildPathSameFace(255 * ((counter % 2) * 2 - 1) * getSign(longSide), hingeB, goalLong, goalShort, !isPositive);
  for (i = 0; i < endArray.length; i++) {
    returnArray.push(endArray[i]);
  }
  if (counter > 1) {
    var swappedArray = new Array();
    for (i = 0; i < returnArray.length; i++) {
      swappedArray.push([returnArray[i][1], returnArray[i][0], returnArray[i][2]]);
    }
    return swappedArray;
  } else {
    return returnArray;
  }
}

function sortXYZ(x, y, z, orderKey) { //    Sorts three numbers to a predetermined order.
  switch (orderKey) {
    case "abc":
      return [x, y, z];
      break;
    case "acb":
      return [x, z, y];
      break;
    case "bac":
      return [y, x, z];
      break;
    case "bca":
      return [y, z, x];
      break;
    case "cab":
      return [z, x, y];
      break;
    case "cba":
      return [z, y, x];
      break;
  }
}

function buildPath(x1, y1, z1, x2, y2, z2) { // Detects which faces of the cube two points are on, and connects them by the appropriate path. Not completed.
  var returnArray = new Array();
  var faceMatch = matchFaces(x1, y1, z1, x2, y2, z2);
  var orderKey = "";
  var posStart = -1;
  var posEnd = 2;
  if (faceMatch[0]) {
    switch (Math.abs(faceMatch[0])) {
      case 1:
        orderKey = "bca";
        break;
      case 2:
        orderKey = "acb";
        break;
      case 3:
        orderKey = "abc";
        break;
    }
    posStart = (getSign(faceMatch[0]) + 1) / 2;
  } else if (faceMatch[1]) {
    switch (Math.abs(faceMatch[1])) {
      case 1:
        orderKey = "a";
        if (Math.abs(faceMatch[2]) == 2) {
          orderKey += "bc";
        } else {
          orderKey += "cb";
        }
        break;
      case 2:
        orderKey = "b";
        if (Math.abs(faceMatch[2]) == 1) {
          orderKey += "ac";
        } else {
          orderKey += "ca";
        }
        break;
      case 3:
        orderKey = "c";
        if (Math.abs(faceMatch[2]) == 1) {
          orderKey += "ab";
        } else {
          orderKey += "ba";
        }
        break;
    }
    posStart = (getSign(faceMatch[1]) + 1) / 2;
    posEnd = (getSign(faceMatch[2]) + 1) / 2;
  } else {
    switch (faceMatch[2]) {
      case 1:
        orderKey = "bca";
        break;
      case 2:
        orderKey = "acb";
        break;
      case 3:
        orderKey = "abc";
        break;
    }
    posStart = (getSign(faceMatch[2]) + 1) / 2;
  }
  var startSet = sortXYZ(x1, y1, z1, orderKey);
  var endSet = sortXYZ(x2, y2, z2, orderKey);
  for (i = 0; i < startSet.length; i++) {
    startSet[i] = parseFloat(startSet[i]);
    endSet[i] = parseFloat(endSet[i]);
  }
  if (faceMatch[0]) {
    returnArray = buildPathSameFace(startSet[0], startSet[1], startSet[2], posStart);
  } else if (faceMatch[1]) {
    returnArray = buildPathAdjFaces(startSet[0], startSet[1], startSet[2], posStart, posEnd);
  } else {
    returnArray = buildPathOppFaces(startSet[0], startSet[1], startSet[2], posStart);
  } // Another round of sorting needs to be done before the function is complete, but there's no point until the NaN problem is fixed.
  return returnArray;
}
alert(buildPath(161, 255, 180, -255, -130, 107));

This code produces NaN errors where there should be numerical output:
myArray = myFunction(x[0],x[1],x[2]);
So I changed it to myArray = myFunction(parseFloat(x[0]),parseFloat(x[1]),parseFloat(x[2])); with no effect on the output.

I wrote an alert before this line to see which parameter was the problem:

alert(isNan(x[0])+isNaN(x[1])+isNaN(x[2]));
myArray = myFunction(parseFloat(x[0]),parseFloat(x[1]),parseFloat(x[2]));

which gave me an alert saying "falsefalsefalse".
The function which generates the array I'm here calling x[] reads

function sortXYZ (x,y,z,orderKey) {
    switch(orderKey) {
        case "abc" : return [x,y,z]; break;
        case "acb" : return [x,z,y]; break;
        case "bac" : return [y,x,z]; break;
        case "bca" : return [y,z,x]; break;
        case "cab" : return [z,x,y]; break;
        case "cba" : return [z,y,x]; break;
    }
}

So I changed it to

function sortXYZ (x,y,z,orderKey) {
    alert(isNaN(x)+""+isNaN(y)+""+isNaN(z));
    switch(orderKey) {
        case "abc" : return [parseFloat(x),parseFloat(y),parseFloat(z)]; break;
        case "acb" : return [parseFloat(x),parseFloat(z),parseFloat(y)]; break;
        case "bac" : return [parseFloat(y),parseFloat(x),parseFloat(z)]; break;
        case "bca" : return [parseFloat(y),parseFloat(z),parseFloat(x)]; break;
        case "cab" : return [parseFloat(z),parseFloat(x),parseFloat(y)]; break;
        case "cba" : return [parseFloat(z),parseFloat(y),parseFloat(x)]; break;
    }
}

which gives me another alert saying "falsefalsefalse", and still outputs NaN instead of numbers.

Not all the outputs that ought to be numerical have turned into NaN, just some of them; I have yet to find any rhyme or reason as to which ones.

What do I do?

0

There are 0 answers