错误使用three.js挤出形状

Joh*_*ter 4 javascript three.js d3.js

我刚刚开始使用three.js,并且在挤出一些2d形状时遇到了一些问题.

我有一个包含美国所有郡的GeoJSON文件.我正在使用d3.js和一个d3.geo.albersUSa()投影将每个纬度/经度转换为一个X/Y坐标列表,THREE.Shape然后进行挤压和绘制.这对大多数县来说似乎都行得通.

我看到的问题是,某些县的子集无法使用以下警告序列错误地挤出或挤出:

Warning, unable to triangulate polygon!
Duplicate point 653.4789181355854:204.0166729191409
Either infinite or no solutions!
Its finite solutions.
Either infinite or no solutions!
Too bad, no solutions.
Run Code Online (Sandbox Code Playgroud)

我不确定我究竟究竟是什么问题 - 据我所知,这些特殊形状并没有什么特别之处.我做错了什么,或者这是three.js中挤出代码的问题?


例如,这里有一些缺少的县:

另请注意德克萨斯州的三角形"沙漏"缺失部分:这些看起来像一些只有一半渲染的县(它们最终变成三角形而不是矩形或正方形?)

示例输出 较大的

为巨大的代码转储道歉,我试图尽可能地削减它.

建立:

/* initialize the scene, camera, light, and background plane */
var Map = function(params) {
  this.width     = params.width;
  this.height    = params.height;
  this.container = params.target || document.body;

  this.renderer = new THREE.WebGLRenderer({antialias: true});
  this.renderer.setSize(this.width, this.height);
  this.renderer.setClearColorHex(0x303030, 1.0);

  this.container.appendChild(this.renderer.domElement);

  this.camera = new THREE.PerspectiveCamera(45, this.width / this.height,
                                            1, 10000);
  this.scene = new THREE.Scene();
  this.scene.add(this.camera);

  this.camera.position.z = 550;
  this.camera.position.x = 0;
  this.camera.position.y = 550;

  this.camera.lookAt(this.scene.position);

  this.projection = d3.geo.albersUsa()
    .scale(1000)
    .translate([250, 0]);


 var pointLight = new THREE.PointLight(0xFFFFFF);
 pointLight.position.x = 800;
 pointLight.position.y = 800;
 pointLight.position.z = 800;

  var plane = new THREE.Mesh(
    new THREE.PlaneGeometry(10000, 10000, 10, 10),
    new THREE.MeshLambertMaterial({color: 0xffffff})
  );

  plane.rotation.x = -Math.PI/2;

  this.scene.add(pointLight);
  this.scene.add(plane);
Run Code Online (Sandbox Code Playgroud)

};

渲染:

/* given a GeoJSON Feature, return a list of Vector2s
 * describing where to draw the feature, using the provided projection. */
function path(proj, feature) {
  if (feature.geometry.type == 'Polygon') {
    return polygonPath(proj, feature.geometry.coordinates);
  } else if (feature.geometry.type == 'MultiPolygon') {
    return multiPolygonPath(proj, feature.geometry.coordinates);
  }
}

/* a GeoJSON Polygon is a set of 'rings'.  The first ring is the shape of the polygon.
 * each subsequent ring is a hole inside that polygon. */
function polygonPath(proj, rings) {
  var list = [];
  var cur  = [];

  $.each(rings, function(i, ring) {
    cur = [];

    $.each(ring, function(i, coord) {
      var pts = proj(coord);
      cur.push(new THREE.Vector2(pts[0], pts[1]));
    });

    list.push(cur);
  });

  return list;
}

/* a GeoJSON MultiPolgyon is just a series of Polygons. */
function multiPolygonPath(proj, polys) {
  var list = [];
  $.each(polys, function(i, poly) {
    list.push(polygonPath(proj, poly));
  });
  return list;
}

/* for each feature, find it's X/Y Path, create shape(s) with the required holes,
 * and extrude the shape */
function renderFeatures(proj, features, scene, isState) {
  var color = 0x33ccff;

  $.each(features, function(i, feature) {
    var polygons = path(proj, feature);
    if (feature.geometry.type != 'MultiPolygon') {
      polygons = [polygons];
    }

    $.each(polygons, function(i, poly) {
      var shape = new THREE.Shape(poly[0]);

      if (poly.length > 1) {
        shape.holes = poly.slice(1).map(function(item) { return new THREE.Shape(item); });
      }

      var geom = new THREE.ExtrudeGeometry(shape, { amount: 20, bevelEnabled: false });
      var c = new THREE.Mesh(geom, new THREE.MeshLambertMaterial({color: color}) );

      c.rotation.x = Math.PI/2;
      c.translateX(-290);
      c.translateZ(50);
      c.translateY(5);

      scene.add(c);
    });
  });
}

Map.prototype.renderCounties = function() {
  $.getJSON('/data/us-counties.json', function(json) {
    renderFeatures(this.projection, json.features, this.scene, false);
    this.renderer.render(this.scene, this.camera);
  }.bind(this));
}
Run Code Online (Sandbox Code Playgroud)

Sam*_*ard 6

看起来多边形的点的顺序错误.

  • 事实上,事实证明,有一些背对背的重复点(根据错误信息) - 检查这个并扔掉它们似乎解决了大多数(如果不是全部)漏洞.我会继续把它交给你,因为你引导我找到正确答案:). (3认同)