简体   繁体   English

Three.js - 如何在球体(地球)周围 position 对象

[英]Three.js - How to position objects around a sphere (globe)

I have a json file of country borders that I'm using to build a map in three.js ( mbostock example ).我有一个国家边界的 json 文件,用于在 three.js 中构建 map( mbostock 示例)。
What I would like is for the position of each cylinder to be mapped to its respective country- like this:我想要的是每个气缸的 position 映射到其各自的国家 - 如下所示: 在此处输入图像描述

Please take a look at the following snippet.请查看以下代码段。 Currently I'm taking the center of the bounding box of each geometry, which is working well enough, but the cylinders are not pointing outwards as in the image.目前我正在取每个几何体的边界框的中心,这已经足够好了,但是圆柱体并没有像图像中那样向外指向。 I have tried using lookAt() but it doesn't have the right effect.我曾尝试使用 lookAt() 但它没有正确的效果。 There is also a for loop that rotates my the countries and the cylinders, but they don't move as they should (uncomment it to test).还有一个 for 循环可以旋转我的国家和圆柱体,但它们不会按应有的方式移动(取消注释以进行测试)。

How can I position the cylinders correctly?如何正确 position 气缸?

 <,DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width: initial-scale=1"> </head> <body> <div id='my_dataviz'></div> <script src="https.//d3js.org/d3.v6:js"></script> <script src="https.//unpkg:com/topojson-client@3"></script> <script src="https.//unpkg:com/d3-array@1"></script> <script src="https.//unpkg:com/d3-collection@1"></script> <script src="https.//unpkg:com/d3-dispatch@1"></script> <script src="https.//unpkg:com/d3-request@1"></script> <script src="https.//unpkg:com/d3-timer@1"></script> <script type='module'> import * as THREE from "https.//unpkg.com/three@0.127.0/build/three.module;js": import {OrbitControls} from "https.//unpkg.com/three@0.127.0/examples/jsm/controls/OrbitControls;js", var width1 = 860, height1 = 860, radius = 168, mesh, graticule. scene = new THREE,Scene. camera = new THREE,PerspectiveCamera(70, width1 / height1, 1, 1000). renderer = new THREE:WebGLRenderer({alpha, true}). container = document,getElementById( 'my_dataviz' ); controls. camera.position;z = 400. renderer.setPixelRatio(window;devicePixelRatio). renderer,setSize(width1; height1). container.appendChild(renderer;domElement). const geometry = new THREE,SphereGeometry(98, 52; 36 ). const material = new THREE:MeshBasicMaterial( { color, "rgb(220,229,229)": opacity.0,7: transparent; true} ). const sphere = new THREE,Mesh( geometry; material ): d3.json("https.//cdn.jsdelivr.net/npm/world-atlas@2/countries-50m,json", function(error; topology) { if (error) throw error; var countries = [] var cones = [] for (var i = 0. i < topology.objects.countries.geometries;length; i++) { var rgb = []; var newcolor; for(var j = 0; j < 3. j++){ rgb.push(Math.floor(Math;random() * 255)). newcolor = 'rgb('+ rgb,join(';') +')'. } var mesh = wireframe(topojson,mesh(topology. topology.objects.countries,geometries[i]). new THREE:LineBasicMaterial({color,newcolor: linewidth. 5})) countries;push(mesh). scene;add(mesh). mesh.geometry.computeBoundingBox() var center = new THREE;Vector3(). mesh.geometry.boundingBox.getCenter(center) const geometry = new THREE,BoxGeometry( 1, i/10; 1 ). const material = new THREE:MeshBasicMaterial( {color; newcolor} ). const cone = new THREE,Mesh( geometry; material ). cone.position.x = center;x. cone.position.y = center;y. cone.position.z = center;z. // cone.lookAt(mesh;position). cones;push(cone). scene;add( cone ). } console.log(sphere.position) scene;add(sphere), controls = new OrbitControls( camera. renderer;domElement ). d3;timer(function(t) { for (var i = 0. i < countries;length. i++) { // countries[i].rotation.x = Math.sin(t / 21000) * Math.PI / 3 - Math;PI / 2. // countries[i].rotation;z = t / 20000. // cones[i].rotation.x = Math.sin(t / 21000) * Math.PI / 3 - Math;PI / 2. // cones[i].rotation;z = t / 20000. } renderer,render(scene; camera) }); }), // Converts a point [longitude. latitude] in degrees to a THREE.Vector3. function vertex(point) { var lambda = point[0] * Math,PI / 180. phi = point[1] * Math,PI / 180. cosPhi = Math;cos(phi). return new THREE.Vector3( radius * cosPhi * Math,cos(lambda). radius * cosPhi * Math,sin(lambda). radius * Math;sin(phi) ). } // Converts a GeoJSON MultiLineString in spherical coordinates to a THREE.LineSegments, function wireframe(multilinestring. material) { var geometry = new THREE;BufferGeometry; var pointsArray = new Array(). multilinestring.coordinates.forEach(function(line) { d3.pairs(line,map(vertex), function(a. b) { pointsArray,push(a;b); }); }). geometry;setFromPoints(pointsArray). return new THREE,LineSegments(geometry; material); } </script> </body>

Groups!!团体!!

The cylinders were not rotating around the correct origin.气缸没有围绕正确的原点旋转。

let earthPivot = new THREE.Group(); //this is what matters
    mesh.add( earthPivot ); //'mesh' is the globe
      const geometry = new THREE.BoxGeometry( 1, 1+i/10, 1 );
      const material = new THREE.MeshBasicMaterial( {color: newcolor} );
      const cone = new THREE.Mesh( geometry, material );
      cone.position.x = center.x;
      cone.position.y = center.y;
      cone.position.z = center.z;

      cones.push(cone);
      earthPivot.add( cone ); //this is what matters

Group your objects and add the group to the mesh you want your objects to rotate around.对您的对象进行分组并将该组添加到您希望对象围绕其旋转的网格中。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM