首页 > 解决方案 > 如何检测坐标是否在区域内?

问题描述

我正在尝试检测玩家是否在特定区域内,我当前存储一个Region对象,其中包含我将要调用的两个变量,cornerOnecornerTwo基本上是包含 X、Y、Z 的矢量变量,我保存了所有区域在一个MutableSet

我想确保我传递给它的新向量在该区域内。
目前我尝试的是:

fun isInRegion(location: Location): Boolean {
    return regions.none { inside(location, it.cornerOne, it.cornerTwo) }
}

private fun inside(location: Location, cornerOne: Location, cornerTwo: Location): Boolean {
    return (location.x >= cornerOne.x && location.x <= cornerTwo.x) && 
           (location.z >= cornerOne.z && location.z <= cornerTwo.z)
}

我忽略了 Y,因为该区域只是水平的,所以我将忽略高度。
我目前拥有的方式适用于前 3 个区域,但是一旦我制作了第 4 个区域,它就完全停止工作,检测到第一个区域,但没有检测到其他区域。有一个更好的方法吗?有人告诉我四叉树可能会更好,但我不明白在这种情况下它是如何工作的。

PS:我也在标记 Java,因为如果有人在 Java 部分看到它,我也不介意 Java 帮助。

编辑:
在我拥有的区域代码上if (!isValidRegion()) return,这将防止区域太小:

fun isValidRegion(): Boolean {
    return !(getXSelected() < 5 || getZSelected() < 5)
}

这确保了cornerOne.x <= cornerTwo.xcornerOne.z <= cornerTwo.z

这是获取选定 X 的方法,它将获取最后一个块的 X 并从第一个块的 X 中减去。

private fun getXSelected(): Int {
    return abs(finalBlock.x - originBlock.x) + 1
}

编辑2:
所以我将inside功能更改为:

private fun inside(location: Location, cornerOne: Location, cornerTwo: Location): Boolean {
    return inBetween(location.x, cornerOne.x, cornerTwo.x) && 
           inBetween(location.z, cornerOne.z, cornerTwo.z)
}

private fun inBetween(a: Int, b: Int, c: Int): Boolean {
    return (a in b..c) || (a in c..b)
}

它确实有效,但是我不知道这是否是一个好的解决方案,因为我不知道如果过于频繁地调用它是否会对性能不利。

标签: javakotlincoordinates

解决方案


通过以下两种方式之一更改您的代码:

1)将定义更改inside为(不太优选):

private fun inside(location: Location, cornerOne: Location, cornerTwo: Location): Boolean {
    return (location.x >= Math.min(cornerOne.x, cornerTwo.x) && location.x <= Math.max(cornerOne.x, cornerTwo.x)) && 
           (location.z >= Math.min(cornerOne.z, cornerTwo.z) && location.z <= Math.max(cornerOne.z, cornerTwo.z))
}

或者改变你生成cornerOne和的方式cornerTwo

2.1)不要在你的一代中使用`abs(你将需要更多的一代迭代)

2.2)在生成角的初始候选后,cornerOne如果它们的顺序不符合预期,则在 z 轴上执行相同的操作(单独!!)


推荐阅读