WPF: Нахождение элемента вдоль пути

Похоже, что ваша установка может быть нарушена, поскольку я не могу повторить это:

$ cat a.py
import z3
f = z3.Function('f', z3.IntSort(), z3.IntSort(), z3.IntSort())
x = z3.Int('x')
s = z3.Solver()
s.add(f(1, 10) == 42)
s.add(z3.ForAll([x], f(2, x) == f(1, x)))
print s.sexpr()
s.check()
m = s.model()
print(m.eval(f(1, 10)))  # print 0
print(m.eval(f(2, 10)))  # print 0

$ python a.py
(declare-fun f (Int Int) Int)
(assert (= (f 1 10) 42))
(assert (forall ((x Int)) (= (f 2 x) (f 1 x))))

42
42

Обратите внимание, что я добавил print s.sexpr() в ваш код, и он красиво напечатал сгенерированный SMTLib. Вы видите то же самое?

6
задан Cœur 29 July 2017 в 10:41
поделиться

9 ответов

угол между роботами является arctan (x-расстояние, y-расстояние) (большинство платформ обеспечивает этот arctan с 2 аргументами, который делает угловую корректировку к Вам. Затем просто необходимо проверить, является ли этот угол меньше, чем некоторое число далеко от текущего заголовка.

Править: жаль о неопределенном ответе, но вот некоторые мои примечания по Вашему обновлению:

  • координаты были бы в декартовой системе, не оконной системе. Это приводит к некоторым различным числам

    Ориентация: 3.3 <-это неправильно, bot1 похож, он ориентирован приблизительно на 4 или что-то. 191 градус был бы о позиции 8:30 по часам, на которые почти непосредственно указывают корпус 2. Неудивительный системные "Видимые" возвраты!

    азимут: cy был бы-31 (31 единица под), а не 31.

С этими изменениями необходимо получить корректные результаты.

3
ответ дан 16 December 2019 в 21:46
поделиться

Вычислите относительный угол и расстояние каждого робота относительно текущего. Если угол в некотором пороге текущего заголовка и в макс. диапазоне, то он видит его.

Единственная хитрая вещь будет обрабатывать граничный случай, куда угол идет от 2pi радианы к 0.

1
ответ дан 16 December 2019 в 21:46
поделиться

Что-то вроде этого в классе Вашего бота (код C#):

/// <summary>
/// Check to see if another bot is visible from this bot's point of view.
/// </summary>
/// <param name="other">The other bot to look for.</param>
/// <returns>True iff <paramref name="other"/> is visible for this bot with the current turret angle.</returns>
private bool Sees(Bot other)
{
    // Get the actual angle of the tangent between the bots.
    var actualAngle = Math.Atan2(this.X - other.X, this.Y - other.Y) * 180/Math.PI + 360;

    // Compare that angle to a the turret angle +/- the field of vision.
    var minVisibleAngle = (actualAngle - (FOV_ANGLE / 2) + 360);
    var maxVisibleAngle = (actualAngle + (FOV_ANGLE / 2) + 360); 
    if (this.TurretAngle >= minVisibleAngle && this.TurretAngle <= maxVisibleAngle)
    {
        return true;
    }
    return false;
}

Примечания:

  • +360 там, чтобы вызвать любые отрицательные углы к их соответствующим положительным значениям и сместить граничный случай угла 0 к куда-нибудь легче расположиться тест.
  • Это могло бы быть выполнимо использующий только углы радиана, но я думаю, что они грязны и тверды считать:/
  • Посмотрите Математику. Документация Atan2 для получения дополнительной информации.
  • Я настоятельно рекомендую изучение Платформы XNA, поскольку это создается с игровым дизайном в памяти. Однако это не использует WPF.

Это предполагает что:

  • нет никаких препятствий для затруднения представления
  • Класс бота имеет свойства X and Y
  • Свойства X and Y в центре бота.
  • Бот классифицирует свойство TurretAngle, которое обозначает положительный угол башенки относительно оси X, против часовой стрелки.
  • Класс бота имеет статический угол константы под названием FOV_ANGLE, обозначающий поле зрения башенки.

Отказ от ответственности: Это не тестируется или даже проверяется на компиляцию, адаптируйте ее по мере необходимости.

1
ответ дан 16 December 2019 в 21:46
поделиться

Ваша башенка действительно имеет это широким из шаблона увольнения? Путь маркер, взятия были бы прямой линией и это не станет больше, когда это перемещается. У Вас должен быть простой вектор в направлении, башенка, представляющая башенки, уничтожает зону. Каждый корпус имел бы круг ограничения представлением их уязвимой области. Затем можно продолжить двигаться способ, которым они делают с трассировкой лучей. Простой луч / круговое пересечение. Взгляд на раздел 3 из документа Пересечение Линейных и Круговых Компонентов в 2D.

0
ответ дан 16 December 2019 в 21:46
поделиться

Несколько предложений после реализации чего-то подобного (давным-давно!):

Следующее предполагает, что Вы - цикличное выполнение через всех ботов на поле битвы (не особенно хорошая практика, но быстрый и легкий получить что-то работа!)

1) Намного легче проверить, находится ли бот в диапазоне затем, если это может в настоящее время замечаться в FOV, например.

int range = Math.sqrt( Math.abs(my.Location.X - bots.Location.X)^2 + 
            Math.abs(my.Location.Y - bots.Location.Y)^2 );

if (range < maxRange)
{
    // check for FOV
}

Это гарантирует, что может потенциально закоротить-cuircuit большую проверку FOV и ускорить процесс выполнения моделирования. Как протест, у Вас могла быть некоторая случайность здесь для создания этого более интересным, таким, что после определенного расстояния шанс видеть линейно пропорционален диапазону бота.

2) Эта статья, кажется, имеет материал вычисления FOV на нем.

