【问题标题】:Finding distance from point within cell to border of that cell - when moving along vector查找从单元格内的点到该单元格边界的距离 - 沿矢量移动时
【发布时间】:2021-04-23 00:07:35
【问题描述】:

我正在尝试计算我的对象在移动到另一个单元格之前将在给定单元格内行进多长时间。

这对我来说真的很重要,但我也需要知道交叉点是什么(但如果我知道与起点的距离,那将是微不足道的)。

我的一些游戏规则是:

  • 每个单元格可能有不同的移动成本
  • 整个单元格的移动成本完全相同
  • 我将对象从 A 点直线移动到 B 点
  • 我知道起始对象位置及其方向(作为矢量)
  • 单元格的边界线是由数字组成的完整整数。

我到底需要什么:

  • 如果继续朝上述方向移动,单位将在哪里耗尽移动点。

所以对于我需要计算的每个单元格:

  • 从单元格内的点到此单元格边界的距离 - 沿方向矢量移动时。

我想我跳过了一些三角学课,或者我太困了,但我找不到任何简单的解决方案来解决这个问题,也找不到快速而肮脏的解决方法。

【问题讨论】:

  • 距离公式为 C 平方 = A 平方 + B 平方。换句话说,求 X 的变化,求平方,求 Y 的变化,求平方,将平方相加,然后求平方根。

标签: generics math trigonometry


【解决方案1】:

我做了一些功能,可以满足我的需要。我不确定它是否会完全健壮(我特别害怕一些浮点舍入,这会导致将点放在 on 边框上 - 在该边框的错误一侧并导致 0 距离)。 它也打印了很多并分配了很多,但我计划缩短它,改进它并在未来更新这个答案。我想分享一些效果很好的东西——以防有人遇到类似的问题/或者我不会很快更新它。

Vector2D cellCross(Vector2D startPoint, Vector2D direction)
{
    printf("start point [x:%f|y:%f]\n",startPoint.x,startPoint.y);
    printf("direction [x:%f|y:%f]\n",direction.x,direction.y);
    if (!direction.isNormalized())
    {
        printf("in cellCross() : direction vector must be normalized!\n");
        throw "bad arg";
    }

    //cell center is like Vector2D(x,y) from my image
    Vector2D cellCenter (floor(startPoint.x)+0.5 , floor(startPoint.y)+0.5);
    printf("cell center [x:%f|y:%f]\n",cellCenter.x,cellCenter.y);
    //relative point is like Vector2D(m,n) from my image
    Vector2D relativePoint ( startPoint.x-cellCenter.x , startPoint.y-cellCenter.y );
    printf("relative point [x:%f|y:%f]\n",relativePoint.x,relativePoint.y);
    Vector2D targetCorner;
    if (direction.x>0)
        targetCorner.x=0.5;
    else
        targetCorner.x=-0.5;
    if (direction.y>0)
        targetCorner.y=0.5;
    else
        targetCorner.y=-0.5;
    printf("target corner [x:%f|y:%f]\n",targetCorner.x,targetCorner.y);

    double x_diff = targetCorner.x - relativePoint.x;
    double y_diff = targetCorner.y - relativePoint.y;
    printf("x_diff : %f\n",x_diff);
    printf("y_diff : %f\n",y_diff);

    Vector2D crossPoint;

    if (fabs(x_diff*direction.x) > fabs(y_diff*direction.y))
    { // we will cross at (targetCorner.x,[unknown]y)
        crossPoint.x = targetCorner.x;
        crossPoint.y = relativePoint.y + (direction.y * (x_diff/direction.x) );
    }
    else
    { // we will cross at ([unknown]x,targetCorner.y)
        crossPoint.y = targetCorner.y;
        crossPoint.x = relativePoint.x + (direction.x * (y_diff/direction.y) );
    }
    crossPoint.x+=cellCenter.x;
    crossPoint.y+=cellCenter.y;
    printf("cross point [x:%f|y:%f]\n",crossPoint.x,crossPoint.y);
    printf("distance : %f\n",startPoint.distanceTo(crossPoint) );
    return crossPoint;
}

展示一个示例 - 用于:

Vector2D startPoint (2.0,0.5);
Vector2D direction = Vector2D(10,-30).normalized();
Vector2D endingPoint = cellCross(startPoint,direction);

打印出来了:

start point [x:2.000000|y:0.500000]
direction [x:0.316228|y:-0.948683]
cell center [x:2.500000|y:0.500000]
relative point [x:-0.500000|y:0.000000]
target corner [x:0.500000|y:-0.500000]
x_diff : 1.000000
y_diff : -0.500000
cross point [x:2.166667|y:0.000000]
distance : 0.527046

这看起来对我和我的计算器来说是大致正确的结果。

我可以将函数结果的距离乘以该图块的移动成本,然后对下一个图块重复计算,直到我的单位达到负移动点数。通过将其移动 last_tile_movement_cost * motion_points 在同一方向上进行快速校正,应将其放置在应降落的正确位置。

【讨论】:

    猜你喜欢
    • 2015-07-26
    • 1970-01-01
    • 2016-01-16
    • 2021-09-07
    • 2020-05-23
    • 2010-10-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多