@korner-brazers

Как остановить вращение в нужном месте?

Делаю колесо фортуны, вращение примитивно:
angle += 10 * speed;

Замедление или ускорение тоже обычное:
if(play){
  speed += 0.1;
}

if(stop) speed -= 0.1;

speed = Math.min(1,Math.max(0, speed));


Но появилась дилемма, нужно либо плавно остановить в нужном сегменте, либо наоборот, не останавливать на нежелательных сегментах. Уже весь рунет обшарил, пытался сам чет нахимичить, но не чего не выходит.

Нашел типа такого примера:
var speed=  1 -   ( (angle-EndAngle) % 6.28318531 ) / 6.28318531 ;


Вроде как останавливает на нужной секции, но делает это быстро и с рывком.
  • Вопрос задан
  • 349 просмотров
Решения вопроса 1
@lorc
Ну я бы в момент нажатия на "стоп" определил угол где колесо должно остановиться. Например, с помощью генератора случайных чисел.

Допустим, в момент нажатия "стоп" угол колеса alpha, а мы хотим чтобы оно остановилось в угле beta, сделав около пяти оборотов. Тогда, если alpha > beta, то нам нужно провернуть колесо на theta = 360 * 5 + beta - alpha градусов.
Если alpha < beta, то понадобиться например theta = 360 * 6 - beta + alpha градусов.

Итого, мы знаем скорость вращения speed, знаем количество градусов которое нужно пройти - theta. Знаем что в конце скорость должна быть 0. Надо посчитать замедление а.

Пришло время математики. За время t колесо провернется на speed * t - a * t * t /2 градусов. Нам надо чтобы оно провернулось на theta.

Значит, мы имеем уравнение speed * t - a * t * t /2 = theta. Еще мы помним что скорость в конце должна быть равна 0. Значит speed - a * t = 0.

Подставляем, сокращем. Получаем a = speed * speed / ( 2 * theta). Теперь вы знаете замедление, на которое нужно уменьшать скорость каждый цикл.

Только, учтите, что у вас время дискретно поэтому, не налажайте с единицами измерения для t, speed и а.
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 1
@Karpion
Вы зря считаете угол по формуле типа "+=" - она накапливает ошибки. Лучше считать "angle = time * speed".

Допустим, в момент начала остановки угловая скорость была speed, а остановиться надо через угол fi.
Если скорость будет неизменной, то колесо пройдёт угол fi за время t1=fi/speed. Если скорость будет равномерно снижаться до нуля, то за это время колесо пройдёт угол fi/2.

Допустим, в момент t0 колесо имеет угол angle0. И мы начинаем тормозить по формуле
angle = angle0 + (time * speed) - (uskr * time^2 / 2)
Колесо тормозится - ускорение отрицательное.

Скорость обнулится в момент
d_time1 = speed / uskr
В этот момент угол angle1 будет равен - по формуле выше. И он д.б. такой, какой нам надо, т.е. он известен.

angle1 = angle0 + (time1 * speed) - (uskr * time1^2 / 2)

Подставляем time1 :
angle1 = angle0 + (speed / uskr * speed) - (uskr * (speed / uskr)^2 / 2)
angle1 = angle0 + (speed^2 / uskr) - (speed^2 / uskr / 2) = angle0 + (speed^2 / uskr /2)
(speed^2 / uskr /2) = angle1 - angle0
uskr = (speed^2 / 2 / (angle1 - angle0))

Ну вот, вроде, всё. Вычисляем:
angle0 = time0 * speed
uskr = (speed^2 / 2 / (angle1 - angle0))
d_time1 = speed / uskr
if time < time0 then {
angle = time * speed;
} else if time < time0 + d_time1 then
angle = angle0 + (time * speed) - (uskr * time^2 / 2)
} else {
angle = angle1
}
Как-то так...
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы