Как определить, находится ли координата внутри области? - PullRequest
1 голос
/ 30 января 2020

Я пытаюсь определить, находится ли игрок внутри определенной области c, в настоящее время я храню объект Region, который содержит две переменные, которые я буду называть cornerOne и cornerTwo, углы в основном векторные переменные, содержащие 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.x и cornerOne.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)
}

И это сработало, однако Я не знаю, будет ли это хорошим решением, так как я не знаю, будет ли это ухудшать производительность, если он вызывается слишком часто.

1 Ответ

0 голосов
/ 30 января 2020

Измените свой код одним из двух способов:

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 xs, если их порядок не такой, как ожидалось, и сделать то же самое на оси z (отдельно !!)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...