Простое физическое движение

Немного поздно, но я прошел через то же самое сегодня только с Pyside, но должен быть тем же ...

Подход «очень прост», хотя мне стоило немного времени ... Сначала установите все привязки на NoAnchor, затем переходите к точке зрения, переместите ее на сцену, переместите сцену на это значение, масштабируйте и, наконец, переведите обратно:

def wheelEvent(self, evt):
    #Remove possible Anchors
    self.widget.setTransformationAnchor(QtGui.QGraphicsView.NoAnchor)
    self.widget.setResizeAnchor(QtGui.QGraphicsView.NoAnchor)
    #Get Scene Pos
    target_viewport_pos = self.widget.mapToScene(evt.pos())
    #Translate Scene
    self.widget.translate(target_viewport_pos.x(),target_viewport_pos.y())
    # ZOOM
    if evt.delta() > 0:
        self._eventHandler.zoom_ctrl(1.2)
    else:
        self._eventHandler.zoom_ctrl(0.83333)
    # Translate back
    self.widget.translate(-target_viewport_pos.x(),-target_viewport_pos.y())

Это было единственное решение что сработало для моих целей. ИМХО это тоже самое логичное решение ...

30
задан gnovice 12 September 2017 в 03:57
поделиться

6 ответов

Я нашел этот вопрос очень интересным, так как я недавно сделал некоторую работу над моделированием движения снаряда с перетаскиванием.

Точка 1: Вы по существу обновляете положение и скорость с помощью явное/вперед Euler повторение , где каждое новое значение для состояний должно быть функцией старых значений. В таком случае необходимо обновлять положение сначала , затем обновляя скорость.

Точка 2: существуют более реалистические модели физики для [1 113] эффект трения перетаскивания . Одна модель (предложенный [1 114] Adam Liss ) включает силу сопротивления, которая пропорциональна скорости (известный как перетаскивание Stokes, которое обычно относится к низким ситуациям скорости). Тот, который я ранее предложил, включает силу сопротивления, которая пропорциональна квадрат из скорости (известный как квадратичное перетаскивание, которое обычно относится к высоким ситуациям скорости). Я обращусь к каждому относительно того, как Вы вывели бы формулы для максимальной скорости и время, требуемое эффективно достигнуть максимальной скорости. Я буду предшествовать полным деривациям, так как они скорее включены.

<час>

перетаскивание Stokes:

уравнение для обновления скорости было бы:

velocity += acceleration - friction*velocity

, который представляет следующее дифференциальное уравнение:

dv/dt = a - f*v

Используя первую запись в [1 116] эта таблица интегралов , мы можем найти решение (принимающий v = 0 в t = 0):

v = (a/f) - (a/f)*exp(-f*t)

максимум (т.е. терминал) скорость возникает, когда t>> 0, так, чтобы второй срок в уравнении был очень близко к нулю и:

v_max = a/f

Относительно времени должен был достигнуть максимальной скорости, отметить, что уравнение никогда действительно достигает ее, но вместо этого асимптоты к ней. Однако, когда аргумент экспоненциала равняется-5, скорость составляет приблизительно 98% максимальной скорости, вероятно, достаточно близко для рассмотрения этого равным. Можно тогда приблизить время к максимальной скорости как:

t_max = 5/f

можно тогда использовать эти два уравнения для решения для [1 147] f и , учитывая желаемое vmax и tmax.

<час>

Квадратичное перетаскивание:

уравнение для обновления скорости было бы:

velocity += acceleration - friction*velocity*velocity

, который представляет следующее дифференциальное уравнение:

dv/dt = a - f*v^2

Используя первую запись в [1 118] эта таблица интегралов , мы можем найти решение (принимающий v = 0 в t = 0):

v = sqrt(a/f)*(exp(2*sqrt(a*f)*t) - 1)/(exp(2*sqrt(a*f)*t) + 1)

максимум (т.е. терминал) скорость возникает, когда t>> 0, так, чтобы экспоненциальные условия были намного больше, чем 1 и подходы уравнения:

v_max = sqrt(a/f)

Относительно времени должен был достигнуть максимальной скорости, отметить, что уравнение никогда действительно достигает ее, но вместо этого асимптоты к ней. Однако, когда аргумент экспоненциала равняется 5, скорость составляет приблизительно 99% максимальной скорости, вероятно, достаточно близко для рассмотрения этого равным. Можно тогда приблизить время к максимальной скорости как:

t_max = 2.5/sqrt(a*f)

, который также эквивалентен:

t_max = 2.5/(f*v_max)

Для желаемого vmax и tmax, второе уравнение для [1 154] tmax скажет Вам, чем должен быть f, и затем можно включить это к уравнению для [1 156] vmax для получения значения для [1 157] .

<час>

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

Другая Точка: я сразу не понял это, но обновление скорости больше не необходимо, если Вы вместо этого используете формулы, я произошел для [1 159] v (t) . Если Вы просто смоделируете ускорение от отдыха, и Вы отслеживаете время, так как ускорение началось, то код посмотрит что-то как:

position += velocity_function(timeSinceStart)

