Three.js:通过轴上的点构造平面

时间:2016-05-29 04:29:59

标签: javascript three.js

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

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

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

1 个答案:

答案 0 :(得分:2)

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

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

飞机定义有两件事:

  • 法线(垂直于平面的矢量)
  • 从原点到飞机的距离

法线可以由位于平面上的任何两个非平行向量的叉积构建,例如,因此y - xz - x

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

现在,当渲染平面时,它将具有初始法线N,我们可以创建一个四元数将向量N旋转到normal,我将使用轴角度形式在哪里

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

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

distance = dot(normal, x)

请注意,这是一个很有意义的有符号值,因为移动平面所需要做的就是将distance单位移动到法线方向

实施

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))
}

Demo

编辑1:正如@WestLangley评论的那样你可以使用plane.quaternion.setFromUnitVectors( Z, normal )通过避免使用trig函数来简化上面描述的四元数,你可以阅读更多关于这个真棒的简化distance normal 3}}

编辑2:@WestLangley添加了一个关于法线方向的注释,它完全有效,在实现中而不是检查这个我决定渲染构成平面的三角形的两个面,如果你还想制作首先要从上面的方程中看出,如果distance是负的意味着平面在看到它时离开原点,如果发生这种情况你需要翻转方向if (distance < 0) { distance *= -1 normal.multiplyScalar(-1) } 也使'始终为正

INSERT INTO context.login VALUES(?,?,?,?,?)