【问题标题】:3D bounding box for an item with three axis rotations具有三轴旋转的项目的 3D 边界框
【发布时间】:2019-12-18 00:58:04
【问题描述】:

我正在尝试找到最终成为所有三个轴旋转中旋转形状的边界框的 大小。尽管为了简单起见,下面演示的示例仅旋转了 x 轴。

vector Size = <10,1,0.5>; vector Deg = <22.5,0,0>
if(Deg.x > 0 && Deg.y == 0 && Deg.z == 0){
  Y1 = Cos(Deg.x) * Size.y + Sin(Deg.x) * Size.z;
  Z1 = Cos(Deg.x) * Size.z + Sin(Deg.x) * Size.y;}

以下是 y 和 z 旋转,也就是说,如果您决定将度数更改为 和 。

if(Deg.y > 0 && Deg.x == 0 && Deg.z == 0){
  X2 = Cos(Deg.y) * Size.x + Sin(Deg.y) * Size.z;
  Z2 = Cos(Deg.y) * Size.z + Sin(Deg.y) * Size.x;}
if(Deg.z > 0 && Deg.x == 0 && Deg.y == 0){
  X3 = Cos(Deg.z) * Size.x + Sin(Deg.z) * Size.y;
  Y3 = Cos(Deg.z) * Size.y + Sin(Deg.z) * Size.x;}

虽然我迷失的部分是,如果你在两轴或三轴上旋转,我该从哪里开始。如或

是否有一个网站提供教程或示例方程式我可以查看,或者有任何提示或想法可以帮助我解决这个问题。

编辑:

我想补充一下,Nico 的评论有帮助,因为我要问的是:Axis-Aligned Bounding Box 或简称 AABB。

至于 JohanC 关于 22.5 的评论,是的 Deg = Degree。同样是的,您必须将度数转换为弧度,但我将其作为度数在示例中用于 Sin 和 Cos 输入以保持简单。

如果您想知道这个问题有什么用处。举个例子,你需要知道 AABB 来帮助计算一个方程,以保持有问题的项目与它所在的表面齐平,如果你要说在它有 旋转的情况下调整项目的大小不是完美的零旋转。

【问题讨论】:

  • 请注意,您正在编写的 22.5 似乎是度数,而大多数实现中的 sin 和 cos 都使用弧度。因此,您需要将角度除以 180 并乘以 Pi。
  • 要绕多轴旋转,您需要选择一个顺序(例如,先是 X,然后是 Y,然后是 Z)并使用一个旋转的输出向量作为下一个旋转的输入。
  • 另外,您的公式每次旋转都需要一个正窦和一个负窦。

标签: math rotation trigonometry quaternions bounding-box


【解决方案1】:

经过大量测试和调试,我找到了自己的解决方案。我将展示并解释我创建的脚本的一小部分,因为不同的编码语言的功能和选项可能会有所不同。

关于以下示例脚本的一些详细信息。度 = 度数。虽然是的,JohanC 提到的关于弧度的内容是正确的,因为即使是我使用的语言,我也必须使用函数将度数转换为弧度。并非每种语言或计算器都是这样的,但出于使其更易于阅读的意图和目的,我确实去掉了多余的部分,同时保持代码/等式的内容完好无损。同样在本例中,我将其沿 Z 轴旋转以进行演示并作为起点。

vector Size = <10,1,0.5>; //Insert your own coding language function
//for splitting the size in half with positive and negative halves.
vector min = <-5,-0.5,-0.25>; vector max = <5,0.5,0.25>;
//You'll need at least 8 points in total to do this correctly.
//I already have 8 points added down below, labeled p1 - p8
vector p1 = <max.x,max.y,max.z>; vector p2 = <max.x,min.y,max.z>;
vector p3 = <max.x,max.y,min.z>; vector p4 = <max.x,min.y,min.z>;
vector p5 = <min.x,max.y,max.z>; vector p6 = <min.x,min.y,max.z>;
vector p7 = <min.x,max.y,min.z>; vector p8 = <min.x,min.y,min.z>;
vector Deg = <0,0,22.5>
//This will give you an idea of how to setup the x,y,z for each point
//equation to make / change to fit the rotations. Plus to make it compact
//I suggest that you use list, a while loop, and etc.
x1 = p1.x * llCos(Deg.z) - p1.y * llSin(Deg.z);
y1 = p1.y * llCos(Deg.z) + p1.x * llSin(Deg.z);

我没有在上面的示例中使用几个列表、真假语句、while 循环和其他一些东西。虽然它保持简单,以展示它不太复杂的部分以及并非每种语言都具有相同的可用功能这一事实。

虽然一旦你获得了收集到的 8 个点的所有位置数据,你就可以将每个 x、y、z 点信息放入自己的列表中。然后运行方程(根据每次旋转的需要进行编辑)。之后,从每个轴旋转输出中获取最大值和最小值。然后取最大值并从中减去最小值,因为最小值总是负数。那里将为您提供边界框的 大小。

我确实想补充一点,来自 Nico 的链接略有帮助,尽管其中唯一的缺陷是“如果”您使用的语言允许矩阵或“如果”您能够创建多维数组。如果您能做到这一点,请使用 Nico 提供的链接,看看是否有帮助。

还有一些 JohanC 提示/提示也有帮助。说到这一点,当且仅当您使用 8 点方法时,关于“使用从一个旋转到下一个旋转的向量输出”的部分效果很好。否则,如果您尝试使用一个到下一个的边界框大小,第一个到第二个的旋转将正常工作,因为它此时仅在 2D 中移动,但是当您尝试使用第二个旋转边界框进行第三次旋转时,它将无法正常工作因为它将从 2D 变为 3D。

注意 - 如果您认为您有更好的方法来计算方程式或更简单的方法来解释它,请随时添加您自己的答案。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-08-29
    • 2021-08-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-01-24
    • 2014-05-07
    • 1970-01-01
    相关资源
    最近更新 更多