3) Как выпускник AI... неф Вы попробовали Нейронные сети, Вы могли обучить их распознавать, является ли робот в диапазоне и допустимой цели. Это инвертировало бы любую ужасно сложную и замысловатую математику! Вы могли иметь много слой perceptron [1], [2] канал в координатах ботов и целевых координатах и получить хорошее fire/no-fire решение в конце. ПРЕДУПРЕЖДЕНИЕ: Я чувствую себя обязанным сказать Вам, что этой методологии не является самым легким достигнуть и может быть ужасно печальной, когда она идет не так, как надо. Из-за (простой) недетерминированной природы этой формы алгоритма, отладка может быть болью. Плюс Вы будет нуждаться в некоторой форме изучения любого Назад Propogation (с учебными случаями) или Генетический алгоритм (другой сложный процесс к идеальному)! Учитывая выбор я использовал бы Номер 3, но не для всех!

1
ответ дан 16 December 2019 в 21:46
поделиться

Это скажет Вам, если центр canvas2 может быть поражен canvas1. Если Вы хотите объяснить ширину canvas2, это становится немного более сложным. Короче говоря необходимо было бы сделать две проверки, один для каждого из соответствующих углов canvas2, вместо каждый проверяет центр.

/// assumming canvas1 is firing on canvas2

// positions of canvas1 and canvas2, respectively
// (you're probably tracking these in your Tank objects)
int x1, y1, x2, y2;

// orientation of canvas1 (angle)
// (you're probably tracking this in your Tank objects, too)
double orientation;
// angle available for firing
// (ditto, Tank object)
double angleOfSight;

// vector from canvas1 to canvas2
int cx, cy;
// angle of vector between canvas1 and canvas2
double azimuth;
// can canvas1 hit the center of canvas2?
bool canHit;

// find the vector from canvas1 to canvas2
cx = x2 - x1;
cy = y2 - y1;

// calculate the angle of the vector
azimuth = Math.Atan2(cy, cx);
// correct for Atan range (-pi, pi)
if(azimuth < 0) azimuth += 2*Math.PI;

