2016-04-25 4 views
2

В настоящее время у меня есть все необходимые инструменты, кроме векторов, и проверьте, находится ли моб внутри фактического треугольника. Если вы хотите получить более подробную информацию, взгляните на прилагаемую картинку. Не беспокойтесь о круге, я уже понял это. A picture briefly explaining what I want the code to do and how I want it to work(Java) Векторные проблемы - проверьте, находится ли монстр внутри 3 векторов

В настоящее время мой код выглядит следующим образом:

public void cleaveCone(Player damager, LivingEntity victim, int level) { 
    for(Entity lentity : damager.getNearbyEntities(3, 2, 3)) { 
     if(!(lentity instanceof LivingEntity)) continue; 
     LivingEntity entity = (LivingEntity) lentity; 
    } 
} 

В настоящее время мне нужно 3 векторов для треугольника, и мне нужно проверить, если они находятся внутри треугольника, круг уже покрыт, в коде , Зомби были бы сущностью, и игроком был бы ущерб.

+0

Нам нужен код того, что у вас уже есть. – RAnders00

+0

Я отредактировал главный пост, код должен быть виден в данный момент. Я также добавил некоторое описание ниже кода. –

+0

Вы также можете посмотреть [этот ответ] (http://stackoverflow.com/a/2049712/4464702) о том, как проверить, находится ли точка внутри треугольника (2D). – RAnders00

ответ

2

Чтобы получить три координаты или вершины треугольника, вы можете использовать некоторую тригонометрию и yaw игрока. Согласно вашему изображению, одна вершина треугольника - это Location игрока. Внутренний angle треугольника в этой точке и length, который определяет, как долго две стороны треугольника, выступающие из плеера, определяют весь треугольник. Когда эти два значения определены, мы можем найти координаты двух оставшихся вершин треугольника. Вот грубый набросок:

enter image description here

Пример того, как получить Location S двух вершин:

double angle = 90; // An example angle of 90 degrees 
double length = 5; // An example length of 5 

Location v1 = player.getLocation(); // The first vertex of the triangle, the player's location 

double yaw = v1.getYaw(); // The player's yaw (in degrees) between 0º and 360º 

World world = player.getWorld(); // The player's world 

Location v2 = new Location(world, (-Math.sin(Math.toRadians(yaw - (angle/2))) * distance) + v1.getX(), 0, (Math.cos(Math.toRadians(yaw - (angle/2))) * distance) + v1.getZ()); // The second vertex 
Location v3 = new Location(world, (-Math.sin(Math.toRadians(yaw + (angle/2))) * distance) + v1.getX(), 0, (Math.cos(Math.toRadians(yaw + (angle/2))) * distance) + v1.getZ()); // The third vertex 

Отрицательный синус угла в радианах используется для X координат в то время как косинус угла в радианах используется для Z-координаты.

Я использовал некоторые частицы, чтобы визуализировать линии треугольника в Minecraft, это один имеет длину 5 и угол 90 градусов:

enter image description here

Один метод, который вы можете использовать, чтобы проверить, является ли точка внутри двумерного треугольника размещена как ответ на этот question и использует барицентрические координаты. Вот пример метода, адаптированного для Bukkit/Spigot.

// v1, v2 and v3 are the vertices of the triangle, in no specific order 
// The Y coordinates are ignored (two dimensional) 
public static boolean isLocationInTriangle(Location location, Location v1, Location v2, Location v3) { 
    // Bunch of math... 
    double a = 0.5 * (-v2.getZ() * v3.getX() + v1.getZ() * (-v2.getX() + v3.getX()) + v1.getX() * (v2.getZ() - v3.getZ()) + v2.getX() * v3.getZ()); 
    int sign = a < 0 ? -1 : 1; 
    double s = (v1.getZ() * v3.getX() - v1.getX() * v3.getZ() + (v3.getZ() - v1.getZ()) * location.getX() + (v1.getX() - v3.getX()) * location.getZ()) * sign; 
    double t = (v1.getX() * v2.getZ() - v1.getZ() * v2.getX() + (v1.getZ() - v2.getZ()) * location.getX() + (v2.getX() - v1.getX()) * location.getZ()) * sign; 

    return s > 0 && t > 0 && (s + t) < 2 * a * sign; 
} 

Я провел некоторое тестирование с этим и, похоже, работает достаточно хорошо.

Вы можете использовать это в вашем методе так:

List<Entity> nearbyEntities = player.getNearbyEntities(8, 2, 8); // Get entities within 16x4x16 box centered around player 
for (Entity entity : nearbyEntities) { // For each Entity found 
    if (entity instanceof LivingEntity) { // If the Entity is an instance of a LivingEntity 
     LivingEntity living = (LivingEntity) entity; // Cast 
     if (isLocationInTriangle(living.getLocation(), player.getLocation(), v2, v3)) { // If the LivingEntity is inside the triangle 
      living.damage(6); // Damage the entity (just as an example) 
     } 
    } 
} 

Обратите внимание, что даже если метод IsLocationInTriangle игнорирует Y координаты или высоты (так как это двухмерная проверка), метод getNearbyEntities ищет лиц внутри поле, и в этом примере это поле имеет высоту 4 блока, причем центр находится в месте нахождения игрока. Поэтому объекты, расположенные более чем на 2 блока выше или ниже игрока, не будут проверяться.

В качестве альтернативы, как только у вас есть три координаты треугольника v1, v2 и v3, вы могли бы, конечно, использовать их для создания JavaFX Polygon как Joop упоминался и использовать его метод contains, чтобы проверить, является ли предприятие находится внутри треугольник вместо использования метода барицентрических координат.

+0

Большое вам спасибо, это именно то, что мне было нужно, и благодаря вам, объясняющим вещи, я сейчас запомню это. Пальцы вверх –

0

Сделайте Polygon и проверьте это. Исправление: используйте JavaFX Polygon - для двойных точек.

Более низкий уровень: есть три вектора a -> b -> c -> a для треугольника и проверьте, что все продукты с векторным вектором положительные или такие.

+0

Я пытался получить b и c векторы, но мне это не удалось, потому что я не могу понять формулу. –

+0

Попробуйте Polygon и его содержит. Он работает с точками x, y. –

+0

Minecraft использует значения «double» для обозначения местоположений, и поскольку треугольник охватывает только несколько блоков, я предполагаю, что координаты треугольника должны быть точными для большего, чем одно целое. –

 Смежные вопросы

  • Нет связанных вопросов^_^