Немного поздно, но я прошел через то же самое сегодня только с 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())
Это было единственное решение что сработало для моих целей. ИМХО это тоже самое логичное решение ...
Я нашел этот вопрос очень интересным, так как я недавно сделал некоторую работу над моделированием движения снаряда с перетаскиванием.
Точка 1: Вы по существу обновляете положение и скорость с помощью явное/вперед Euler повторение , где каждое новое значение для состояний должно быть функцией старых значений. В таком случае необходимо обновлять положение сначала , затем обновляя скорость.
Точка 2: существуют более реалистические модели физики для [1 113] эффект трения перетаскивания . Одна модель (предложенный [1 114] Adam Liss ) включает силу сопротивления, которая пропорциональна скорости (известный как перетаскивание 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 в целом. Я оставлю это, чтобы другие попытались. =)
Это, вероятно, не, что Вы ищете, но в зависимости от того, какой механизм Вы продолжаете работать, могло бы быть лучше еще использовать механизм, созданный кем-то, как farseer (для C#). Примечание Codeplex снижается для обслуживания.
Это не отвечает на Ваш вопрос, но одна вещь, которую Вы не должны делать на моделированиях как это, зависят от фиксированной частоты кадров. Вычислите время начиная с последнего обновления и используйте дельту-T в своих уравнениях. Что-то как:
static double lastUpdate=0;
if (lastUpdate!=0) {
deltaT = time() - lastUpdate;
velocity += acceleration * deltaT;
position += velocity * deltaT;
}
lastUpdate = time();
также хорошо проверить, теряете ли Вы фокус и прекращаете обновлять, и когда Вы получаете lastUpdate набора фокуса к 0. Тем путем Вы не заставляете огромный deltaT обрабатывать, когда Вы возвращаетесь.
Если Вы хотите видеть то, что может быть сделано с очень простые модели физики с помощью очень простая математика, смотреть на некоторые проекты Царапины в http://scratch.mit.edu/ - можно получить некоторые полезные идеи & Вы, конечно, весело проведете время.
, Если мы следуем за физикой, как указано, нет никакой максимальной скорости. С чисто физической точки зрения Вы зафиксировали ускорение в постоянной величине, что означает, что скорость всегда увеличивается.
Как альтернатива, рассмотрите две силы, действующие на Ваш объект:
, Таким образом, скорость при повторении n
становится: vn = v0 + n F - dvn-1
Вы попросили выбирать максимальную скорость, vnmax, который происходит при повторении nmax
.
Примечание, что проблема под-ограниченным ; то есть, F и d связан, таким образом, можно произвольно выбрать значение для одного из них, затем вычислить другой.
Теперь, когда прокрутка шара, действительно ли кто-либо готов взять математику?
Предупреждение: это ужасно и включает степенной ряд !
<час> Редактирование: Почему самка, последовательность n**F**
в первом уравнении появляется буквально, если нет пространство после n
?
velocity *= friction;
Это не препятствует тому, чтобы скорость шла об определенном моменте...
Трение увеличивается экспоненциально (не заключайте мне в кавычки на том) когда скорость увеличивается и будет 0 в покое. В конечном счете Вы достигнете точки где трение = ускорение.
, Таким образом, Вы хотите что-то вроде этого:
velocity += (acceleration - friction);
position += velocity;
friction = a*exp(b*velocity);
, Где Вы выбираете значения для a и b., b будет управлять, сколько времени он берет для достижения максимальной скорости и управления желанием, как резко трение увеличивается. (Снова, не проводите свое собственное исследование на этом - я иду от того, что я помню от класса 12 физики.)
Abort
поток внешне. Читайте: interact-sw.co.uk/iangblog/2004/11/12/cancellation. В основном это очень очень неправильно в три пути: (1) создание ненужного дополнительного потока, (2) активное ожидание на нем и (3) прерывание его в потенциально критический момент, не позволяя надлежащую очистку. – Aaronaught 7 April 2010 в 14:15