[英](Java) Vector problems - Check if a monster is inside 3 Vectors
目前,除了矢量和檢查生物是否在實際三角形內之外,我擁有所有需要的工具。 如果您想了解更多詳細信息,請查看所附圖片。 別擔心圓圈,我已經知道了。
目前我的代碼如下所示:
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 個向量,我需要檢查它們是否在三角形內,圓圈已經被覆蓋,在代碼中,僵屍是實體,玩家是破壞者。
要獲得三角形的三個坐標或頂點,您可以使用一些三角學和玩家的yaw
。 根據您的圖像,三角形的一個頂點是玩家的Location
。 內部angle
在該點的三角形和一個的length
,其限定了三角形從播放器突出的兩側多久是,定義整個三角形。 定義這兩個值后,我們就可以找到三角形剩余兩個頂點的坐標。 這是一個粗略的草圖:
如何獲取兩個頂點的Location
的示例:
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 度:
您可以用來檢查一個點是否在二維三角形內的一種方法被發布為該問題的答案,並使用重心坐標。 這是一個適用於 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
方法getNearbyEntities
查找框內的實體,在此示例中,框的高度為 4 個塊,中心位於玩家的位置。 因此,玩家上方或下方超過 2 個方塊的實體將不會被檢查。
或者,一旦您擁有三角形v1
、 v2
和v3
的三個坐標,您當然也可以使用它們來創建像Joop提到的 JavaFX Polygon
並使用其contains
方法檢查實體是否在三角形內,而不是使用重心坐標法。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.