Exemplo n.º 1
0
function triangulate(points, includePointAtInfinity) {
  var n = points.length
  if(n === 0) {
    return []
  }
  
  var d = points[0].length
  if(d < 1) {
    return []
  }

  //Special case:  For 1D we can just sort the points
  if(d === 1) {
    return triangulate1D(n, points, includePointAtInfinity)
  }
  
  //Lift points, sort
  var lifted = new Array(n)
  var upper = 1.0
  for(var i=0; i<n; ++i) {
    var p = points[i]
    var x = new Array(d+1)
    var l = 0.0
    for(var j=0; j<d; ++j) {
      var v = p[j]
      x[j] = v
      l += v * v
    }
    x[d] = l
    lifted[i] = new LiftedPoint(x, i)
    upper = Math.max(l, upper)
  }
  uniq(lifted, compareLifted)
  
  //Double points
  n = lifted.length

  //Create new list of points
  var dpoints = new Array(n + d + 1)
  var dindex = new Array(n + d + 1)

  //Add steiner points at top
  var u = (d+1) * (d+1) * upper
  var y = new Array(d+1)
  for(var i=0; i<=d; ++i) {
    y[i] = 0.0
  }
  y[d] = u

  dpoints[0] = y.slice()
  dindex[0] = -1

  for(var i=0; i<=d; ++i) {
    var x = y.slice()
    x[i] = 1
    dpoints[i+1] = x
    dindex[i+1] = -1
  }

  //Copy rest of the points over
  for(var i=0; i<n; ++i) {
    var h = lifted[i]
    dpoints[i + d + 1] = h.point
    dindex[i + d + 1] =  h.index
  }

  //Construct convex hull
  var hull = ch(dpoints, false)
  if(includePointAtInfinity) {
    hull = hull.filter(function(cell) {
      var count = 0
      for(var j=0; j<=d; ++j) {
        var v = dindex[cell[j]]
        if(v < 0) {
          if(++count >= 2) {
            return false
          }
        }
        cell[j] = v
      }
      return true
    })
  } else {
    hull = hull.filter(function(cell) {
      for(var i=0; i<=d; ++i) {
        var v = dindex[cell[i]]
        if(v < 0) {
          return false
        }
        cell[i] = v
      }
      return true
    })
  }

  if(d & 1) {
    for(var i=0; i<hull.length; ++i) {
      var h = hull[i]
      var x = h[0]
      h[0] = h[1]
      h[1] = x
    }
  }

  return hull
}
Exemplo n.º 2
0
"use strict";function LiftedPoint(r,n){this.point=r,this.index=n}function compareLifted(r,n){for(var t=r.point,e=n.point,i=t.length,a=0;i>a;++a){var u=e[a]-t[a];if(u)return u}return 0}function triangulate1D(r,n,t){if(1===r)return t?[[-1,0]]:[];var e=n.map(function(r,n){return[r[0],n]});e.sort(function(r,n){return r[0]-n[0]});for(var i=new Array(r-1),a=1;r>a;++a){var u=e[a-1],f=e[a];i[a-1]=[u[1],f[1]]}return t&&i.push([-1,i[0][1]],[i[r-1][1],-1]),i}function triangulate(r,n){var t=r.length;if(0===t)return[];var e=r[0].length;if(1>e)return[];if(1===e)return triangulate1D(t,r,n);for(var i=new Array(t),a=1,u=0;t>u;++u){for(var f=r[u],o=new Array(e+1),v=0,c=0;e>c;++c){var l=f[c];o[c]=l,v+=l*l}o[e]=v,i[u]=new LiftedPoint(o,u),a=Math.max(v,a)}uniq(i,compareLifted),t=i.length;for(var h=new Array(t+e+1),g=new Array(t+e+1),p=(e+1)*(e+1)*a,s=new Array(e+1),u=0;e>=u;++u)s[u]=0;s[e]=p,h[0]=s.slice(),g[0]=-1;for(var u=0;e>=u;++u){var o=s.slice();o[u]=1,h[u+1]=o,g[u+1]=-1}for(var u=0;t>u;++u){var d=i[u];h[u+e+1]=d.point,g[u+e+1]=d.index}var w=ch(h,!1);if(w=n?w.filter(function(r){for(var n=0,t=0;e>=t;++t){var i=g[r[t]];if(0>i&&++n>=2)return!1;r[t]=i}return!0}):w.filter(function(r){for(var n=0;e>=n;++n){var t=g[r[n]];if(0>t)return!1;r[n]=t}return!0}),1&e)for(var u=0;u<w.length;++u){var d=w[u],o=d[0];d[0]=d[1],d[1]=o}return w}var ch=require("incremental-convex-hull"),uniq=require("uniq");module.exports=triangulate;