mattdesl / three-line-2d

lines expanded in a vertex shader
MIT License
235 stars 34 forks source link

Corrected distance calculation #9

Open tomorrowevening opened 7 years ago

tomorrowevening commented 7 years ago
function distance2(x1, y1, x2, y2) {
    var xd = (x1-x2) * (x1-x2);
    var yd = (y1-y2) * (y1-y2);
    return Math.sqrt( xd + yd );
}

LineMesh.prototype.update = function (path, closed) {
  path = path || [];
  var normals = getNormals(path, closed);

  if (closed) {
    path = path.slice();
    path.push(path[0]);
    normals.push(normals[0]);
  }

  var attrPosition = this.getAttribute('position');
  var attrNormal = this.getAttribute('lineNormal');
  var attrMiter = this.getAttribute('lineMiter');
  var attrDistance = this.getAttribute('lineDistance');
  var attrIndex = typeof this.getIndex === 'function' ? this.getIndex() : this.getAttribute('index');

  var indexCount = Math.max(0, (path.length - 1) * 6);
  if (!attrPosition.array ||
      (path.length !== attrPosition.array.length / 3 / VERTS_PER_POINT)) {
    var count = path.length * VERTS_PER_POINT;
    attrPosition.array = new Float32Array(count * 3);
    attrNormal.array = new Float32Array(count * 2);
    attrMiter.array = new Float32Array(count);
    attrIndex.array = new Uint16Array(indexCount);

    if (attrDistance) {
      attrDistance.array = new Float32Array(count);
    }
  }

  if (undefined !== attrPosition.count) {
    attrPosition.count = count;
  }
  attrPosition.needsUpdate = true;

  if (undefined !== attrNormal.count) {
    attrNormal.count = count;
  }
  attrNormal.needsUpdate = true;

  if (undefined !== attrMiter.count) {
    attrMiter.count = count;
  }
  attrMiter.needsUpdate = true;

  if (undefined !== attrIndex.count) {
    attrIndex.count = indexCount;
  }
  attrIndex.needsUpdate = true;

  if (attrDistance) {
    if (undefined !== attrDistance.count) {
      attrDistance.count = count;
    }
    attrDistance.needsUpdate = true;
  }

  var index = 0;
  var c = 0;
  var dIndex = 0;
  var indexArray = attrIndex.array;
  var pathLength = 0, lastPt = undefined;

  // Determine path length
  path.forEach(function (point, pointIndex, list) {
    if(lastPt !== undefined) {
      var d = distance2(point[0], point[1], lastPt[0], lastPt[1]);
      pathLength += d;
    }
    lastPt = point;
  });

  // Determine normalized position of each vertice along path
  lastPt = undefined;
  var pos = 0;
  path.forEach(function (point, pointIndex, list) {
    var i = index;
    indexArray[c++] = i + 0;
    indexArray[c++] = i + 1;
    indexArray[c++] = i + 2;
    indexArray[c++] = i + 2;
    indexArray[c++] = i + 1;
    indexArray[c++] = i + 3;

    var dist = 0;

    if(lastPt !== undefined) {
      dist = distance2(point[0], point[1], lastPt[0], lastPt[1]);
    }
    lastPt = point;

    attrPosition.setXYZ(index++, point[0], point[1], 0);
    attrPosition.setXYZ(index++, point[0], point[1], 0);

    if (attrDistance) {
      pos += dist / pathLength;
      attrDistance.setX(dIndex++, pos);
      attrDistance.setX(dIndex++, pos);
    }
  });

  var nIndex = 0;
  var mIndex = 0;
  normals.forEach(function (n) {
    var norm = n[0];
    var miter = n[1];
    attrNormal.setXY(nIndex++, norm[0], norm[1]);
    attrNormal.setXY(nIndex++, norm[0], norm[1]);

    attrMiter.setX(mIndex++, -miter);
    attrMiter.setX(mIndex++, miter);
  });
};
mcrawshaw commented 6 years ago

Just in case someone comes across this... The original code assumes the distance between the points on the line is equal. This update allows varied distances.

matthewsanders commented 6 years ago

Shouldn't this be a pull request?