给定带有three.js的静态摄像机场景、0,0,0上的球形和任意维的矩形sprite (例如文本标签),我正在寻找一种“threejs方法”(或公式),该方法允许精灵在不需要剪裁的情况下在最小半径范围内旋转。
到目前为止,我的方法是计算球体上位置的极坐标,然后用活动维数的因子来抵消雪碧,因为它接近球体的起源。我把它稍微修改了一下:
const xPolar = Math.sin(phi) * Math.sin(theta);
const yPolar = Math.cos(phi);
const zPolar = Math.sin(phi) * Math.cos(theta);
const x = xPolar + sprite.radius * xPolar;
const y = yPolar + sprite.radius * yPolar;
const z = zPolar + (theta < 0 ? -sprite.radius : sprite.radius) * xPolar // ahem;这里的工作示例:https://codepen.io/theprojectsomething/full/xadQvK/
当phi接近极点时,请注意剪裁。在这个例子中不算太糟,但希望有一个更优雅的解决方案,并从一个更好地理解在发挥作用的人的力量!
备注:
Spherical类;手动计算是为了清晰起见。发布于 2018-09-06 09:35:53
让我们试着把我们拥有的东西正规化。首先,我们假设我们在一个坐标系中,球体在原点,视图方向是z轴。如果我们不在那个坐标系中,很容易将输入的数据转换成这个坐标系,然后进行计算,最后再转换回原来的坐标系。
我们有一个方向向量d,它指定了我们希望精灵中心出现的方向(在代码片段中,这就是您所称的xyzPolar )。此外,我们有雪碧的宽度w和高度h,我们知道宽度沿x轴扩展,高度沿y轴扩展(因为我们有一个视图对齐坐标系)。
现在,对于任意标量偏移量t,我们可以将sprite的中心指定为t * d。然后,我们的sprite上的要点由以下集合描述:
{ t * d + x * (w/2, 0, 0) + y * (0, h/2, 0) | -1 <= x <= 1, -1 <= y <= 1 }x和y是雪碧上的参数位置,其中(-1, -1)定义左下角,(0, 0)定义中心。我们特别感兴趣的是离球心最近的点,我们希望这个点是r (球体的半径),远离它。因此:
min (t * dx + x * w/2)^2 + (t * dy + y * h/2)^2 + (t * dz)^2 = r^2
x, y in [-1, 1]如果我们知道这个最近点的参数x和y,我们可以很容易地求解t,给出精灵的最终中心位置。
然而,我们不知道这些参数。让我们把这个公式分开:
( min (t * dx + x * w/2)^2 ) + ( min (t * dy + y * h/2)^2 ) + (t * dz)^2 = r^2
x in [-1, 1] y in [-1, 1]如果我们可以设置前两个项,则将最小化。
x = -2 dx t / w
y = -2 dy t / h在这种情况下,这两个条件将为零,我们可以解决t = r / abs(dz)。本质上,这将把雪碧放在z = +- r所在的xy对齐平面上。如果我们有一个无限的精灵,在这里我们没有约束x和y,这就是事实。
然而,我们没有无限的精灵。我们必须限制x和y在允许的范围内。因此,如果我们有一个候选的t,我们也可以检查它是否是一个有效的解决方案,只需使用上面的公式计算x和y,并检查它们是否在允许的范围内。如果最近的点在精灵中心的某个地方(而不是在边缘或拐角处),这将是正确的。
幸运的是,对于x和y,我们只需要检查一些可能的值。因此,该算法将计算所有可能值的t,然后检查该解决方案是否有效,并且只保留单个有效解。现在,x和y可能有哪些值?
我们已经知道了-1 <= x <= 1和-1 <= y <= 1的情况。此范围内的所有值都是等效的,因为它们使前两个项为零(对最终结果没有影响)。对于每个变量,还有两种情况。x = -1或x = 1 (y相同)。这总共给出了我们需要解决的9个组合。但我们可以做得更好。我们知道t,w和h是阳性的。因此,x和y将分别具有与dx和dy相反的标志。例如,如果dx是正的,我们只需要检查x = -1或第一个项消失的情况(本质上,这意味着如果方向向量指向右侧,雪碧的右边边缘永远不会是最近的点)。同样地,如果dx或dy完全为零,我们立即知道相应的术语消失了,我们不需要考虑另一种情况。另外,如果是dz = 0,不要评估前两个项消失的情况
所以我们只剩下四个案子了。作为参考,以下是每个变量的三种不同情况的术语:
first term
-1 = x dx^2 * t^2 - dx * t * w + w^2 / 4
-1 < x < 1 0
x = 1 dx^2 * t^2 + dx * t * w + w^2 / 4
second term
-1 = y dy^2 * t^2 - dy * t * h + h^2 / 4
-1 < y < 1 0
y = 1 dy^2 * t^2 + dy * t * h + h^2 / 4对于需要评估的四种情况,组合二次方程并求解t。最后,计算x和y,并检查它们是否匹配案例(如果您有案例x = 1,检查是否符合x >= 1等)。最后,计算出雪碧中心为t * d。
因此,不幸的是,这并不比你所拥有的更优雅,但它更准确。
https://stackoverflow.com/questions/52194353
复制相似问题