计算 3D 平面圆的最小半径

Calculating the minimum radius for a circle of 3D planes

假设我们有 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...
}

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

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

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

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

@KillzoneKid Updated question with my MSPaint skills to better illustrate the current scenario

所以你想知道 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

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

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

要计算每个 "side" 中点的坐标,只需使用极坐标:

例如:

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