使用三个 js 和 NSF OpenTopography 数据的点云:如何设置相机和控件库来导航数据?
Point cloud using three js and NSF OpenTopography data : How do you set up the camera and a controls library to navigate the data?
我正在做一个小项目,我试图使用三个 js 在点云可视化中显示 NSF OpenTopography 数据。我能够创建点云,但 运行 相机设置和相机导航存在严重问题。我尝试过使用各种控件(OrbitControls.js、TrackballControls.js 和 FirstPersonControls.js),但都不够用。下面是一个 link 到我在可视化中所处位置的工作副本。我的目标是能够绘制点云数据并使用鼠标或箭头键在场景中导航。
http://jsfiddle.net/mcroteau/ycg1hqu0/
如果需要其他代码和/或示例,请告诉我。上面的 jsfiddle 只是许多尝试中的一种尝试。
任何指导将不胜感激。
Javascript
var container, scene,
camera, renderer,
controls, stats,
geometry, material;
var SCREEN_WIDTH = window.innerWidth,
SCREEN_HEIGHT = window.innerHeight;
var VIEW_ANGLE = 45,
ASPECT = SCREEN_WIDTH / SCREEN_HEIGHT,
NEAR = 0.1,
FAR = 20000;
var POINT_SIZE = 1;
var BACKGROUND_COLOR = 0xefefef,
POINT_COLOR = 0x4466B0;
var maxX = maxY = maxZ = 0;
var minX = minY = minZ = 0;
var midX = midY = midZ = 0;
var step = 1;
var lookZ = lookX = 0;
init();
animate();
function init() {
scene = new THREE.Scene();
container = document.createElement('div');
document.body.appendChild( container );
if ( Detector.webgl ){
renderer = new THREE.WebGLRenderer({ antialias: true });
}else{
renderer = new THREE.CanvasRenderer();
}
renderer.setSize(SCREEN_WIDTH, SCREEN_HEIGHT);
renderer.setClearColor( BACKGROUND_COLOR, 1);
container.appendChild( renderer.domElement );
stats = new Stats();
stats.domElement.style.position = 'absolute';
stats.domElement.style.bottom = '0px';
stats.domElement.style.zIndex = 100;
container.appendChild( stats.domElement );
geometry = new THREE.Geometry();
for (var i = 0; i < data.length; i ++ ) {
var vertex = new THREE.Vector3();
/**
correct x, y, z values
camera seems really out of position when using these values
**/
//var x = data[i][0];
//var y = data[i][1];
//var z = data[i][2];
var x = data[i][1];
var y = data[i][2];
var z = data[i][0];
vertex.x = x;
vertex.y = y;
vertex.z = z;
geometry.vertices.push(vertex);
if(i < 10){
console.log([x, y, z]);
}
checkSetMaxValues(x, y, z, i);
}
setMedians()
camera = new THREE.PerspectiveCamera( VIEW_ANGLE, ASPECT, NEAR, FAR);
camera.position.x = minX - 20
camera.position.y = maxY + 20
camera.position.z = minZ - 20
scene.position.x = midX
scene.position.y = minY
scene.position.z = midZ
scene.add(camera);
camera.lookAt(scene.position);
//controls = new THREE.OrbitControls( camera, renderer.domElement );
lookZ = camera.position.z
lookX = camera.position.x
material = new THREE.PointCloudMaterial( { size: POINT_SIZE, color : POINT_COLOR } );
particles = new THREE.PointCloud( geometry, material );
scene.add( particles );
window.addEventListener( 'resize', onWindowResize, false );
}
function setMedians(){
midX = (maxX + minX) / 2;
midY = (maxY + minY) / 2;
midZ = (maxZ + minZ) / 2;
console.info('mid', midX, midY, midZ);
}
function checkSetMaxValues(x, y, z, i){
if(x > maxX || maxX === 0)maxX = x
if(x < minX || minX === 0)minX = x
if(y > maxY || maxY === 0)maxY = y
if(y < minY || minY === 0)minY = y
if(z > maxZ || maxZ === 0)maxZ = z
if(z < minZ || minZ === 0)minZ = z
if(data.length == i + 1){
console.log('max:', maxX, maxY, maxZ)
console.log('min:', minX, minY, minZ)
}
}
function onWindowResize() {
var windowHalfX = window.innerWidth / 2;
var windowHalfY = window.innerHeight / 2;
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize( window.innerWidth, window.innerHeight );
}
function animate() {
render();
update();
requestAnimationFrame( animate );
}
function update(){
stats.update();
updateCamera();
//would like to use a controls library
//controls.update()
}
function updateCamera(){
if(lookZ < maxZ){
camera.position.z = camera.position.z + 0.20;
lookZ = camera.position.z
}
if(lookZ >= maxZ){
if(lookX < maxX){
camera.position.x = camera.position.x + 0.20;
lookX = camera.position.x
}
}
camera.lookAt(scene.position)
}
function render() {
renderer.render( scene, camera );
}
问题似乎是 Orbit Controls 无法处理您疯狂的场景大小。当相机 position
设置为如此高的值时,旋转速度和缩放会适应(移动速度更快)。但是您的视觉数据的一般边界框并没有那么大,所以我猜它会立即移出视图 space。
我通过使用 geometry.center();
重新居中几何而不修改 scene.position
解决了这个问题。这是结果:http://jsfiddle.net/ycg1hqu0/9/
我正在做一个小项目,我试图使用三个 js 在点云可视化中显示 NSF OpenTopography 数据。我能够创建点云,但 运行 相机设置和相机导航存在严重问题。我尝试过使用各种控件(OrbitControls.js、TrackballControls.js 和 FirstPersonControls.js),但都不够用。下面是一个 link 到我在可视化中所处位置的工作副本。我的目标是能够绘制点云数据并使用鼠标或箭头键在场景中导航。
http://jsfiddle.net/mcroteau/ycg1hqu0/
如果需要其他代码和/或示例,请告诉我。上面的 jsfiddle 只是许多尝试中的一种尝试。
任何指导将不胜感激。
Javascript
var container, scene,
camera, renderer,
controls, stats,
geometry, material;
var SCREEN_WIDTH = window.innerWidth,
SCREEN_HEIGHT = window.innerHeight;
var VIEW_ANGLE = 45,
ASPECT = SCREEN_WIDTH / SCREEN_HEIGHT,
NEAR = 0.1,
FAR = 20000;
var POINT_SIZE = 1;
var BACKGROUND_COLOR = 0xefefef,
POINT_COLOR = 0x4466B0;
var maxX = maxY = maxZ = 0;
var minX = minY = minZ = 0;
var midX = midY = midZ = 0;
var step = 1;
var lookZ = lookX = 0;
init();
animate();
function init() {
scene = new THREE.Scene();
container = document.createElement('div');
document.body.appendChild( container );
if ( Detector.webgl ){
renderer = new THREE.WebGLRenderer({ antialias: true });
}else{
renderer = new THREE.CanvasRenderer();
}
renderer.setSize(SCREEN_WIDTH, SCREEN_HEIGHT);
renderer.setClearColor( BACKGROUND_COLOR, 1);
container.appendChild( renderer.domElement );
stats = new Stats();
stats.domElement.style.position = 'absolute';
stats.domElement.style.bottom = '0px';
stats.domElement.style.zIndex = 100;
container.appendChild( stats.domElement );
geometry = new THREE.Geometry();
for (var i = 0; i < data.length; i ++ ) {
var vertex = new THREE.Vector3();
/**
correct x, y, z values
camera seems really out of position when using these values
**/
//var x = data[i][0];
//var y = data[i][1];
//var z = data[i][2];
var x = data[i][1];
var y = data[i][2];
var z = data[i][0];
vertex.x = x;
vertex.y = y;
vertex.z = z;
geometry.vertices.push(vertex);
if(i < 10){
console.log([x, y, z]);
}
checkSetMaxValues(x, y, z, i);
}
setMedians()
camera = new THREE.PerspectiveCamera( VIEW_ANGLE, ASPECT, NEAR, FAR);
camera.position.x = minX - 20
camera.position.y = maxY + 20
camera.position.z = minZ - 20
scene.position.x = midX
scene.position.y = minY
scene.position.z = midZ
scene.add(camera);
camera.lookAt(scene.position);
//controls = new THREE.OrbitControls( camera, renderer.domElement );
lookZ = camera.position.z
lookX = camera.position.x
material = new THREE.PointCloudMaterial( { size: POINT_SIZE, color : POINT_COLOR } );
particles = new THREE.PointCloud( geometry, material );
scene.add( particles );
window.addEventListener( 'resize', onWindowResize, false );
}
function setMedians(){
midX = (maxX + minX) / 2;
midY = (maxY + minY) / 2;
midZ = (maxZ + minZ) / 2;
console.info('mid', midX, midY, midZ);
}
function checkSetMaxValues(x, y, z, i){
if(x > maxX || maxX === 0)maxX = x
if(x < minX || minX === 0)minX = x
if(y > maxY || maxY === 0)maxY = y
if(y < minY || minY === 0)minY = y
if(z > maxZ || maxZ === 0)maxZ = z
if(z < minZ || minZ === 0)minZ = z
if(data.length == i + 1){
console.log('max:', maxX, maxY, maxZ)
console.log('min:', minX, minY, minZ)
}
}
function onWindowResize() {
var windowHalfX = window.innerWidth / 2;
var windowHalfY = window.innerHeight / 2;
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize( window.innerWidth, window.innerHeight );
}
function animate() {
render();
update();
requestAnimationFrame( animate );
}
function update(){
stats.update();
updateCamera();
//would like to use a controls library
//controls.update()
}
function updateCamera(){
if(lookZ < maxZ){
camera.position.z = camera.position.z + 0.20;
lookZ = camera.position.z
}
if(lookZ >= maxZ){
if(lookX < maxX){
camera.position.x = camera.position.x + 0.20;
lookX = camera.position.x
}
}
camera.lookAt(scene.position)
}
function render() {
renderer.render( scene, camera );
}
问题似乎是 Orbit Controls 无法处理您疯狂的场景大小。当相机 position
设置为如此高的值时,旋转速度和缩放会适应(移动速度更快)。但是您的视觉数据的一般边界框并没有那么大,所以我猜它会立即移出视图 space。
我通过使用 geometry.center();
重新居中几何而不修改 scene.position
解决了这个问题。这是结果:http://jsfiddle.net/ycg1hqu0/9/