Комментарии 17
Хотелось бы увидеть пример работы на видео. Если возможно.
Добавил видео. Если что-то не так сильно не ругайте, это мое первое видео.
А что у Вас за тема стоит? и доп панель с dropbox? Часы? и как сделали полупрозрачную верхнюю панель?
Было бы полезно в самое начало статьи вставить пару картинок, просто-и-понятно демонстрирующих/напоминающих, что же такое параллакс-эффект.
Уверен, не все читающие знают/помнят.
Уверен, не все читающие знают/помнят.
Было бы неплохо увидеть побольше комментариев в коде и разъяснения, что за «Spring formula» и откуда она была выведена.
Ох, spring formula была выведена в муках и воспоминаниях основ высшей математики. По сути она переводит координаты реального смещения экрана (пальцем) в координаты смещения фона с учетом функции пружины.
Простым языком, например, мы сдвигаем палец на 0.3 единицы, а фон уходит на 0.2 единицы. Если пружина не действует, то смещение на 0.3 единицы пальцем будет соответствовать смещению фона тоже на 0.3 единицы.
В начале действия пружины расхождение в смещениях фона и пальца небольшие и по мере «сжатия» пружины разница между смещениями увеличивается вплоть до того, что фон перестает двигаться при движении пальца (пружина полностью сжата). С математической точки зрения формула пружины, это перевернутая порабола(далее просто порабола), при чем точкой начала «действия» этой пораболы(пружины), является точка в которой производная пораболы равна единице, чтобы при «стыковке» с линейной функцией, которая действует до пружины получалась гладкая функция, если этого не сделать, то получим рывок при переходе из обычного режима в режим пружины. Так же значение самой функции пораболы должно точно соответствовать линейной функции обычного движения в точке начала действия пружины, то есть в точке сопряжения этих функций.
В методе NormalizePosition происходит как раз это сопряжение и переключение с линейной функции на пораболическую в точке начала действия пружины stringZone, которая в свою очередь начинается на последнем виртуальном скрине. А жесткая формула, которая была там указана, это формула перевернутой пораболы, которая сдвинута по осям x y и сжата по y так, чтобы соответствовать вышеуказанным ограничениям.
Таким образом, мы получаем гладкую S образную функцию на промежутке входных значений от 0 до 1.
Ух, наверное ничего не понятно, но это был один из самых сложных участков реализации. Еще есть формула инерции f(x) = ax^3 + bx^2 + cx + d, которая по сути является аппроксимирующей функцией третьего порядка нашего движения, которую мы «подстраиваем» под скорость движения нашего пальца в момент отрыва от экрана, а дальше начиная с этой скорости функция автоматом вычисляет положение экрана плавно сводя эту скорость к нулю.
Если что-то не понятно задавайте вопросы попробую прояснить :)
Простым языком, например, мы сдвигаем палец на 0.3 единицы, а фон уходит на 0.2 единицы. Если пружина не действует, то смещение на 0.3 единицы пальцем будет соответствовать смещению фона тоже на 0.3 единицы.
В начале действия пружины расхождение в смещениях фона и пальца небольшие и по мере «сжатия» пружины разница между смещениями увеличивается вплоть до того, что фон перестает двигаться при движении пальца (пружина полностью сжата). С математической точки зрения формула пружины, это перевернутая порабола(далее просто порабола), при чем точкой начала «действия» этой пораболы(пружины), является точка в которой производная пораболы равна единице, чтобы при «стыковке» с линейной функцией, которая действует до пружины получалась гладкая функция, если этого не сделать, то получим рывок при переходе из обычного режима в режим пружины. Так же значение самой функции пораболы должно точно соответствовать линейной функции обычного движения в точке начала действия пружины, то есть в точке сопряжения этих функций.
В методе NormalizePosition происходит как раз это сопряжение и переключение с линейной функции на пораболическую в точке начала действия пружины stringZone, которая в свою очередь начинается на последнем виртуальном скрине. А жесткая формула, которая была там указана, это формула перевернутой пораболы, которая сдвинута по осям x y и сжата по y так, чтобы соответствовать вышеуказанным ограничениям.
Таким образом, мы получаем гладкую S образную функцию на промежутке входных значений от 0 до 1.
Ух, наверное ничего не понятно, но это был один из самых сложных участков реализации. Еще есть формула инерции f(x) = ax^3 + bx^2 + cx + d, которая по сути является аппроксимирующей функцией третьего порядка нашего движения, которую мы «подстраиваем» под скорость движения нашего пальца в момент отрыва от экрана, а дальше начиная с этой скорости функция автоматом вычисляет положение экрана плавно сводя эту скорость к нулю.
Если что-то не понятно задавайте вопросы попробую прояснить :)
> это формула перевернутой пораболы, которая сдвинута по осям x y и сжата по y так, чтобы соответствовать вышеуказанным ограничениям.
Вот это не вполне ясно. Где там перевернутая парабола? Как понимаю, коэффициенты и общий вид ее значительно изменен, эти вычитания из 1 и 0,5 тоже неясны.
Вот это не вполне ясно. Где там перевернутая парабола? Как понимаю, коэффициенты и общий вид ее значительно изменен, эти вычитания из 1 и 0,5 тоже неясны.
Я же говорю, формула выводилась в муках :). Если воспользоваться сервисом bit.ly/TQWFkI в нем, можно увидеть, что это перевернутая порабола. Но естественно не вся порабола используется в качестве рабочего участка, а только от 0 до 0.2.
В частном случае я взял springZone равным 0.2, так как у нас 5 рабочих столов (всю шкалу изменений от 0 до 1 делим на 5 получаем 0.2). График интересующего нас участка: bit.ly/Uduona. В итоге мы получили функцию, производная которой равна 1 в 0, и производная равна 0 в 0.2 (то есть в конце springZone, «пружина» сжата до максимума).
По поводу коэффициентов получившейся формулы я сейчас не могу точно сказать какой из них за что отвечает (напр. за сдвиги и сжатия/расширения), у меня по математике была 4, и это было 6 лет назад, не помню я уже, подбирал полуэкспиремнтально и с листочком бумаги, который к сожалению потерялся. Но при желании можно легко разобраться исходя из начальной y = x^2 и в общем виде введя коэффициенты y = a + b*(x*c + d)^2, с помощью вышеуказанного сервиса увидеть, какой из коэфициентов за что отвечает и сгенерировать нужные для своей цели.
В частном случае я взял springZone равным 0.2, так как у нас 5 рабочих столов (всю шкалу изменений от 0 до 1 делим на 5 получаем 0.2). График интересующего нас участка: bit.ly/Uduona. В итоге мы получили функцию, производная которой равна 1 в 0, и производная равна 0 в 0.2 (то есть в конце springZone, «пружина» сжата до максимума).
По поводу коэффициентов получившейся формулы я сейчас не могу точно сказать какой из них за что отвечает (напр. за сдвиги и сжатия/расширения), у меня по математике была 4, и это было 6 лет назад, не помню я уже, подбирал полуэкспиремнтально и с листочком бумаги, который к сожалению потерялся. Но при желании можно легко разобраться исходя из начальной y = x^2 и в общем виде введя коэффициенты y = a + b*(x*c + d)^2, с помощью вышеуказанного сервиса увидеть, какой из коэфициентов за что отвечает и сгенерировать нужные для своей цели.
С графиками стало визуально яснее, вам была нужна производная y'(x), вида (в вашем случае) -5x + 1
Просто интересно было бы понять, как вы прикидывали эти коэффициенты, чтобы по производной построить параболу.
Просто интересно было бы понять, как вы прикидывали эти коэффициенты, чтобы по производной построить параболу.
На самом деле все происходило визуально, нарисовал пораболу, нашел визуально, какой участок меня интересует и потом методом тыка пробовал подбирать коэффиенты, которые «установили» бы этот участок в нужный мне диапазон за основу брал формулу y=a + b*(c*x +d)^2, и потом методом подбора коэффициентов нашел искомые мне значения. Если честно уже смутно помню, как именно дошел до результата.
Правильный способ взять за основу формулу y=a*x^2+b*x+c (взято отсюда http://bit.ly/WNJr58) найти производную равную 2*a*x+b. Принять, что производная в 0 равна 1, а в точке максимального сжатия S равна 0, и так же сама функция пораболы равна 0 в точке 0. Итого получаем систему из трех уравнений:
b=1
2aS+b=0
c=0
Откуда легко выражает формулу «пружины» y = (-1/(2S)) * x^2 + x, где S это springZone. (http://bit.ly/W08LWm — график по новому методу, ничем не отличается от изначального).
Вывод: надо было хорошо учить математику, и не идти сразу «визуальным» способом, а найти решение за 5 минут чисто математически. Хотя с другой стороны (оправдывая себя :) система образования могла быть построена на более прикладном уровне и сразу рассказывать, для чего и где мы можем использовать пораболы, гиперболы, производные, апроксимацию и прочие полезные вещи.
Правильный способ взять за основу формулу y=a*x^2+b*x+c (взято отсюда http://bit.ly/WNJr58) найти производную равную 2*a*x+b. Принять, что производная в 0 равна 1, а в точке максимального сжатия S равна 0, и так же сама функция пораболы равна 0 в точке 0. Итого получаем систему из трех уравнений:
b=1
2aS+b=0
c=0
Откуда легко выражает формулу «пружины» y = (-1/(2S)) * x^2 + x, где S это springZone. (http://bit.ly/W08LWm — график по новому методу, ничем не отличается от изначального).
Вывод: надо было хорошо учить математику, и не идти сразу «визуальным» способом, а найти решение за 5 минут чисто математически. Хотя с другой стороны (оправдывая себя :) система образования могла быть построена на более прикладном уровне и сразу рассказывать, для чего и где мы можем использовать пораболы, гиперболы, производные, апроксимацию и прочие полезные вещи.
Вот меня тоже заинтересовал скорее подход, поскольку я догадывался, что можно привести к уравнениям, но пошел неверным путем, рассчитывая коэффициенты a и b из графика и пытаясь их сопоставить с графиком и производной.
Большое спасибо! Остался последний вопрос — из каких соображений рассчитывается xOffsetNormalized и как он мог бы быть рассчитан исходя из измененной формулы?
Большое спасибо! Остался последний вопрос — из каких соображений рассчитывается xOffsetNormalized и как он мог бы быть рассчитан исходя из измененной формулы?
xOffsetNormalized имеет диапазон от 0 до 0.5, и равен Math.abs(xOffset — 0.5f), то есть мы приводим диапазон движений от 0 до 1 к диапазону от 0 до 0.5, но без информации в какую сторону от середины (от позиции 0.5) мы двигаемся.
Дальше работает наша функция пружины, которая не важно по какому методу посчитана (результат то один и тот же). И потом мы восстанавливаем информацию о направлении движения с помощью конструкций
if(xOffset < 0.5f)
xOffset = 0.5f — xOffsetNormalized;
else
xOffset = 0.5f + xOffsetNormalized;
Таким образом, мы применяем нашу пружину к нормализованному значению входного параметра, и на обоих концах входного параметра пружина работает одинаково (то есть от 0 до 0.2 и от 0.8 до 1).
Математически мы просто «отзеркалили» функцию нормализованного значения относительно осей XY. Получив в итоге S образную функцию от 0 до 1, которая имеет линейный вид в диапазоне от 0.2 до 0.8 и «загнутый» (пораболлический) на краях.
Дальше работает наша функция пружины, которая не важно по какому методу посчитана (результат то один и тот же). И потом мы восстанавливаем информацию о направлении движения с помощью конструкций
if(xOffset < 0.5f)
xOffset = 0.5f — xOffsetNormalized;
else
xOffset = 0.5f + xOffsetNormalized;
Таким образом, мы применяем нашу пружину к нормализованному значению входного параметра, и на обоих концах входного параметра пружина работает одинаково (то есть от 0 до 0.2 и от 0.8 до 1).
Математически мы просто «отзеркалили» функцию нормализованного значения относительно осей XY. Получив в итоге S образную функцию от 0 до 1, которая имеет линейный вид в диапазоне от 0.2 до 0.8 и «загнутый» (пораболлический) на краях.
.
Зарегистрируйтесь на Хабре, чтобы оставить комментарий
Параллакс эффект для живых обоев на Android