我正在尝试使用THREE.js库渲染SciPy SphericalVoronoi的输出。基于scipy文档中的matplotlib示例,我希望它相对简单。
更新2/18/17:
我最初没有说明voronoi区域是四边形,所以现在将它们分成三角形。我确实让单位立方体示例工作;但是,放大几何图形似乎并不完整。
Python脚本:
import json
import numpy as np
from scipy.spatial import SphericalVoronoi
# http://stackoverflow.com/questions/27050108/convert-numpy-type-to-python/27050186#27050186
class NumpyEncoder(json.JSONEncoder):
def default(self, obj):
if isinstance(obj, np.integer):
return int(obj)
elif isinstance(obj, np.floating):
return float(obj)
elif isinstance(obj, np.ndarray):
return obj.tolist()
else:
return super(NumpyEncoder, self).default(obj)
def computeVoronoi( data ):
vertices = np.array( data['vertices'] )
lenVerts = int( vertices.shape[0] / 3 )
vertices = np.reshape( vertices, ( lenVerts, 3 ) )
voronoi = SphericalVoronoi( vertices, data['regularRadius'] )
'''
points = np.array([[0, 0, 1], [0, 0, -1], [1, 0, 0], [0, 1, 0], [0, -1, 0], [-1, 0, 0], ])
voronoi = SphericalVoronoi( points, 1, np.array([0, 0, 0]) )
'''
voronoi.sort_vertices_of_regions()
return voronoi
if __name__ == '__main__':
with open( './map.json' ) as infile:
voronoi = computeVoronoi( json.load( infile ) )
indices = []
for region in voronoi.regions:
# need to split the quad into tris for rendering
i1 = region[0]
i2 = region[1]
i3 = region[2]
i4 = region[3]
indices.append( i1 )
indices.append( i2 )
indices.append( i3 )
indices.append( i3 )
indices.append( i4 )
indices.append( i1 )
with open( './voronoi.json', 'w' ) as outfile:
json.dump( {
'indices': indices,
'colors': np.random.random( (len( voronoi.vertices ),3) ).flatten(),
'vertices': voronoi.vertices.flatten()
}, outfile, cls=NumpyEncoder )
THREE.js脚本:
var loader = new THREE.FileLoader()
loader.load( 'voronoi.json', function( data ) {
vJson = JSON.parse( data )
var geometry = new THREE.BufferGeometry()
geometry.addAttribute( 'position', new THREE.BufferAttribute( new Float32Array( vJson.vertices ), 3 ) )
geometry.addAttribute( 'color', new THREE.BufferAttribute( new Float32Array( vJson.colors ), 3 ) )
geometry.setIndex( new THREE.BufferAttribute( new Uint32Array( vJson.indices ), 1 ) )
var voronoiMesh = new THREE.Mesh(
geometry,
new THREE.MeshBasicMaterial({
color: 0xffffff,
side: THREE.DoubleSide,
vertexColors: THREE.VertexColors,
})
)
scene.add( voronoiMesh )
})
以下是渲染现在的样子: render link