【问题标题】:Line algorithm that connects all points, no diagonals连接所有点的线算法,没有对角线
【发布时间】:2016-08-04 17:32:53
【问题描述】:

我在 Tron Lightbike 上。我想去一个点,但我只能做 90 度转弯。这可以防止像这样的线条形状: 并且只允许这样的行:

存储这些移动我有一个 Queue 实现 (FIFO),它将移动存储为 Integers。

UP:    0
RIGHT: 1
DOWN:  2
LEFT:  3

我有敌人的 X 和 Y 位置,我也有我的 X 和 Y 位置。我想画一条从我到敌人的所有点都连接(没有对角线)的线,并将方向数字存储在我的Queue中。

这种线的生成方式是什么?

【问题讨论】:

  • 我相信你必须定义每次击中时的绘图行为。因此,假设您有一些网格并说您在 [2][3],并且您点击 UP,那么您必须将您的位置更新为 [2][4],然后在该位置绘制一个矩形。至少这就是我将如何在 JavaFX 中实现类似的东西
  • @SomeStudent 我没有画线,我正在尝试用移动方向填充队列,使线尽可能笔直。
  • 我想类似的逻辑仍然适用?将移动命令添加到所述队列?所以你说你知道你的位置,你知道你的敌人。然后说你在[2][3],敌人在[1][7],你可以向右做4步,向下1步;除非我误会了。您的方向将仅更新您的 X 或 Y,创建对角线的唯一方法是您的移动将同时更新两个位置。由于是90度转弯,一次只更新一个位置;至少我是这么看的
  • @SomeStudent 我知道如何从队列中填充/读取,并且我知道我可以通过直接向上然后直接向右到达那里,但我正在尝试以看起来像直线的方式进行行。
  • 所以你想做一堆近似直线的小动作。您可能需要Brezenham's line algorithm 之类的东西来计算点,然后根据您的 90 度转弯限制进行小幅调整。这个问题可能对你有帮助:stackoverflow.com/questions/4672279/…

标签: java arrays algorithm matrix line


【解决方案1】:

我假设你想要这样的结果:

这可以通过从源单元格移动到目标单元格来实现,例如一次向右和向下一个单元格,并根据从理想线到网格单元格中心点的垂直距离决定每一步:

如果 x 是网格单元大小的一半,而 α 是理想的斜率线,则从中心点到理想线的阈值垂直距离为x.(1 - tan(α))。如果距离小于这个,水平移动,如果它大于这个,垂直移动。

你也可以这样看:如果理想线只穿过当前单元格的左右边缘,则水平移动;如果它穿过当前单元格的顶部/底部边缘,则向上/向下移动。

如果理想线比水平线更垂直(切线> 1)使用类似的方法,但旋转90°:测量从单元格中心到理想线的水平距离,垂直移动更小的距离,水平移动距离更远。


此 JavaScript 代码 sn-p 显示了主要用于水平线的算法,如示例中所示,以及主要用于垂直线的等效方法,使用余切:

function tronPath(a, b) {
    var path = [a];
    var x = a.x, y = a.y;                         // starting cell
    var dx = a.x == b.x ? 0 : b.x > a.x ? 1 : -1; // right or left
    var dy = a.y == b.y ? 0 : b.y > a.y ? 1 : -1; // up or down
    if (dx == 0 || dy == 0) {
        // STRAIGHT LINE ...
    }
    else if (Math.abs(b.x - a.x) > Math.abs(b.y - a.y)) {
        // MAINLY HORIZONTAL
        var tan = (b.y - a.y) / (b.x - a.x);      // tangent
        var max = (1 - Math.abs(tan)) / 2;        // distance threshold
        while (x != b.x || y != b.y) {            // while target not reached
            var ideal = a.y + (x - a.x) * tan;    // y of ideal line at x
            if ((ideal - y) * dy >= max) y += dy; // move vertically
            else x += dx;                         // move horizontally
            path.push({x:x, y:y});                // add cell to path
        }
    }
    else {
        // MAINLY VERTICAL
        var cotan = (b.x - a.x) / (b.y - a.y);    // cotangent
        var max = (1 - Math.abs(cotan)) / 2;      // distance threshold
        while (x != b.x || y != b.y) {            // while target not reached
            var ideal = a.x + (y - a.y) * cotan;  // x of ideal line at y
            if ((ideal - x) * dx >= max) x += dx; // move horizontally
            else y += dy;                         // move vertically
            path.push({x:x, y:y});                // add cell to path
        }
    }
    return path;
}
var a = {x:1, y:1}, b = {x:11, y:5};
var path = tronPath(a, b);
document.write(JSON.stringify(path));

【讨论】:

  • 我回家后测试一下,谢谢! 'x.y' 是指 x*y 吗?
  • 确实,x.y 是程序员写成 x*y 的数学符号。
  • 我看到了 JS 代码 sn-p,你在其中更改了 X 和 Y。你能做到让 JSON 有 0、1、2 和 3 来表示方向移动吗?
  • {x += dx; dir = 2-dx;}, {y += dy; dir = 1-dy;}(或 1+dx,取决于方向)
  • 会不会只有像var max = (1 - tan * dx) / 2这样垂直变化的距离?
猜你喜欢
  • 1970-01-01
  • 2010-09-21
  • 2014-12-09
  • 2021-01-01
  • 1970-01-01
  • 2019-02-19
  • 2015-02-18
  • 2020-10-19
  • 1970-01-01
相关资源
最近更新 更多