【问题标题】:Calculating the minimum radius for a circle of 3D planes计算 3D 平面圆的最小半径
【发布时间】:2018-07-28 18:13:26
【问题描述】:

假设我们有N 数量的 3D 卡片形平面围绕中心原点盘旋,面向中间。 为了计算这些平面的位置(相对于原点),我们使用以下方法:

auto Delta = FMath::DegreesToRadians(360.f) / (float)(N);
for (unsigned i = 0; i < N; i++) {
    auto X = Radius * FMath::Sin(Delta * (float)i);
    auto Y = Radius * FMath::Cos(Delta * (float)i);
    auto Location = FVector(X, Y, 0.f);
    // Spawn plane actor, set it's location, etc...
}

这很好用。但是现在,假设我们想要指定N,并用它来计算Radius,这样每个平面的边几乎不会接触,但不会发生碰撞。我们需要的是一种计算最小半径的方法。

我意识到我可以从某个高值开始,在一些actor中生成,检查它们是否正在碰撞,如果没有,则删除所有actor并将Radius减少一些值,然后重新开始,直到我们发生碰撞,但这似乎有点矫枉过正。必须有一种更简单、更数学的方法。

有什么想法吗?这是一张图像,可以帮助可视化我正在尝试计算的内容,ONLY n(边数)和 a(边宽):

请注意,n = 6a = 10 只是比喻性的例子。它们可以是任何非零值。

【问题讨论】:

  • 一定有,你能更好地解释一下X和Y是什么吗?飞机有多宽?
  • @farbiondriven 我在 UE4 中工作,所以它们是左手的、z 向上的世界坐标。 X & Y 指定围绕原点的圆上的 X/Y 点,距离原点 Radius
  • 谢谢!因此,您需要 N 个演员,并且您想知道他们可以在不相互接触的情况下从原点生成的最小半径。所以你需要知道的最后一件事是宽度,然后它是一个简单的等式。
  • @farbiondriven 我可以计算网格的宽度,但只是为了举例,假设它有 248 个单位宽,我们想要 30 个网格
  • 这可能会有所帮助 calculatorsoup.com/calculators/geometry-plane/polygon.php 答案:n = 30,a = 248 m,r = 1179.78 m,R = 1186.28 m,A = 4388790 m2,P = 7440 m,x = 168 °, y = 12°

标签: c++ algorithm math trigonometry unreal-engine4


【解决方案1】:

只需将多边形分成相同大小的三角形(披萨片)并计算其中一个三角形的中心角 (Delta)。给定三角形底边(周界边)a 的长度,使用这个角度来计算三角形的高度。高度等于半径。

auto radius = a / FMath::Tan(Delta / 2.0);

要计算每个“边”中点的坐标,只需使用极坐标:

例如

for (unsigned i = 0; i < N; i++) {
    /* ... */
    auto x = radius * FMath::Cos(i * Delta + Delta / 2.0);
    auto y = radius * FMath::Sin(i * Delta + Delta / 2.0);
}

【讨论】:

  • 我觉得换成这个答案很糟糕,尤其是当两个答案非常相似时,但你的答案实际上对我当前的代码来说更干净、更高效。
  • @RectangleEquals 不客气,这个答案和UE比较相关,而且是使用引擎功能,所以是正确的选择。
【解决方案2】:

@KillzoneKid 用我的 MSPaint 技能更新了问题以更好 说明当前情景

所以你想知道 X 和 Y 把你的飞机放在哪里?当半径已知时应该很容易。如果可行的话,也许可以试试这样的东西(2D,但你可以将其调整为 3D):

#include <iostream>
#include <cmath>

int main() {

    constexpr double PI = 3.141592653589793238;
    double sideWidth = 248;
    int countSides = 6;

    double deltaAngleRads = 2.0 / countSides * PI;
    double minRadius = sideWidth / (2 * std::tan(PI / countSides));

    double rads = 0.0;
    for (int i = 0; i < countSides; ++i)
    {
        std::cout << "X=" << minRadius * std::sin(rads) << "\tY=" << minRadius * std::cos(rads) << std::endl;
        rads += deltaAngleRads;
    }

    std::cout << "Min radius: " << minRadius << std::endl;

    return 0;
}

https://ideone.com/zo0HV1

【讨论】:

    猜你喜欢
    • 2017-04-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-11
    • 2012-03-02
    相关资源
    最近更新 更多