// determine if canvas1 can hit canvas2
// can eliminate the and (&&) with Math.Abs but this seems more instructive
canHit = (azimuth < orientation + angleOfSight) &&
    (azimuth > orientation - angleOfSight);
1
ответ дан 16 December 2019 в 21:46
поделиться

Это может быть довольно легко достигнуто с использованием понятия в векторной математике, названной скалярным произведением.

http://en.wikipedia.org/wiki/Dot_product

Это может выглядеть пугающим, но дело не в этом плохо. Это - самый корректный способ заниматься Вашей проблемой FOV, и красота состоит в том, что та же математика работает, имеете ли Вы дело с 2D или 3D (именно тогда, Вы знаете, что решение правильно).

(ПРИМЕЧАНИЕ: Если что-нибудь не ясно, просто спросите в разделе комментария, и я заполню недостающие звенья.)

Шаги:

1) Вам нужны два вектора, каждый - направляющийся вектор основного корпуса. Другой вектор, в котором Вы нуждаетесь, получен из положения рассматриваемого корпуса и основного корпуса.

Для нашего обсуждения давайте предположим, что направляющийся вектор для основного корпуса (топор, да) и вектор между положением основного корпуса, и целевой корпус (основной обмен). Например, если основной корпус в местоположении (20, 30), и целевой корпус в (45, 62), то вектор b = (45 - 20, 62 - 30) = (25, 32).

Снова, ради обсуждения, давайте предположим, что вектор заголовка основного корпуса (3,4).

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

2) Скалярное произведение определяется как

* b = |a || b | because(угол)

читайте как (скалярное произведение) b с тех пор a, и b не являются числами, они - векторы.

3) или выразил иначе (после некоторого алгебраического управления):

удите рыбу = acos ((* b) / |a || b |)

угол является углом между этими двумя векторами a и b, таким образом, одна только эта информация может сказать Вам, видит ли один корпус другого или нет.

|a | является величиной вектора a, который согласно Теореме Pythagoras, просто sqrt (топор * топор + да * да), то же идет для |b |.

Теперь вопрос прибывает, как Вы узнаете * b (скалярное произведение b) для нахождения угла.

4) Здесь прибывает спасение. Оказывается, что скалярное произведение может также быть выражено как указано ниже:

* b = топор * основной обмен + да *

Так удят рыбу = acos ((топор * основной обмен + да *) / |a || b |)

Если угол является меньше чем половиной Вашего FOV, то рассматриваемый корпус в поле зрения. Иначе это не.

Так с помощью чисел в качестве примера выше:

На основе наших чисел в качестве примера:

a = (3, 4) b = (25, 32)

|a | = sqrt (3 * 3 + 4 * 4)

|b | = sqrt (25 * 25 + 32 * 32)

удите рыбу = acos ((20 * 25 + 30 * 32) / |a || b |

(Обязательно преобразуйте получающийся угол в градус или радиан как соответствующий прежде, чем сравнить его с Вашим FOV),

1
ответ дан 16 December 2019 в 21:46
поделиться

Рассмотрение обоих из вопросов, я думаю, что можно решить эту проблему с помощью математики, если, затем необходимо решить много других проблем вокруг обнаружения коллизий, выпустив пули и т.д. Они не тривиальны для решения, особенно если боты не являются квадратными. Я рекомендовал бы смотреть на механизмы физики - farseer на codeplex, хороший пример WPF, но это превращает его в путь проекта, больше, чем средняя школа dev задача.

Лучший совет, который я получил для высоких оценок, делают что-то простое действительно хорошо, не отделяйтесь, поставляют что-то блестящее.

0
ответ дан 16 December 2019 в 21:46
поделиться

Ваша обновленная проблема, кажется, возникает из различных "нулевых" направлений orientation и azimuth: orientation из 0, кажется, означает "прямо", но azimuth из 0 "прямых прав".

0
ответ дан 16 December 2019 в 21:46
поделиться
Другие вопросы по тегам:

Похожие вопросы: