【问题标题】:How to calculate rotation for geometries on a sphere so that they face outwards如何计算球体上几何图形的旋转,使它们朝外
【发布时间】:2020-12-27 17:06:54
【问题描述】:

我有一个sphere,我正在根据从坐标(半径 = 200)转换的点(x、y、z)在表面上添加圆柱体。现在我被困在如何单独计算每个圆柱体从球体面向外所需的旋转。

我正在使用 Matrix4(makeRotationX(); 和 Matrix4(makeRotationZ(); 来旋转几何体。

function drawCylinder(x_values, y_values, z_values, scene) {

  var cylinderHeight = 20;
  var rotationX = new THREE.Matrix4().makeRotationX(Math.PI/2);
  var rotationZ = new THREE.Matrix4().makeRotationZ(Math.PI/2);

  var axis = new THREE.Vector3(x_values, y_values, z_values);
  var geometry = new THREE.CylinderGeometry(2, 2, cylinderHeight, 32 );
  geometry.translate(x_values[0], y_values[0], z_values[0]);
  //geometry.applyMatrix4(rotationZ);

  var material = new THREE.MeshBasicMaterial({
    color: 0x5affb5
  });
  var mesh = new THREE.Mesh(geometry, material);
  scene.add(mesh);

  clearArrays();

}

示例(x:– 71.2237692444388,y:– 47.741840449353155,z:– 182.89858218456328)

【问题讨论】:

标签: math three.js rotation


【解决方案1】:

您没有在问题中说明球体中心的坐标。让我叫他们(x0, y0, z0)

球体半径为R = 200,圆柱体高度为cylinderHeight = 20

圆柱体底部有坐标(x, y, z)

由于您希望圆柱体在地球上“垂直”定向,因此您希望圆柱体的轴位于径向方向;换句话说,您希望球体的中心、圆柱体的底部和圆柱体的顶部对齐。另一种表述方式是,您希望两个向量 Center->Bottom 和 Center->Top 共线。另一种表述方式是,您希望这两个向量的坐标成比例。

由于您知道所涉及的所有长度,因此比例因子必须是(R + cylinderHeight) / R

最后圆柱体顶部的坐标(xT, yT, zT)由下式给出:

(xT-x0, yT-y0, zT-z0) = (R + cylinderHeight) / R * (x-x0, y-y0, z-z0)

xT = (R + cylinderHeight) * (x-x0) / R + x0
yT = (R + cylinderHeight) * (y-y0) / R + y0
zT = (R + cylinderHeight) * (z-z0) / R + z0

【讨论】:

  • 如果您可以控制对象底部和顶部的位置,这将是一个有效的解决方案,但据我所知,您只能控制中心。无论如何,清洁解决方案并保存以备将来使用。
【解决方案2】:

你可以使用quaternion.setFromUnitVectors(),有一个基向量和一个圆柱位置向量:

body{
  overflow: hidden;
  margin: 0;
}
<script type="module">
import * as THREE from "https://threejs.org/build/three.module.js";
import {OrbitControls} from "https://threejs.org/examples/jsm/controls/OrbitControls.js";

let scene = new THREE.Scene();
let camera = new THREE.PerspectiveCamera(60, innerWidth / innerHeight, 1, 100);
camera.position.setScalar(10);
let renderer = new THREE.WebGLRenderer();
renderer.setSize(innerWidth, innerHeight);
document.body.appendChild(renderer.domElement);

let controls = new OrbitControls(camera, renderer.domElement);

let radius = 5;
let s = new THREE.Mesh(new THREE.SphereBufferGeometry(radius, 36, 18), new THREE.MeshNormalMaterial({wireframe: true}));
scene.add(s);

// cylinders
let g = new THREE.CylinderBufferGeometry(0.125, 0.125, 1, 8);
g.translate(0, 0.5, 0);
let m = new THREE.MeshBasicMaterial({color: "orange"});
let baseV = new THREE.Vector3(0, 1, 0);
let dirV = new THREE.Vector3();
for(let i = 0; i < 50; i++){
  let c = new THREE.Mesh(g, m);
  c.position.setFromSphericalCoords(
    radius,
    Math.random() * Math.PI,
    Math.random() * Math.PI * 2
  );
  c.quaternion.setFromUnitVectors(baseV, dirV.copy(c.position).normalize());
  scene.add(c);
}

renderer.setAnimationLoop(()=>{
  renderer.render(scene, camera);
});

</script>

【讨论】:

  • 谢谢!在我理解了一切意味着什么之后,它就像一种魅力:)
猜你喜欢
  • 2018-08-19
  • 2017-08-13
  • 2022-01-24
  • 1970-01-01
  • 1970-01-01
  • 2013-04-08
  • 1970-01-01
  • 2016-03-19
  • 1970-01-01
相关资源
最近更新 更多