1. Вы находитесь в сообществе Rubukkit. Мы - администраторы серверов Minecraft, разрабатываем собственные плагины и переводим на различные языки плагины наших коллег из других стран.
    Скрыть объявление
Скрыть объявление
В преддверии глобального обновления, мы проводим исследования, которые помогут нам сделать опыт пользования форумом ещё удобнее. Помогите нам, примите участие!

Помогите Радиус относительно location.

Тема в разделе "Разработка плагинов для новичков", создана пользователем pro100koder, 3 авг 2018.

  1. Автор темы
    pro100koder

    pro100koder Активный участник Пользователь

    Баллы:
    76
    Обшарил немножко интернет, особо ничего не нашёл, кроме getNearblyEntities(), но с этим как-то не разобрался... Что мне нужно: из ArrayList-a доставать локацию, и в радиусе от этой локации искать игроков (К примеру, локация на координатах 1 33 7, если в радиусе 2 блоков от этой локации есть игрок/игроки, отправлять им сообщение, на пример.)
     
  2. l_Slime_l

    l_Slime_l Активный участник Пользователь

    Баллы:
    76
    Так используй getNearbyEntities и проверяй если entity - игрок.
     
  3. Exception_Prototype

    Exception_Prototype Активный участник Пользователь

    Баллы:
    96
    Сперва напиши, что ты хочешь сделать.
    А про получение игроков в радиусе полностью почитай и пойми эту тему.
     
  4. LuckyZeeRo

    LuckyZeeRo Активный участник Пользователь

    Баллы:
    96
    Имя в Minecraft:
    i0xHeX
    Код:
    java.util.List<Entity> getNearbyEntities(double x, double y, double z)
    Returns a list of entities within a bounding box centered around this entity
    Ты получаешь всех существ (включая игроков) в заданном кубоиде от текущей локации. К примеру если будет кубоид 5, 2, 5, то это значит что по X в две стороны 5 блоков, по Z в две стороны по 5 блоков, по Y в две стороны по 2 блока. Кубоид размером 10 на 4 на 10. Далее смотри по своей ситуации. Перебираешь всех этих существ в кубоиде, затем отсеиваешь только игроков, затем отсеиваешь среди них по дистанции уже реальной (если нужно тебе конкретно в радиусе).
    Простой пример:
    PHP:
    int r 10;
    Set<Entityentities world.getNearbyEntitites(locationrrr);
    Set<Playerplayers = new HashSet<>(); // Это будет конечный результат
    for (Entity entity entities) {
        if (!(
    entity instanceof Player)) continue;
        if (
    location.distance(entity.getLocation()) > r) continue;
        
    players.add((Playerentity));
    Можно реализовать проще на Java 8:
    PHP:
    int r 10;
    Set<Playerplayers world.getNearbyEntities(locationrrr).stream()
        .
    filter(entity -> entity instanceof Player)
        .
    filter(entity -> entity.getLocation().distance(location) <= r)
        .
    map(entity -> (Playerentity).collect(Collectors.toSet());
     
    Последнее редактирование: 3 авг 2018
  5. Автор темы
    pro100koder

    pro100koder Активный участник Пользователь

    Баллы:
    76
    Проблема в том, что "центр" кубоида - локация, а не существо. Вот немножечко моего г.кода:
    Код:
    public static ArrayList<Location> sl = new ArrayList<Location>();
    
    for(int i=0;i<sl.size();i++){
                Location loc = sl.get(i);
    for (Entity entity : loc.getNearbyEntities(1, 1, 1)) {
                    if (entity.getType() == EntityType.PLAYER) {
                        players.add(((Player) entity));
                    }
                }
    И там в строчке "for (Entity entity : loc.getNearbyEntities(1.0, 1.0, 1.0)) {" вылезает ошибка, добавить cast, что loc - entity, если так сделать, будет, что бы вы думали? Правильно, ошибки в консоли.
     
  6. LuckyZeeRo

    LuckyZeeRo Активный участник Пользователь

    Баллы:
    96
    Имя в Minecraft:
    i0xHeX
    Есть два варианта:
    - Брать от World -> World#getNearbyEntitites(location, rx, ry, rz)
    - Брать от существа (Entity) -> Entity#getNearbyEntitites(rx, ry, rz)

    Тебе как раз подходит 1 вариант: loc.getWorld().getNearbyEntitites(loc, ....)
     
  7. Klavy

    Klavy Активный участник Пользователь

    Баллы:
    66
    Есть еще вариант 3, итератор на всех игроков и .distance() (метод точно не помню) проверять
     
  8. LuckyZeeRo

    LuckyZeeRo Активный участник Пользователь

    Баллы:
    96
    Имя в Minecraft:
    i0xHeX
    Да, точно, как то не вспомнил даже.
    PHP:
    Set<Playerplayers world.getPlayers().stream()
            .
    filter(player -> player.getLocation().distance(location) <= r)
            .
    collect(Collectors.toSet());
     
  9. Cool_boy

    Cool_boy Активный участник Пользователь

    Баллы:
    96
    Имя в Minecraft:
    prettydude
    distanceSquared будет быстрее работать
     
  10. LuckyZeeRo

    LuckyZeeRo Активный участник Пользователь

    Баллы:
    96
    Имя в Minecraft:
    i0xHeX
    Практически одинаково. Даже при огромных массивах данных.
     
  11. Reality_SC

    Reality_SC Старожил Пользователь

    Баллы:
    123
    Имя в Minecraft:
    Reality_SC
    На огромных массивах данных не считать квадратный корень не будет быстрее, чем считать квадратный корень?
     
  12. LuckyZeeRo

    LuckyZeeRo Активный участник Пользователь

    Баллы:
    96
    Имя в Minecraft:
    i0xHeX
    Будет чутку быстрее, но почти одинаково.
     
  13. Cool_boy

    Cool_boy Активный участник Пользователь

    Баллы:
    96
    Имя в Minecraft:
    prettydude
    На stackoverflow среди комментов кто-то говорил что на половину быстрее, нормального полного ответа не нашёл. Лично мне лень тестить, фиолетово как-то, просто знаю что оно быстрее и что в ядре используют в квадрате.
     
  14. LuckyZeeRo

    LuckyZeeRo Активный участник Пользователь

    Баллы:
    96
    Имя в Minecraft:
    i0xHeX
    Я пробовал бенчмарки делать, пробовал с рандомом, без, пробовал с полной формулой (включая квадраты и т.д.), пробовал без. Кол. операций на секунду было почти одинаковое. Может быть JIT подкачал, но что есть, то пишу.
     
  15. Reality_SC

    Reality_SC Старожил Пользователь

    Баллы:
    123
    Имя в Minecraft:
    Reality_SC
    Хотелось бы видеть эти бенчмарки )) прогрев делал? ))
     
  16. LuckyZeeRo

    LuckyZeeRo Активный участник Пользователь

    Баллы:
    96
    Имя в Minecraft:
    i0xHeX
    Делал, вот сам код:
    https://privatebin.net/?6e86ec35b102a83e#KXZqBo1Siv5qkjZX8BzfdLTAVhGKPjz70aWEV714jmM=
    Вот результат:
    Код:
    Benchmark              Mode  Cnt      Score      Error   Units
    MyBenchmark.fastSqrt  thrpt    5  78900,371 ±  421,628  ops/ms
    MyBenchmark.sqrt      thrpt    5  73468,187 ± 1149,025  ops/ms
    Если найдешь здесь ошибки по оптимизации результатов, буду признателен.
    Код:
    # JMH version: 1.21
    # VM version: JDK 1.8.0_151, Java HotSpot(TM) 64-Bit Server VM, 25.151-b12
    # VM invoker: C:\Program Files\Java\jre1.8.0_151\bin\java.exe
    # VM options: -Dfile.encoding=UTF-8
    # Warmup: 3 iterations, 3 s each
    # Measurement: 5 iterations, 5 s each
    # Timeout: 10 min per iteration
    # Threads: 1 thread, will synchronize iterations
    # Benchmark mode: Throughput, ops/time
    # Benchmark: ua.i0xhex.benchmark.MyBenchmark.fastSqrt
    
    # Run progress: 0,00% complete, ETA 00:01:08
    # Fork: 1 of 1
    # Warmup Iteration   1: 74715,939 ops/ms
    # Warmup Iteration   2: 74238,698 ops/ms
    # Warmup Iteration   3: 78574,523 ops/ms
    Iteration   1: 78968,207 ops/ms
    Iteration   2: 78765,202 ops/ms
    Iteration   3: 79029,288 ops/ms
    Iteration   4: 78812,270 ops/ms
    Iteration   5: 78926,890 ops/ms
    
    
    Result "ua.i0xhex.benchmark.MyBenchmark.fastSqrt":
      78900,371 ±(99.9%) 421,628 ops/ms [Average]
      (min, avg, max) = (78765,202, 78900,371, 79029,288), stdev = 109,496
      CI (99.9%): [78478,743, 79321,999] (assumes normal distribution)
    
    
    # JMH version: 1.21
    # VM version: JDK 1.8.0_151, Java HotSpot(TM) 64-Bit Server VM, 25.151-b12
    # VM invoker: C:\Program Files\Java\jre1.8.0_151\bin\java.exe
    # VM options: -Dfile.encoding=UTF-8
    # Warmup: 3 iterations, 3 s each
    # Measurement: 5 iterations, 5 s each
    # Timeout: 10 min per iteration
    # Threads: 1 thread, will synchronize iterations
    # Benchmark mode: Throughput, ops/time
    # Benchmark: ua.i0xhex.benchmark.MyBenchmark.sqrt
    
    # Run progress: 50,00% complete, ETA 00:00:34
    # Fork: 1 of 1
    # Warmup Iteration   1: 70689,527 ops/ms
    # Warmup Iteration   2: 69663,753 ops/ms
    # Warmup Iteration   3: 73249,735 ops/ms
    Iteration   1: 73956,293 ops/ms
    Iteration   2: 73533,717 ops/ms
    Iteration   3: 73325,395 ops/ms
    Iteration   4: 73329,234 ops/ms
    Iteration   5: 73196,293 ops/ms
    
    
    Result "ua.i0xhex.benchmark.MyBenchmark.sqrt":
      73468,187 ±(99.9%) 1149,025 ops/ms [Average]
      (min, avg, max) = (73196,293, 73468,187, 73956,293), stdev = 298,398
      CI (99.9%): [72319,162, 74617,212] (assumes normal distribution)
    
    
    # Run complete. Total time: 00:01:09
    
    REMEMBER: The numbers below are just data. To gain reusable insights, you need to follow up on
    why the numbers are the way they are. Use profilers (see -prof, -lprof), design factorial
    experiments, perform baseline and negative tests that provide experimental control, make sure
    the benchmarking environment is safe on JVM/OS/HW level, ask for reviews from the domain experts.
    Do not assume the numbers tell you what you want them to tell.
    
    Benchmark              Mode  Cnt      Score      Error   Units
    MyBenchmark.fastSqrt  thrpt    5  78900,371 ±  421,628  ops/ms
    MyBenchmark.sqrt      thrpt    5  73468,187 ± 1149,025  ops/ms
     
  17. Reality_SC

    Reality_SC Старожил Пользователь

    Баллы:
    123
    Имя в Minecraft:
    Reality_SC
    Т.к. в проверяемом цикле практически нет ветвлений, кроме next(), я бы заменил его тело на:
    Код:
    index = (index + 1) % SIZE;
    return randData[index];
    Но в целом всё показательно, разница в 2.7 раза.
     
  18. LuckyZeeRo

    LuckyZeeRo Активный участник Пользователь

    Баллы:
    96
    Имя в Minecraft:
    i0xHeX
    Где ты там 2.7 нашел, по дельте или что?
    Score 1 = 78900
    Score 2 = 73468

    Кстати после правки того выше, как то скорость немного упала:
    return randData[index = (index + 1) % SIZE];
    Код:
    Benchmark              Mode  Cnt      Score      Error   Units
    MyBenchmark.fastSqrt  thrpt    5  65464,644 ±  314,550  ops/ms
    MyBenchmark.sqrt      thrpt    5  56119,564 ± 7057,873  ops/ms
    В общем примерно +10% скорости, если без Math.sqrt.
     
    Последнее редактирование: 6 авг 2018
  19. Shevchik

    Shevchik Старожил Пользователь

    Баллы:
    173
    Имя в Minecraft:
    _Shevchik_
    Не использовать fpu когда есть такая возможность - крайне здравая мысль ибо бывают конфигураци где fpu может быть один на несколько ядер (привет пацанам из amd). Либо fpu может просто тормознутым чудовищем, или его вовсе может и не быть, и тогда конец, ибо тогда будет софтовый рассчёт, который адищенски медленный (arm-softfloat).
     
  20. Reality_SC

    Reality_SC Старожил Пользователь

    Баллы:
    123
    Имя в Minecraft:
    Reality_SC
    Я в шары долбился, error-ы поделил. Сорян.

    P. S. Очень слегка модифицировал код, у меня получились такие результаты:
    Код:
    Benchmark              Mode  Cnt       Score      Error   Units
    MyBenchmark.fastSqrt  thrpt    5  152268,596 ± 3755,570  ops/ms
    MyBenchmark.sqrt      thrpt    5  128341,391 ± 5962,195  ops/ms
    
    Я значительно уменьшил SIZE, чтобы минимизировать время доступа к памяти, т.к. мы измеряем не его; а также заинлайнил руками distanceSq в distance, чтобы глубина вызовов хотя бы в исходном коде была одинаковая.
    Результат: 18.6% выигрыша.
     
    Последнее редактирование: 7 авг 2018

Поделиться этой страницей