, где "velocity_function" является одной из этих двух формул для [1 160] v (t) и Вам больше не была бы нужна скоростная переменная. В целом здесь существует компромисс: вычисление v (t) может быть более в вычислительном отношении дорогим, чем простое обновление скорости с повторяющейся схемой (из-за экспоненциальных условий), но это, как гарантируют, останется стабильным и ограниченным. При определенных условиях (как попытка получить очень короткое tmax), повторение может стать нестабильным и взрыв, типичная проблема с вперед Euler методом. Однако поддерживая пределы на переменные (как 0 < f < 1), должен предотвратить эту нестабильность.

, Кроме того, если Вы чувствуете себя несколько мазохистскими, можно быть в состоянии интегрировать формулу для [1 164] v (t) для получения закрытого решения для формы для [1 165] p (t) , таким образом предшествующий потребность в повторении Newton в целом. Я оставлю это, чтобы другие попытались. =)

37
ответ дан gnovice 12 September 2017 в 03:57
поделиться
  • 1
    Очень, очень опасный для Abort поток внешне. Читайте: interact-sw.co.uk/iangblog/2004/11/12/cancellation. В основном это очень очень неправильно в три пути: (1) создание ненужного дополнительного потока, (2) активное ожидание на нем и (3) прерывание его в потенциально критический момент, не позволяя надлежащую очистку. – Aaronaught 7 April 2010 в 14:15

Это, вероятно, не, что Вы ищете, но в зависимости от того, какой механизм Вы продолжаете работать, могло бы быть лучше еще использовать механизм, созданный кем-то, как farseer (для C#). Примечание Codeplex снижается для обслуживания.

1
ответ дан Diones 12 September 2017 в 03:57
поделиться
  • 1
    @AbhishekPandya на Вас продвигают сервер, который необходимо изменить от разработчика на сертификаты выпуска, чтобы протестировать с TestFlight и заставить его работать с официальным выпуском AppStore. – Shebuka 17 August 2017 в 12:39

Это не отвечает на Ваш вопрос, но одна вещь, которую Вы не должны делать на моделированиях как это, зависят от фиксированной частоты кадров. Вычислите время начиная с последнего обновления и используйте дельту-T в своих уравнениях. Что-то как:

static double lastUpdate=0;
if (lastUpdate!=0) {
  deltaT = time() - lastUpdate;
  velocity += acceleration * deltaT;
  position += velocity * deltaT;
}
lastUpdate = time();

также хорошо проверить, теряете ли Вы фокус и прекращаете обновлять, и когда Вы получаете lastUpdate набора фокуса к 0. Тем путем Вы не заставляете огромный deltaT обрабатывать, когда Вы возвращаетесь.

2
ответ дан GoatRider 12 September 2017 в 03:57
поделиться

Если Вы хотите видеть то, что может быть сделано с очень простые модели физики с помощью очень простая математика, смотреть на некоторые проекты Царапины в http://scratch.mit.edu/ - можно получить некоторые полезные идеи & Вы, конечно, весело проведете время.

1
ответ дан 12 September 2017 в 03:57
поделиться
  • 1
    когда я запускаю свое приложение от XCode, продвиньте работы уведомления, но когда я загружаю сборку на Appstore и загружаю его для тестирования использования testflight это won' t работа. – Abhishek Pandya 16 August 2017 в 13:05

Предупреждение: Частичное Решение

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

Как альтернатива, рассмотрите две силы, действующие на Ваш объект:

  • постоянная внешняя сила, F, который имеет тенденцию ускорять его, и
  • сила перетаскивания, d, который пропорционален скорости и имеет тенденцию замедлять ее.

, Таким образом, скорость при повторении n становится: vn = v0 + n F - dvn-1

Вы попросили выбирать максимальную скорость, vnmax, который происходит при повторении nmax.

Примечание, что проблема под-ограниченным ; то есть, F и d связан, таким образом, можно произвольно выбрать значение для одного из них, затем вычислить другой.

Теперь, когда прокрутка шара, действительно ли кто-либо готов взять математику?

Предупреждение: это ужасно и включает степенной ряд !

<час>

Редактирование: Почему самка, последовательность n**F** в первом уравнении появляется буквально, если нет пространство после n?

3
ответ дан Adam Liss 12 September 2017 в 03:57
поделиться
  • 1
    Ответ выше также использует дочерний поток + тип аварийного прекращения работы решения. Существует ли лучший способ иметь дело с этим? – Rob 7 April 2010 в 17:06
velocity *= friction;

Это не препятствует тому, чтобы скорость шла об определенном моменте...

Трение увеличивается экспоненциально (не заключайте мне в кавычки на том) когда скорость увеличивается и будет 0 в покое. В конечном счете Вы достигнете точки где трение = ускорение.

, Таким образом, Вы хотите что-то вроде этого:

velocity += (acceleration - friction);
position += velocity;
friction = a*exp(b*velocity);

, Где Вы выбираете значения для a и b., b будет управлять, сколько времени он берет для достижения максимальной скорости и управления желанием, как резко трение увеличивается. (Снова, не проводите свое собственное исследование на этом - я иду от того, что я помню от класса 12 физики.)

2
ответ дан 12 September 2017 в 03:57
поделиться
  • 1
    Чувак этот код уничтожил мой Xeon xD С 24 ядрами – Mehdi LAMRANI 29 June 2012 в 04:30
Другие вопросы по тегам:

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