Three.js:通过轴上的点构造平面 [英] Three.js: Construct plane through points on axes

查看:414
本文介绍了Three.js:通过轴上的点构造平面的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试创建一个在x轴上穿过(例如)2的平面,y轴上的3个和z轴上的12个(换句话说,平面6x + 4y + z = 12)。

I'm trying to create a plane that passes through (say) 2 on the x-axis, 3 on the y-axis and 12 on the z-axis (in other words, the plane 6x + 4y + z = 12).

到目前为止,我尝试使用点积创建一个水平面并围绕3个轴旋转,这使我接近所需的平面,但是它永远不会完全正确。

I've so far tried creating a horizontal plane and rotating it around the 3 axes using the dot product, which gave me close to the desired plane, but it would never be exactly right.

我怀疑我需要使用Matrix4,但找不到合适的例子。

I suspect I need to use Matrix4, but couldn't find a suitable example.

推荐答案

这是建立它的一种方法,从你的例子中你有三个向量是规范基础的倍数 i,j,k 例如

Here's one way to build it, from your example you have three vectors which are multiples of the canonical basis i,j,k e.g.

x = x_0 * [1 0 0]
y = y_0 * [0 1 0]
z = z_0 * [0 0 1]

飞机定义有两件事:


  • 法线(垂直于平面的矢量)

  • 从原点到平面的距离

正常可以从cro建立ss位于平面上的任何两个非平行向量的乘积,例如 y - x z - x 因此

The normal can be built from the cross product of any two non-parallel vectors that lie on the plane, e.g. y - x and z - x therefore

normal = normalize(cross(y - x, z - x))

现在当渲染飞机时它将有一个初始正常 N ,我们可以创建一个四元数旋转向量 N 正常,我将使用轴角形式

Now when the plane is rendered it will have an initial normal N, we can create a quaternion rotates the vector N to normal, I'll use the axis angle form where

q_{axis} = cross(N, normal)
q_{angle} = acos(dot(N, normal))

接下来可以通过法线和平面上任何点的点积找到飞机的距离,例如

Next the distance to the plane can be found with the dot product of the normal and any point on the plane e.g.

distance = dot(normal, x)

请注意,这是一个有符号的值,很棒,因为移动飞机只需要移动它距离正常方向的单位

Note that this is a signed value which is awesome since all you have to do to move the plane is move it distance units in the normal direction

var plane = new THREE.Mesh(
  new THREE.PlaneGeometry(10, 10),
  new new THREE.MeshNormalMaterial()
)
// ...
function rotatePlane(x, y, z) {
  var xy = new THREE.Vector3().subVectors(y, x)
  var xz = new THREE.Vector3().subVectors(z, x)
  var normal = new THREE.Vector3().crossVectors(xy, xz).normalize()

  // initial normal vector of the plane
  var Z = new THREE.Vector3(0, 0, 1)
  var axis = new THREE.Vector3().crossVectors(Z, normal).normalize()
  var angle = Math.acos(Z.dot(normal))
  var q = new THREE.Quaternion().setFromAxisAngle(axis, angle)
  plane.rotation.setFromQuaternion(q)

  var distanceToPlane = x.dot(normal)
  plane.position.copy(normal.clone().multiplyScalar(distanceToPlane))
}



演示



编辑1:如@WestLangley所述,您可以使用 plane.quaternion.setFromUnitVectors(Z,normal) 引擎盖下的内容简化了描述的四元数以上通过避免使用trig函数,你可以阅读更多关于这个真棒的简化文章

Demo

Edit 1: as @WestLangley commented you can use plane.quaternion.setFromUnitVectors( Z, normal ) which under the hood simplifies the quaternion described above by avoiding the use of trig functions among other things, you can read more about the simplification in this awesome article

编辑2:@WestLangley添加了关于正常方向的评论,该评论完全有效,在实现而不是检查这个我决定渲染构成平面的三角形的两个面,如果你还想让平面永远不看原点你首先从上面的方程中知道如果距离是负的,这意味着飞机在看着它的同时远离原点,如果发生这种情况,你需要翻转正常的方向还使距离始终为正

Edit 2: @WestLangley added a comment about the direction of the normal which is completely valid, in the implementation instead of checking for this I decided to render both faces of the triangles that make the plane, if you also want to make the plane to never look at the origin first you realize from the above equations that if distance is negative that means that the plane moved away from the origin while looking at it, if this happens you need to flip the direction of the normal which also makes distance to always be positive

if (distance < 0) {
  distance *= -1
  normal.multiplyScalar(-1)
}

这篇关于Three.js:通过轴上的点构造平面的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