繁体   English   中英

如何将矢量旋转 90 度到垂直平面,然后再从该平面旋转 15 度?

[英]How can I rotate a vector 90 degrees into a perpendicular plane, and then 15 degrees free from that plane?

我最终想要的是一个向量,给出下图中绿线的方向,只知道黄点和绿点的position。
更具体地说,它的角度可以是随机的,只要它的端点在圆柱体的绿蓝色表面上的某个地方结束。 因此,圆柱体周围 360° 自由,大约 15° 限制在圆柱体的边缘。

圆柱垂直于黄点和绿点的线。

长度不重要,重要的是方向。

我的主要问题是我不知道如何 go 从矢量黄色到绿点,再到垂直于它的任何矢量。

PS 这些东西都没有在 axyz 轴上对齐。 该网格不是 xyz,只是为了帮助可视化。 在此处输入图像描述

这是代码:给定一个角度 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.

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