Elite Games - Свобода среди звезд!
.
ВНИМАНИЕ!
Наша конференция посвящена космической тематике и компьютерным играм.
Политические вопросы и происходящие в мире события в данный момент на нашем сайте не обсуждаются!

  » Расчет точки упреждения | страница 2
Конференция предназначена для общения пилотов. Для удобства она разделена на каналы, каждый из которых посвящен определенной игре. Пожалуйста, открывайте темы только в соответствующих каналах и после того, как убедитесь, что данный вопрос не обсуждался ранее.

Поиск | Правила конференции | Фотоальбом | Регистрация | Список пилотов | Профиль | Войти и проверить личные сообщения | Вход

   Страница 2 из 2
На страницу: Пред.  1, 2 | Все страницы
Поиск в этой теме:
Канал Игры Мечты: «Расчет точки упреждения»
akm
 470 EGP


Рейтинг канала: 1(3)
Репутация: 173
Сообщения: 1638
Откуда: Паразит Прайм
Зарегистрирован: 23.10.2002
синусы, кватернионы, дифференциальные уравнения.... главное хвост! ой, т.е. задачу можно решить в лоб численными методами, причем с минимальной нагрузкой движка расчетами. Я такую задачу успешно решил даже на тормознутом скрипт-движке Х2, вот код:
Код:

001  $step.duration = 2  // в секундах
002  $num.of.steps = 9   // (num.steps x duration) определяет временной интервал, в теч. которого будет усредняться вектор скорости цели
003 
010  $pmax = 3
011  $Interception.point =  array alloc: size=$pmax
012  $Tgt.positions =  array alloc: size=$num.of.steps
013  $n = 0
014  $positions.saved = $n
015 
016  // -----------------
017  // Здесь синхронизация с глобальным таймером до 1сек
018  // т.е. выполнение тут останавливается до момента перехода таймера ч-з целую секунду
019  // -----------------
020  $cur.time = значение глоб. таймера
021
022  $cur.Tgt.pos = $target -> get position as array
023  $Tgt.positions[$n] = $cur.Tgt.pos
024  $estim.dist = get distance between [THIS] and $target
026   
027  while (надо стрелять)
028   
029    $t = ( 10 * $estim.dist ) / $our.speed   // time is in 0.1 sec
033    inc $n
034    if ($n == $num.of.steps)    $n = 0
035
036    if not ($positions.saved == $num.of.steps)
037      inc $positions.saved
038      $delta = $positions.saved * $step.duration * 10
029    else
040      [THIS] -> set local variable: name='Max.Precition.Reached' value=[TRUE]
041    end
042   
043    $time2sync = $cur.time + $step.duration
044  // -----------------
045  // Здесь синхронизация с глобальным таймером до $time2sync
046  // т.е. выполнение тут останавливается до момента перехода таймера через $time2sync
047  // -----------------
048    $cur.time = значение глоб. таймера
049
050    skip if (надо стрелять)
051      break
052    skip if $target -> exists
053      break
054    $cur.Tgt.pos = $target -> get position as array
055    $our.pos = [THIS] -> get position as array
056    $prev.pos = $n - $positions.saved
057    if ($prev.pos < 0)    $prev.pos = $prev.pos + $num.of.steps
058
059    $prev.Tgt.pos = $Tgt.positions[$prev.pos]
060   
061    $p = $pmax
062    while $p
063      dec $p =
064      $x0 = $prev.Tgt.pos[$p]
065      $x = $cur.Tgt.pos[$p]
066      $x = ( ( $x - $x0 ) * $t ) / $delta + $x
067      $Interception.point[$p] = $x
068    end
069   
070    $estim.dist = [THIS] -> get distance to: position array=$Interception.point
071    $y = $Interception.point[1]
072    $z = $Interception.point[2]
073    $nav.mark -> set position: x=$x y=$y z=$z
074    $Tgt.positions[$n] = $cur.Tgt.pos
075  end

