从特定范围内的X / Y坐标中获取正确的数据,但不能超过宽度和高度

时间:2018-12-17 20:54:36

标签: mysql sql logic mariadb coordinates

我正在编写雷达逻辑,以查找附近的物体,然后将其显示在“雷达”窗口中,如下所示:

enter image description here

逻辑(可行!)如下所示-与原始逻辑略有简化:

 -- 5000 = radar distance
 -- Width can be called from a.width
 -- Height can be called from a.height

select * from positions a
    inner join positions b on b.user_id = :user_id
    left join users u on a.user_id = u.id
where 1=1
and (
    a.x >= (b.x - 5000)
 && a.x <= (b.x + 5000)
 && a.y >= (b.y - 5000)
 && a.y <= (b.y + 5000)
)

我的问题是某些对象非常大。即比雷达距离还大这意味着,如果大物体的中心点爬出雷达距离,即使高度/宽度仍在雷达距离之内,整个物体也会移动。

这里是问题的一个示例(即使在技术上仍处于雷达视距范围内,向左移动也会导致黄色形状消失,但是对象的中心点离开雷达距离导致其不在sql结果中显示) :

enter image description here

我希望我对自己的解释足够好,可以理解。这是我自己解决此问题的尝试(我没有努力上班):

尝试#1失败:

select * from positions a
    inner join positions b on b.user_id = 10
    left join users u on a.user_id = u.id
where 1=1
and (
    a.x >= ((b.x+a.width) - 5000)
 && a.x <= ((b.x-a.width) + 5000)
 && a.y >= ((b.y+a.height) - 5000)
 && a.y <= ((b.y+a.height) + 5000)
)

尝试#2失败:

select * from positions a
    inner join positions b on b.user_id = 10
    left join users u on a.user_id = u.id
where 1=1
and (
    a.x >= (b.x - 5000)
 && a.x <= (b.x + 5000)
 && a.y >= (b.y - 5000)
 && a.y <= (b.y + 5000)
)
OR (
    (a.x+a.width) >= ((b.x+a.width) - 5000)
 && (a.x-a.width) <= ((b.x-a.width) + 5000)
 && (a.y+a.height) >= ((b.y+a.height) - 5000)
 && (a.y-a.height) <= ((b.y+a.height) + 5000)
)

我认为我已经开始迷惑自己了。请让我知道是否需要其他信息。

感谢您考虑我的问题


更详尽的示例:

每个对象的高度/宽度/ x / y坐标如下:

+----+------+------+--------+-------+
| id |  x   |  y   | height | width |
+----+------+------+--------+-------+
|  1 |  100 |  100 |    150 |   150 |
|  2 | -250 |  500 |    150 |   150 |
|  3 | 5000 | 2000 |  10000 | 10000 |
+----+------+------+--------+-------+

想象一下,有一个任意的“雷达距离”设置为5,000。

如果我坐在坐标0x, 0y上,我会看到ID3。如果我移动到坐标:-100x, 0y,则我的SQL将不再检索ID3,因为坐标的中心点扩展到5,000雷达距离之外。但是-宽度向雷达扩展50%,高度向雷达扩展50%,这意味着仍应通过SQL查看和检索对象。

SQL Fiddle(将-100更改为0,您将在返回的数据中再次看到大对象)

3 个答案:

答案 0 :(得分:0)

虽然使用平方限制适当地限制了数据,但距点的距离必须是主要的SQL标准。

SELECT * FROM positions a
INNER JOIN positions b ON b.user_id = 10
WHERE POW(a.x - b.x, 2) + POW(a.y - b.y, 2) < POW(5000,2);

答案 1 :(得分:0)

您的“宽度”和“高度”听起来像是图形距离的“边界框”方法。您还按照danblack的建议进行勾股距离吗?

您实际上有两个宽度和高度(或两个半径)-一个用于雷达伸展的距离,另一个用于每个物体伸展的距离。像这样:

 AND a.x >= ((b.x+a.width) - (5000 + b.width))
 AND a.x <= ((b.x-a.width) + (5000 + b.width))
 AND a.y >= ((b.y+a.height) - (5000 + b.height))
 AND a.y <= ((b.y+a.height) + (5000 + b.height))

这意味着每个对象都有一个heightwidth(和radius)。

答案 2 :(得分:0)

好的,我想我已经解决了我的问题。我认为这可以完成工作:

set @my_x = -100;
set @my_y = 0;
set @radar_distance = 5000;

select * from positions a
where 1=1
and (
    a.x >= (@my_x - @radar_distance)
 && a.x <= (@my_x + @radar_distance)
 && a.y >= (@my_y - @radar_distance)
 && a.y <= (@my_y + @radar_distance)
)
or (
    a.x+(a.width/2) >= (@my_x - @radar_distance)
 && a.x-(a.width/2) <= (@my_x + @radar_distance)
 && a.y+(a.height/2) >= (@my_y - @radar_distance)
 && a.y-(a.height/2) <= (@my_y + @radar_distance)
)

尽管我认为,但是,即使物体的尺寸比雷达伸展得更长,它仍然会破裂。我现在要测试

是的,这可行。

我还认为我也可以在我的OR之前删除全部第一部分条件。需要测试

SQL Fiddle