在 three.js 中旋转球体,使地球的映射图像与也在 three.js 中显示的 GeoJSON 相匹配
rotate sphere in three.js so that mapped image of globe matches GeoJSON that is also shown in three.js
我在 three.js 中创建了一个地球仪,并且正在使用映射到该球体的图像。
除此之外,我正在使用 ThreeGeoJSON library 来呈现 geojson 数据。
但是地理位置不匹配。
我需要用映射图像旋转地球仪以便它们对齐,但我不知道该怎么做。我尝试设置一个四元数变量并基于它进行旋转,但无法让它工作。非常感谢任何帮助或指点。
在这里你可以看到我到目前为止所做的工作版本:
http://bl.ocks.org/jhubley/8450d7b0df0a4a9fd8ce52d1775515d5
所有代码、图片、数据都在这里:
https://gist.github.com/jhubley/8450d7b0df0a4a9fd8ce52d1775515d5
下面的index.html我也粘贴了。
<html>
<head>
<title>ThreeGeoJSON</title>
<script src="threeGeoJSON.js"></script>
<!-- Three.js library, movement controls, and jquery for the geojson-->
<script src="three.min.js"></script>
<script src="TrackballControls.js"></script>
<script src="jquery-1.10.2.min.js"></script>
</head>
<body>
<script type="text/JavaScript">
var width = window.innerWidth,
height = window.innerHeight;
// Earth params
var radius = 9.99,
segments = 32,
rotation = 0 ;
//New scene and camera
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(55, width / height, 0.01, 1000);
camera.position.z = 1;
camera.position.x = -.2;
camera.position.y = .5;
//New Renderer
var renderer = new THREE.WebGLRenderer();
renderer.setSize(width, height);
document.body.appendChild(renderer.domElement);
//Add lighting
scene.add(new THREE.AmbientLight(0x333333));
var light = new THREE.DirectionalLight(0xe4eef9, .7);
light.position.set(12,12,8);
scene.add(light);
var quaternion = new THREE.Quaternion();
quaternion.setFromAxisAngle( new THREE.Vector3( 0, 1, 0 ), Math.PI / 2 );
var sphere = createSphere(radius, segments);
//sphere.rotation.y = rotation;
sphere.rotation = new THREE.Euler().setFromQuaternion( quaternion );
scene.add(sphere)
//Create a sphere to make visualization easier.
var geometry = new THREE.SphereGeometry(10, 32, 32);
var material = new THREE.MeshPhongMaterial({
//wireframe: true,
//transparent: true
});
function createSphere(radius, segments) {
return new THREE.Mesh(
new THREE.SphereGeometry(radius, segments, segments),
new THREE.MeshPhongMaterial({
map: THREE.ImageUtils.loadTexture('relief.jpg'),
bumpMap: THREE.ImageUtils.loadTexture('elev_bump_4k.jpg'),
bumpScale: 0.005,
specularMap: THREE.ImageUtils.loadTexture('wateretopo.png'),
specular: new THREE.Color('grey')
})
);
}
var clouds = createClouds(radius, segments);
clouds.rotation.y = rotation;
scene.add(clouds)
function createClouds(radius, segments) {
return new THREE.Mesh(
new THREE.SphereGeometry(radius + .003, segments, segments),
new THREE.MeshPhongMaterial({
map: THREE.ImageUtils.loadTexture('n_amer_clouds.png'),
transparent: true
})
);
}
//Draw the GeoJSON
var test_json = $.getJSON("countries_states.geojson", function(data) {
drawThreeGeo(data, 10, 'sphere', {
color: 'red'
})
});
//Draw the GeoJSON loggerhead data
var test_json = $.getJSON("loggerhead-distro-cec-any.json", function(data) {
drawThreeGeo(data, 10, 'sphere', {
color: 'blue'
})
});
//Set the camera position
camera.position.z = 30;
//Enable controls
var controls = new THREE.TrackballControls(camera);
//Render the image
function render() {
controls.update();
requestAnimationFrame(render);
renderer.render(scene, camera);
}
render();
</script>
</body>
</html>
我用的是r81(只是替换了three.min.js
),而不是古老的r66。我稍微修改了您的 createSphere()
函数,似乎可以正常工作。
function createSphere(radius, segments) {
var sphGeom = new THREE.SphereGeometry(radius, segments, segments);
sphGeom.rotateY(THREE.Math.degToRad(-90));
return new THREE.Mesh(
sphGeom,
new THREE.MeshPhongMaterial({
map: new THREE.TextureLoader().load('relief.jpg'),
bumpMap: new THREE.TextureLoader().load('elev_bump_4k.jpg'),
bumpScale: 0.005,
specularMap: new THREE.TextureLoader().load('wateretopo.png'),
specular: new THREE.Color('grey')
})
);
}
我唯一做的就是将球体的几何形状绕 Y 轴旋转 -90 度。结果是here
我在 three.js 中创建了一个地球仪,并且正在使用映射到该球体的图像。
除此之外,我正在使用 ThreeGeoJSON library 来呈现 geojson 数据。
但是地理位置不匹配。
我需要用映射图像旋转地球仪以便它们对齐,但我不知道该怎么做。我尝试设置一个四元数变量并基于它进行旋转,但无法让它工作。非常感谢任何帮助或指点。
在这里你可以看到我到目前为止所做的工作版本: http://bl.ocks.org/jhubley/8450d7b0df0a4a9fd8ce52d1775515d5
所有代码、图片、数据都在这里: https://gist.github.com/jhubley/8450d7b0df0a4a9fd8ce52d1775515d5
下面的index.html我也粘贴了。
<html>
<head>
<title>ThreeGeoJSON</title>
<script src="threeGeoJSON.js"></script>
<!-- Three.js library, movement controls, and jquery for the geojson-->
<script src="three.min.js"></script>
<script src="TrackballControls.js"></script>
<script src="jquery-1.10.2.min.js"></script>
</head>
<body>
<script type="text/JavaScript">
var width = window.innerWidth,
height = window.innerHeight;
// Earth params
var radius = 9.99,
segments = 32,
rotation = 0 ;
//New scene and camera
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(55, width / height, 0.01, 1000);
camera.position.z = 1;
camera.position.x = -.2;
camera.position.y = .5;
//New Renderer
var renderer = new THREE.WebGLRenderer();
renderer.setSize(width, height);
document.body.appendChild(renderer.domElement);
//Add lighting
scene.add(new THREE.AmbientLight(0x333333));
var light = new THREE.DirectionalLight(0xe4eef9, .7);
light.position.set(12,12,8);
scene.add(light);
var quaternion = new THREE.Quaternion();
quaternion.setFromAxisAngle( new THREE.Vector3( 0, 1, 0 ), Math.PI / 2 );
var sphere = createSphere(radius, segments);
//sphere.rotation.y = rotation;
sphere.rotation = new THREE.Euler().setFromQuaternion( quaternion );
scene.add(sphere)
//Create a sphere to make visualization easier.
var geometry = new THREE.SphereGeometry(10, 32, 32);
var material = new THREE.MeshPhongMaterial({
//wireframe: true,
//transparent: true
});
function createSphere(radius, segments) {
return new THREE.Mesh(
new THREE.SphereGeometry(radius, segments, segments),
new THREE.MeshPhongMaterial({
map: THREE.ImageUtils.loadTexture('relief.jpg'),
bumpMap: THREE.ImageUtils.loadTexture('elev_bump_4k.jpg'),
bumpScale: 0.005,
specularMap: THREE.ImageUtils.loadTexture('wateretopo.png'),
specular: new THREE.Color('grey')
})
);
}
var clouds = createClouds(radius, segments);
clouds.rotation.y = rotation;
scene.add(clouds)
function createClouds(radius, segments) {
return new THREE.Mesh(
new THREE.SphereGeometry(radius + .003, segments, segments),
new THREE.MeshPhongMaterial({
map: THREE.ImageUtils.loadTexture('n_amer_clouds.png'),
transparent: true
})
);
}
//Draw the GeoJSON
var test_json = $.getJSON("countries_states.geojson", function(data) {
drawThreeGeo(data, 10, 'sphere', {
color: 'red'
})
});
//Draw the GeoJSON loggerhead data
var test_json = $.getJSON("loggerhead-distro-cec-any.json", function(data) {
drawThreeGeo(data, 10, 'sphere', {
color: 'blue'
})
});
//Set the camera position
camera.position.z = 30;
//Enable controls
var controls = new THREE.TrackballControls(camera);
//Render the image
function render() {
controls.update();
requestAnimationFrame(render);
renderer.render(scene, camera);
}
render();
</script>
</body>
</html>
我用的是r81(只是替换了three.min.js
),而不是古老的r66。我稍微修改了您的 createSphere()
函数,似乎可以正常工作。
function createSphere(radius, segments) {
var sphGeom = new THREE.SphereGeometry(radius, segments, segments);
sphGeom.rotateY(THREE.Math.degToRad(-90));
return new THREE.Mesh(
sphGeom,
new THREE.MeshPhongMaterial({
map: new THREE.TextureLoader().load('relief.jpg'),
bumpMap: new THREE.TextureLoader().load('elev_bump_4k.jpg'),
bumpScale: 0.005,
specularMap: new THREE.TextureLoader().load('wateretopo.png'),
specular: new THREE.Color('grey')
})
);
}
我唯一做的就是将球体的几何形状绕 Y 轴旋转 -90 度。结果是here