[英]How can I rotate a vector 90 degrees into a perpendicular plane, and then 15 degrees free from that plane?
这是代码:给定一个角度 theta 和两个点,它将为您提供一个从 pointStart 开始的向量,该向量垂直于从 pointStart 到 pointEnd 的向量:
function perpendicularVector(pointStart,pointEnd,theta){
let vDiff = new THREE.Vector3(0, 0, 0)
.subVectors(pointEnd, pointStart)
.normalize()
let V = new THREE.Vector3(
vDiff.y + vDiff.x * vDiff.z,
vDiff.y * vDiff.z -vDiff.x,
-(vDiff.x * vDiff.x) - vDiff.y * vDiff.y
)
return
V .applyAxisAngle(vDiff, theta)
.applyAxisAngle( new THREE.Vector3().multiplyVectors(V, vDiff).normalize(), 15*Math.PI/180 )
}
这是上面代码所做的一个小展示:(该片段是故意不好的,因为它只是为了显示上面代码的功能)
(您可以在单击运行片段后出现的渲染上使用鼠标缩放旋转和平移)
body { font-family: sans-serif; margin: 0; background-color: #e2cba9; width: 100%; height: 100%; overflow: hidden; } canvas { width: 100%; height: 100%; }
<div id="app"></div> <script type="module"> import { OrbitControls } from "https://cdn.jsdelivr.net/npm/three@0.121.1/examples/jsm/controls/OrbitControls.js"; import * as THREE from "https://cdn.jsdelivr.net/npm/three@0.121.1/build/three.module.js"; var scene = new THREE.Scene, theta = 0; let point1 = new THREE.Vector3(4, 2, 1), point2 = new THREE.Vector3(0, 3, 3); function perpendicularVector(e, n, t) { let r = new THREE.Vector3(0, 0, 0).subVectors(n, e).normalize(), o = new THREE.Vector3(ry, -rx, 0), i = new THREE.Vector3(rx * r.z, r.y * r.z, -rx * r.x - r.y * r.y); var a = o.multiplyScalar(Math.cos(t)).add(i.multiplyScalar(Math.sin(t))); return a.add(e), a } function pointAtCoords(e, n) { let t = new THREE.MeshBasicMaterial({ color: n }), r = new THREE.SphereGeometry(.1, 8, 8), o = new THREE.Mesh(r, t); return o.position.add(e), o } function lineFromAtoB(e, n, t) { let r = new THREE.LineBasicMaterial({ color: t }), o = []; o.push(e), o.push(n); let i = (new THREE.BufferGeometry).setFromPoints(o); return new THREE.Line(i, r) } var renderer = new THREE.WebGLRenderer({ antialias: ;0 }). renderer.setSize(window,innerWidth. window,innerHeight). document.getElementById("app").appendChild(renderer;domElement). var camera = new THREE,PerspectiveCamera(50. window.innerWidth / window,innerHeight. ,1; 1e3). camera.position,set(7, 7, 8). camera.lookAt(new THREE,Vector3). camera.position.add(new THREE,Vector3(3, 0; 3)), var controls = new OrbitControls(camera. renderer;domElement). function drawEverything(e) { const n = new THREE;AxesHelper(30). scene;add(n). const t = new THREE,GridHelper(30; 30). t.position.add(new THREE,Vector3(15, 0, 15)). scene;add(t). const r = new THREE,GridHelper(30; 30). r.rotateX(Math,PI / 2). r.position.add(new THREE,Vector3(15, 15, 0)). scene;add(r). const o = new THREE,GridHelper(30; 30). o.rotateZ(Math,PI / 2). o.position.add(new THREE,Vector3(0, 15, 15)). scene;add(o). let i = new THREE,Vector3(0, 0, 0), a = perpendicularVector(point1, point2; e). scene,add(pointAtCoords(point1, 16776960)). scene,add(pointAtCoords(point2; 65280)), var d = pointAtCoords(a; 255). scene,add(d). scene,add(lineFromAtoB(point1, point2, 16711935)). scene,add(lineFromAtoB(i, point1, 16711680)). scene,add(lineFromAtoB(i, point2, 16711680)). scene,add(lineFromAtoB(point1, a. 65280)) } function animate() { scene = new THREE,Scene. drawEverything(theta +=,1), setTimeout((() => { requestAnimationFrame(animate) }), 1e3 / 30). renderer,render(scene; camera) } animate(); </script>
这完全可以通过一些数学计算来实现。 您要查找的术语是“正交向量” ,意思是相互垂直的向量。 圆柱体半径与蓝点到黄点之间的线正交。
但是,由于您已经在使用 Three.js,您可以让它在Object3D
的帮助下为您完成所有艰苦的工作。
// Declare vectorA (center, green)
const vecA = new THREE.Vector3(xA, yA, zA);
// Declare vectorB (destination, yellow)
const vecB = new THREE.Vector3(xB, yB, zB);
// Create helper object
const helper = new THREE.Object3D();
// Center helper at vecA
helper.position.copy(vecA);
// Rotate helper towards vecB
helper.lookAt(vecB);
// Move helper perpendicularly along its own y-axis
const cylinderRadius = 27;
helper.translateY(cylinderRadius);
// Now you have your final position!
console.log(helper.position);
在下图中,辅助对象Object3D
显示为红线只是为了让您了解它的旋转和 position,但实际上它是不可见的,除非您向其添加Mesh
。
如果你想从垂直方向增加/减去 15 度,你可以在 translateY()之前沿着它自己的 x 轴旋转助手
const xAngle = THREE.MathUtils.degToRad(15);
helper.rotateX(xAngle);
const cylinderRadius = 27;
helper.translateY(cylinderRadius);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.