и уже после десятка итераций мы имеем очень точное направление на цель $target. Более того, каждый последующий залп, когда нам нужно уточнить направление на цель (в данном примере каждые 2 сек), повторять эти 10 итераций не требуется! Достаточно одной - и у нас опять точная координата цели!
Собственно, искомое направление на цель - это $nav.mark -> set position: x=$x y=$y z=$z,
а точнее это даже будет точка "столкновения" в пространстве, если цель не изменит вектор скорости.
Исходные параметры - это:
$our.speed - модуль скорости снаряда (или модуль скорости корабля + скорости снаряда, если они суммируются - зависит от физики)
$cur.Tgt.pos = $target -> get position as array - тек.координаты цели
$our.pos = [THIS] -> get position as array - тек.координаты нашего корабля.
Вместо задержек для синхронизации, лучше запускать эти части процедуры по прерыванию от таймера (просто такого функционала в Х2 нет), причем в фоновом режиме, а сам корабль попросту должен всегда стрелять в $nav.mark, а уточнение этого маркера будет непрерывно в бэкграунде.
Учитывая, что CPU все равно тригонометрию и даже корни рассчитывает численными методами, то оптимальнее данного кода придумать попросту невозможно Подмигиваю тут все операции - это +, -, * ...
Кстати, все переменные используются исключительно 16-бит integer Улыбка

Добавил 12.08.2006:
Если оставить только математику, то получится так:
Код:

Distance = Получить расстояние между THIS и Target
for (i=0; i < 10; i++) {
Xo, Yo, Zo = Получить предыдущие координаты Target
X, Y, Z = Получить текущие координаты Target
k = (Distance / BulletSpeed) / Delta
X = (X - Xo)*k + X
Y = (Y - Yo)*k + Y
Z = (Z - Zo)*k + Z
Distance = Получить расстояние между THIS и точкой (X,Y,Z)
}

где THIS - атакующий корабль, ИИ которго и производит наведение
Target - атакуемая цель
BulletSpeed - модуль абсолютной скорости движения снаряда в пространстве
Delta - интервал времени, прошедший с момента, когда цель была в точке (Xo,Yo,Zo)
После 10 - 15 итераций данного алгоритма точка (X,Y,Z) и будет искомой точкой наведения (а также попадания).
Чем больше интервал Delta замера изменения позиции цели, тем лучше усреднение, но хуже предсказание ее динамичных маневров. Для стрельбы Delta лучше делать 1-2 сек, но если ньютоновская физика - то можно и больше. А можно и вовсе не вычислять вектор скорости цели на основе наблюдения этой цели атакующим, а просто его "подсмотреть" заранее, обратившись к внутренним переменным цели Улыбка
А еще данный алгоритм можно использовать и для расчета точки перехвата цели (кстати именно для этого я скрипт и писал), все что нужно - это вместо BulletSpeed использовать текущую скорость движения атакующего, и Delta сделать секунд 20.
А в своем скрипте выше я размазывал 9 итераций на 18 секунд, производя лишь 1 итерацию каждые 2 сек и записывал при этом текущие координаты Target в массив (9 строк) так, чтобы при каждой последующей итерации я мог из этого массива получить наиболее старую позицию Target, т.е. спустя 2 итерации это была бы позиция 4 сек давности, а 9 и более итераций - 18 сек давности.
    Добавлено: 21:12 01-08-2006   
Канал Игры Мечты: «Расчет точки упреждения»
На страницу: Пред.  1, 2 | Все страницы
  
Показать: 
Предыдущая тема | Следующая тема |
К списку каналов | Наверх страницы
Цитата не в тему: Дык догонялки флудеров - увлечение сугубо временное. Когда-то я лидерствовал. Были времена Ксенона и Фокса 68. Потом Осьмы. Теперь Ганса. А Вик во все времена был отъявленным флудером... (Rokar)

  » Расчет точки упреждения | страница 2
Каналы: Новости | Elite | Elite: Dangerous | Freelancer | Star Citizen | X-Tension/X-BTF | X2: The Threat | X3: Reunion | X3: Terran Conflict | X Rebirth | X4: Foundations | EVE Online | Orbiter | Kerbal Space Program | Evochron | VoidExpanse | Космические Миры | Онлайновые игры | Другие игры | Цифровая дистрибуция | play.elite-games.ru | ЗВ 2: Гражданская война | Творчество | Железо | Игра Мечты | Сайт
   Дизайн Elite Games V5 beta.18