从x/y坐标获取一定范围内的正确数据,但包括宽度和高度

vecaoik1  于 2021-06-15  发布在  Mysql
关注(0)|答案(3)|浏览(373)

我正在编写雷达逻辑,找到附近的物体,然后在“雷达”窗口中显示它们:

逻辑(有效!)如图所示-比原来稍微简化:

-- 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)
)

我的问题是有些物体很大。i、 甚至超过雷达距离。这意味着,如果大物体的中心点爬出雷达距离,即使高度/宽度仍在雷达距离内,整个物体也会移动。
下面是一个问题的例子(向左移动会导致黄色形状消失,即使从技术上讲它仍然在雷达视距中,但是对象的中心点离开雷达距离,导致它不会显示在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 |
+----+------+------+--------+-------+

假设有一个任意的“雷达距离”设置为5000。
如果我坐在坐标上: 0x, 0y 我看得见 ID3 . 如果我移动到坐标: -100x, 0y 我的sql不再检索 ID3 因为坐标的中心点超出了5000雷达距离。但是-宽度扩展到雷达的50%,高度扩展到雷达的50%,这意味着该对象仍然可以通过sql看到和检索。
sql fiddle(更改 -1000 您将再次看到返回数据中的大对象)

myzjeezk

myzjeezk1#

您的“宽度”和“高度”听起来像是图形距离的“边界框”方法。你也按照丹布莱克的建议做毕达哥拉斯距离吗?
实际上,你有两个宽度和高度(或两个半径)--一个是你的雷达伸展的距离,一个是每个物体伸展的距离。比如:

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 )对于每个对象。

lkaoscv7

lkaoscv72#

好吧,我想我找到了问题的答案。我认为这就是工作:

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小提琴

mwyxok5s

mwyxok5s3#

虽然使用平方限制可以适当地限制数据,但与点的距离需要是主要的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);

相关问题