gpt4 book ai didi

javascript - 比使用 Bresenham 算法更好的线路选择?

转载 作者:行者123 更新时间:2023-12-05 01:10:07 25 4
gpt4 key购买 nike

我在 HTML Canvas 上画线,并使用不太精确的二维数组(表示 10x10 像素的 block ),我在其中使用 Bresenham 算法“画”线以存储线 ID,因此我可以使用该数组查看选择了哪一行。

这行得通,但我希望它更准确——不是我使用的 10x10 大小(我喜欢这样,我不必完全点击该行),但是当我绘制该数组的表示时在我的实际 Canvas 上,我看到有很多 10x10 block 没有填充,即使线穿过它们:

enter image description here

有更好的解决方案吗?我想要的是捕获实际线穿过的所有网格 block 。

最佳答案

没有看到您的代码,我认为您在使用 Bresenham 算法填充查找表时出现了舍入错误,或者您在运行算法之前缩放了坐标。

jsFiddle显示了我的想法,并且正方形完美对齐。

enter image description here

HTML

<canvas id="myCanvas"></canvas>

CSS

#myCanvas {
width: 250px;
height: 250px;
}

JavaScript

var $canvas = $("#myCanvas"),
ctx = $canvas[0].getContext("2d");

ctx.canvas.width = $canvas.width();
ctx.canvas.height = $canvas.height();

function Grid(ctx) {
this._ctx = ctx;
this._lines = [];
this._table = [];
this._tableScale = 10;
this._createLookupTable();
}
Grid.prototype._createLookupTable = function() {
this._table = [];
for (var y = 0; y < Math.ceil(ctx.canvas.height / this._tableScale); y++) {
this._table[y] = [];
for (var x = 0; x < Math.ceil(ctx.canvas.width / this._tableScale); x++)
this._table[y][x] = null;
}
};
Grid.prototype._updateLookupTable = function(line) {
var x0 = line.from[0],
y0 = line.from[1],
x1 = line.to[0],
y1 = line.to[1],
dx = Math.abs(x1 - x0),
dy = Math.abs(y1 - y0),
sx = (x0 < x1) ? 1 : -1,
sy = (y0 < y1) ? 1 : -1,
err = dx - dy;
while(true) {
this._table[Math.floor(y0 / 10)][Math.floor(x0 / 10)] = line;
if ((x0 == x1) && (y0 == y1)) break;
var e2 = 2 * err;
if (e2 >- dy) { err -= dy; x0 += sx; }
if (e2 < dx) { err += dx; y0 += sy; }
}
};
Grid.prototype.hitTest = function(x, y) {
var ctx = this._ctx,
hoverLine = this._table[Math.floor(y / 10)][Math.floor(x / 10)];
ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
this._lines.forEach(function(line) {
line.draw(ctx, line === hoverLine ? "red" : "black");
});
};
Grid.prototype.drawLookupTable = function() {
ctx.beginPath();
for (var y = 0; y < this._table.length; y++)
for (var x = 0; x < this._table[y].length; x++) {
if (this._table[y][x])
ctx.rect(x * 10, y * 10, 10, 10);
}
ctx.strokeStyle = "rgba(0, 0, 0, 0.2)";
ctx.stroke();
};
Grid.prototype.addLine = function(line) {
this._lines.push(line);
this._updateLookupTable(line);
};
Grid.prototype.draw = function() {
var ctx = this._ctx;
ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
this._lines.forEach(function(line) {
line.draw(ctx);
});
};

function Line(x0, y0, x1, y1) {
this.from = [ x0, y0 ];
this.to = [ x1, y1];
}
Line.prototype.draw = function(ctx, style) {
ctx.beginPath();
ctx.moveTo(this.from[0], this.from[1]);
ctx.lineTo(this.to[0], this.to[1]);
ctx.strokeStyle = style || "black";
ctx.stroke();
};

var grid = new Grid(ctx);
grid.addLine(new Line(80, 10, 240, 75));
grid.addLine(new Line(150, 200, 50, 45));
grid.addLine(new Line(240, 10, 20, 150));
grid.draw();
grid.drawLookupTable();

$canvas.on("mousemove", function(e) {
grid.hitTest(e.offsetX, e.offsetY);
grid.drawLookupTable();
});

关于javascript - 比使用 Bresenham 算法更好的线路选择?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28011113/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com