#javascript #three.js #3d
Вопрос:
Я пытаюсь создать сферу с широтой и длинными координатами.
Широтные координаты представляют границу страны.
В настоящее время я конвертирую координаты 2d Lat Long в 3d-координаты. использование радиуса
Моя цель — создать геометрию из координат.
Я уже пробовал это с помощью строк
И с ConvexGeometry
Это должно выглядеть примерно так:
https://www.turbosquid.com/3d-models/planet-earth-countries-3d-c4d/433487
При этом страны становятся интерактивными
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
const renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
camera.position.z = 100;
let radius = 200;
var RAD2DEG = 180 / Math.PI
var DEG2RAD = Math.PI / 180
/**
* Convert [lat,lon] polar coordinates to [x,y,z] cartesian coordinates
* @param {Number} lon
* @param {Number} lat
* @param {Number} radius
* @return {Vector3}
*/
function polarToCartesian(lon, lat, radius) {
var phi = (90 - lat) * DEG2RAD
var theta = (lon 180) * DEG2RAD
return {
x: -(radius * Math.sin(phi) * Math.sin(theta)),
y: radius * Math.cos(phi),
z: radius * Math.sin(phi) * Math.cos(theta),
}
}
/**
* Convert [x,y,z] cartesian coordinates to polar [lat,lon]
* @param {Vector3} coord
* @return {Array<Number>}
*/
function cartesianToPolar(coord, radius) {
var lon = Math.atan2(coord.x, -coord.z) * RAD2DEG
var length = Math.sqrt(coord.x * coord.x coord.z * coord.z)
var lat = Math.atan2(coord.y, length) * RAD2DEG
return [lon, lat]
}
const convex = new THREE.Group();
const lines = new THREE.Group();
const features = json.features;
const intersectObjects = []
features.forEach(feature => {
let geometry = feature.geometry;
let coordinates = geometry.coordinates;
coordinates.forEach(cords => {
cords.forEach(vectors => {
const points = [];
const points2 = [];
for (let index = 0; index < vectors.length; index ) {
let coord = vectors[index];
let vec3 = polarToCartesian(-coord[0], coord[1], radius);
points2.push(vec3.x, vec3.y, vec3.z);
points.push(new THREE.Vector3(vec3.x, vec3.y, vec3.z));
}
let geometry = new THREE.BufferGeometry().setFromPoints(points);
const material = new THREE.MeshBasicMaterial( { color: 0xff1100 } );
const mesh = new THREE.Mesh( geometry, material );
scene.add(mesh);
intersectObjects.push(mesh);
});
});
});
renderer.render(scene, camera);
const c = new THREE.OrbitControls(camera, renderer.domElement);
c.enableDamping = true; // an animation loop is required when either damping or auto-rotation are enabled
c.dampingFactor = 0.05;
c.enableRotate = true
c.autoRotate = true
c.autoRotateSpeed = 0.1
c.enablePan = false
c.panSpeed = 0.1
const animate = function () {
requestAnimationFrame(animate);
c.update();
renderer.render(scene, camera);
};
animate();
window.addEventListener('resize', onWindowResize);
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
}
let raycaster = new THREE.Raycaster();
let pointer = new THREE.Vector2();
document.addEventListener('pointerdown', onPointerDown);
function onPointerDown(event) {
pointer.set((event.clientX / window.innerWidth) * 2 - 1, - (event.clientY / window.innerHeight) * 2 1);
raycaster.setFromCamera(pointer, camera);
const intersects = raycaster.intersectObjects(intersectObjects);
if (intersects.length > 0) {
const intersect = intersects[0];
for (let i = 0; i < intersects.length; i ) {
intersects[i].object.material = new THREE.MeshBasicMaterial({ color: 0x00ff00 });
}
renderer.render(scene, camera);
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js"></script>
<script src="https://unpkg.com/three@0.133.1/examples/js/math/ConvexHull.js"></script>
<script src="https://unpkg.com/three@0.133.1/examples/js/geometries/ConvexGeometry.js"></script>
<script src="https://unpkg.com/three@0.133.1/examples/js/controls/OrbitControls.js"></script>
<script>
const json = {
"type":"FeatureCollection",
"features":[
{
"type":"Feature",
"properties":{
"name":"Germany"
},
"geometry":{
"type":"MultiPolygon",
"coordinates":[
[
[
[
9.921906,
54.983104
],
[
9.93958,
54.596642
],
[
10.950112,
54.363607
],
[
10.939467,
54.008693
],
[
11.956252,
54.196486
],
[
12.51844,
54.470371
],
[
13.647467,
54.075511
],
[
14.119686,
53.757029
],
[
14.353315,
53.248171
],
[
14.074521,
52.981263
],
[
14.4376,
52.62485
],
[
14.685026,
52.089947
],
[
14.607098,
51.745188
],
[
15.016996,
51.106674
],
[
14.570718,
51.002339
],
[
14.307013,
51.117268
],
[
14.056228,
50.926918
],
[
13.338132,
50.733234
],
[
12.966837,
50.484076
],
[
12.240111,
50.266338
],
[
12.415191,
49.969121
],
[
12.521024,
49.547415
],
[
13.031329,
49.307068
],
[
13.595946,
48.877172
],
[
13.243357,
48.416115
],
[
12.884103,
48.289146
],
[
13.025851,
47.637584
],
[
12.932627,
47.467646
],
[
12.62076,
47.672388
],
[
12.141357,
47.703083
],
[
11.426414,
47.523766
],
[
10.544504,
47.566399
],
[
10.402084,
47.302488
],
[
9.896068,
47.580197
],
[
9.594226,
47.525058
],
[
8.522612,
47.830828
],
[
8.317301,
47.61358
],
[
7.466759,
47.620582
],
[
7.593676,
48.333019
],
[
8.099279,
49.017784
],
[
6.65823,
49.201958
],
[
6.18632,
49.463803
],
[
6.242751,
49.902226
],
[
6.043073,
50.128052
],
[
6.156658,
50.803721
],
[
5.988658,
51.851616
],
[
6.589397,
51.852029
],
[
6.84287,
52.22844
],
[
7.092053,
53.144043
],
[
6.90514,
53.482162
],
[
7.100425,
53.693932
],
[
7.936239,
53.748296
],
[
8.121706,
53.527792
],
[
8.800734,
54.020786
],
[
8.572118,
54.395646
],
[
8.526229,
54.962744
],
[
9.282049,
54.830865
],
[
9.921906,
54.983104
]
]
]
]
}
}
]
}
</script>