我正在编写雷达逻辑,以查找附近的物体,然后将其显示在“雷达”窗口中,如下所示:
逻辑(可行!)如下所示-与原始逻辑略有简化:
-- 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结果中显示) :
我希望我对自己的解释足够好,可以理解。这是我自己解决此问题的尝试(我没有努力上班):
尝试#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
,您将在返回的数据中再次看到大对象)
答案 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))
这意味着每个对象都有一个height
和width
(和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
之前删除全部第一部分条件。需要测试