(Java)矢量问题 - 检查怪物是否在3个矢量

时间:2016-04-25 17:12:55

标签: java vector minecraft bukkit

目前我除了Vector之外还需要所有工具,并检查mob是否在实际三角形内。如果您想了解更多细节,请查看附图。不要担心这个圈子,我已经把它覆盖了。 A picture briefly explaining what I want the code to do and how I want it to work

目前我的代码如下:

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个三角形的矢量,我需要检查它们是否在三角形内,圆圈已被覆盖,在代码中,僵尸将是实体,玩家将成为伤害者。< / p>

2 个答案:

答案 0 :(得分:2)

要获得三角形的三个坐标或顶点,您可以使用一些三角函数和玩家的yaw。根据你的图像,三角形的一个顶点是玩家的Location。该点处三角形的内部anglelength定义了整个三角形,该Location定义了从玩家突出的三角形的两边。当定义这两个值时,我们可以找到三角形的两个剩余顶点的坐标。这是一个粗略的草图:

enter image description here

如何获取两个顶点的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 的示例:

// 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;
}

以弧度表示的角度的负正弦用于X坐标,而以弧度表示的角度的余弦用于Z坐标。

我使用了一些粒子来显示Minecraft中三角形的线条,这个粒子的长度为5,角度为90度:

enter image description here

您可以使用一种方法来检查某个点是否在二维三角形中,并将其作为此question的答案发布,并使用重心坐标。以下是适用于Bukkit / Spigot的示例方法。

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

请注意,即使getNearbyEntities方法忽略Y坐标或高度(因为它是二维检查),v1方法会查找框内的实体,在此示例中该框具有高度为4个街区,中心位于玩家的位置。因此,不会检查在玩家上方或下方超过2个区块的实体。

或者,如果您拥有三角形v2v3Polygon的三个坐标,您当然也可以使用它们来创建JavaFX contains之类的Joop提到并使用其^b^[word](#30b)方法检查实体是否在三角形内,而不是使用重心坐标方法。

答案 1 :(得分:0)

制作一个Polygon并检查一下。 更正:使用JavaFX Polygon - 获得双倍积分。

更低级别:三角形有三个向量a -> b -> c -> a,并检查带有点向量的in产品是否都是正数等。