【问题标题】:Separating Axis thereom: Calculating the MTV for Polygon & Line Segment分离轴定理:计算多边形和线段的 MTV
【发布时间】:2017-01-08 07:53:22
【问题描述】:

几个月来,我一直在尝试编写一个函数来返回需要应用于线段的最小平移,以便将其与相交的多边形分开。我正在使用分离轴定理,似乎我能够正确计算幅度但是,返回的方向有时是错误的。然而,当返回的翻译不正确时,逆向总是正确的。

在下图中,黄线是计算用的线,紫线是黄线+平移,红线是黄线减去平移。如您所见,紫色或红色线在不同位置是正确的,但我不确定在什么条件下返回哪条线。

所以我的问题是:在什么情况下实际上需要翻转翻译,以便我的函数始终返回具有正确方向的翻译?

const Projection Polygon::Project(const Axis &a) const
{
    float min = a.Dot(GetPoint(0));
    float max = min;

    for (unsigned i = 1; i < GetPointCount(); i++)
    {
        float prj = a.Dot(GetPoint(i));

        if (prj < min)
            min = prj;

        else if (prj > max)
            max = prj;
    }

    return Projection(min, max);
}

const Projection Segment::Project(const Axis &a) const
{
    const float dot0 = a.Dot(GetPoint(0));
    const float dot1 = a.Dot(GetPoint(1));

    return Projection(std::min(dot0, dot1), std::max(dot0, dot1));
}

const float Projection::GetOverlap(const Projection &p) const
{
    // x = min & y = max
    return std::min(y - p.x, p.y - x);
}

const Vector2 Segment::GetTranslation(const Polygon &p) const
{
    float Overlap = std::numeric_limits<float>::infinity();
    Axis smallest;
    Vector2 translation;

    AxesVec axes(p.GetAxes());
    axes.push_back(GetAxis());

    for (auto && axis : axes)
    {
        const Projection pA = p.Project(axis);
        const Projection pB = Project(axis);

        if (pA.IsOverlap(pB))
        {
            const float o = pA.GetOverlap(pB);

            if (o < Overlap)
            {
                Overlap = o;
                smallest = axis;
            }
        }
    }

    translation = smallest * (Overlap + 1);

    return translation;
}

【问题讨论】:

标签: c++ algorithm math computational-geometry


【解决方案1】:

问题在于您的GetOverlap 函数返回重叠的幅度,而不是感觉(左或右)。

你可以改成这样:

if(y - p.x < p.y - x)
  return y - p.x;
else
  return x - p.y;

然后在GetTranslation:

const float o = pA.GetOverlap(pB);

if (abs(o) < abs(Overlap))
{
  ...
}

if (Overlap > 0)
  ++Overlap;
else
  --Overlap;

translation = smallest * Overlap;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-02-21
    • 1970-01-01
    • 2023-03-25
    • 2011-08-11
    • 1970-01-01
    相关资源
    最近更新 更多