• HexSphere.js

  • ¶

    HexSphere geometry generator.

  • ¶

    Parent class : geom.Geometry

  • ¶

    Example use

     var g = new HexSphere(0.5);
     var mesh = new Mesh(g, new materials.SolidColor());
    
    var geom = require('pex-geom');
    var Vec3 = geom.Vec3;
    var Geometry = geom.Geometry;
    var Icosahedron = require('./Icosahedron');
  • ¶

    HexSphere ( r, level )

    r - radius { Number = 0.5 }
    level - number of subdivisions { Number/Int = 1 }

    function HexSphere(r, level) {
      r = r || 0.5;
      level = level || 1;
    
      var baseGeom = new Icosahedron(r);
      for(var i=0; i<level; i++) {
        baseGeom = baseGeom.subdivideEdges();
      }
    
      var vertices = [];
      var faces = [];
    
    
      var halfEdgeForVertex = [];
      var halfEdges = baseGeom.computeHalfEdges();
      halfEdges.forEach(function(e) {
        halfEdgeForVertex[e.face[e.slot]] = e;
      });
    
      for(var i=0; i<baseGeom.vertices.length; i++) {
        var vertexIndex = vertices.length;
        var midPoints = [];
  • ¶

    collect center points of neighbor faces

        vertexEdgeLoop(halfEdgeForVertex[i], function(e) {
          var midPoint = centroid(elements(baseGeom.vertices, e.face));
          midPoints.push(midPoint);
        });
        midPoints.forEach(function(p, i){
          vertices.push(p);
        });
        if (midPoints.length == 5) {
          faces.push([vertexIndex, vertexIndex+1, vertexIndex+2, vertexIndex+3, vertexIndex+4]);
        }
        if (midPoints.length == 6) {
          faces.push([vertexIndex, vertexIndex+1, vertexIndex+2, vertexIndex+3, vertexIndex+4, vertexIndex+5]);
        }
      }
    
      vertices.forEach(function(v) {
        v.normalize().scale(r);
      });
    
      Geometry.call(this, { vertices: vertices, faces: faces });
    
      this.computeEdges();
    }
    
    HexSphere.prototype = Object.create(Geometry.prototype);
    
    module.exports = HexSphere;
  • ¶

    Utility functions

    function next(edge) {
      return edge.face.halfEdges[(edge.slot + 1) % edge.face.length]
    }
    
    function prev(edge) {
      return edge.face.halfEdges[(edge.slot - 1 + edge.face.length) % edge.face.length]
    }
    
    function vertexEdgeLoop(edge, cb) {
      var curr = edge;
    
      do {
        cb(curr);
        curr = prev(curr).opposite;
      }
      while(curr != edge);
    }
    
    function centroid(points) {
      var n = points.length;
      var center = points.reduce(function(center, p) {
        return center.add(p);
      }, new Vec3(0, 0, 0));
      center.scale(1 / points.length);
      return center;
    }
    
    function elements(list, indices) {
      return indices.map(function(i) { return list[i]; })
    }