Шары и их движение; Свет и ее путь всегда очаровывали меня. Я изучил анимацию в R несколько дней назад. Я не мог больше сопротивляться. Итак, я сделал один. :)
У всего этого проекта есть три аспекта.
Математическая часть - координатная геометрия
Физическая часть - трение
Алгоритм - здравый смысл
Кодирование - Go-Go Animate (gganimate): P
Математическая часть
- Закрепите границы доски.
- Найдите уравнение отраженной линии вдоль границ.
Здесь мы сохранили границы как прямые, соединяющие точки {(0,0), (0,1), (1,0), (1,1)}.
Результат 1:
Если вы отразите линию y = mx + c через y = 1, y = 0, x = 0 или x = 1, наклон новой линии станет -m.
Результат 2:
- Через строку y = 1 y = mx + c становится y = -mx + (2-c).
- Через строку y = 0 y = mx + c становится y = -mx + -c.
- Через строку x = 1 y = mx + c становится y = -mx + (2m + c).
- Через строку x = 0 y = mx + c становится y = -mx + c.
Часть алгоритма
Выберите начальную точку. (X =?, Y =?)
Выберите направление по оси X. (d = + 1 / -1)
Выберите линию движения (m =?, C =?)
Наблюдение
Когда мяч отскакивает от стены x = 0, направление меняется на d = +1. (положительная ось X)
Когда мяч отскакивает от стены x = 1, направление меняется на d = -1. (отрицательная ось X)
Поэтому необходимо иметь в виду следующее.
Каждый раз, когда мяч попадает в X-стену, наклон, точка пересечения и направление линии движения меняются.
Каждый раз, когда мяч попадает в Y-образную стену, изменяется только наклон и точка пересечения линии движения.
Часть кода
Код, как всегда, дается после гифки.
#starting point x = 0.5 y = 0.2 m = -pi c = 0.2 #direction d = +1 #number of discrete steps n = 90 #length of discrete steps l = 0.01 #dummy X = x Y = y #The Algorithm for (i in t) { X = X + d*l Y = m*X + c if (X < 0) #Reflection along X = 0 { X = 0 Y = m*X + c y = c(y,Y) x = c(x,X) c = c m = -m d = +1 X = X + d*l Y = m*X + c } if (X > 1) #Reflection along X = 1 { X = 1 Y = m*X + c y = c(y,Y) x = c(x,X) c = 2*m + c m = -m d = -1 X = X + d*l Y = m*X + c } if (Y < 0) #Reflection along Y = 0 { Y = 0 X = (Y-c)/m y = c(y,Y) x = c(x,X) c = -c m = -m X = X + d*l Y = m*X + c } if (Y > 1) #Reflection along Y = 1 { Y = 1 X = (Y-c)/m y = c(y,Y) x = c(x,X) c = 2-c m = -m X = X + d*l Y = m*X + c } y = c(y,Y) x = c(x,X) } t = 1:length(x) #engineering the boundary and the animation seq = 1:2 a = c(0,1,1,1,1,0,0,0) b = c(0,0,0,1,1,1,1,0) T = rep(seq,4) d = c(1,1,2,2,3,3,4,4) boundary = data.frame(a,b,d,T) billiard = data.frame(x,y,t) anim <- ggplot(billiard, aes(x, y)) + geom_path(size = 2) + geom_path(size = 1, colour = "red")+ geom_point(colour = "blue", size = 8) + geom_path(boundary, mapping = aes(a, b, group=d), size = 3)+ theme_minimal() + labs(title = 'Simulation of the motion of a Ball in a Billard Table. ')+ transition_reveal(t) animate(anim, nframes = 100, type="cairo")
Я не добавил здесь трений. Итак, добавим трений.
Часть физики - трение
animatecarrom <- function(theta) { library("ggplot2") library("gganimate") library("babynames") library("hrbrthemes") library("gifski") library("png") #starting point x = 0.5 y = 0.5 m = tan(theta) c = y - m*x #direction if (theta > -pi/2 && theta <= pi/2) { d = +1 } if (theta <= 1.5*pi && theta > pi/2) { d = -1 } #number of discrete steps #length of discrete steps l = 0.3 alpha = 0.01 #dummy X = x Y = y up = 0 right = 0 down = 0 left = 0 tstop = floor(l/alpha) deltat = 0.1 seq = seq(0,tstop,deltat) for (i in seq) { X = X + d*deltat*(l-alpha*i) Y = m*X + c if (X < 0) { X = 0 Y = m*X + c y = c(y,Y) x = c(x,X) c = c m = -m d = +1 X = X + d*deltat*(l-alpha*i) Y = m*X + c left = left + 1 } if (X > 1) { X = 1 Y = m*X + c y = c(y,Y) x = c(x,X) c = 2*m + c m = -m d = -1 X = X + d*deltat*(l-alpha*i) Y = m*X + c right = right + 1 } if (Y < 0) { Y = 0 X = (Y-c)/m y = c(y,Y) x = c(x,X) c = -c m = -m X = X + d*deltat*(l-alpha*i) Y = m*X + c down = down + 1 } if (Y > 1) { Y = 1 X = (Y-c)/m y = c(y,Y) x = c(x,X) c = 2-c m = -m X = X + d*deltat*(l-alpha*i) Y = m*X + c up = up + 1 } y = c(y,Y) x = c(x,X) } t = 1:length(x) #engineering the boundary seq = 1:2 a = c(0,1,1,1,1,0,0,0) b = c(0,0,0,1,1,1,1,0) T = rep(seq,4) d = c(1,1,2,2,3,3,4,4) boundary = data.frame(a,b,d,T) billiard = data.frame(x,y,t) anim <- ggplot(billiard, aes(x, y)) + geom_path(size = 2) + geom_path(size = 1, colour = "red")+ geom_point(colour = "blue", size = 8) + geom_path(boundary, mapping = aes(a, b, group=d), size = 3)+ theme_minimal() + labs(title = 'Simulation of the motion of a Ball in a Billard Table. ')+ transition_reveal(t) animate(anim, nframes = 100, type="cairo") anim_save("billiards.gif", type="cairo") }
Спасибо, что зашли.
Если вы узнаете что-то новое из этой статьи, хлопните в ладоши и поделитесь ею со своими коллегами и сообществом, чтобы они получили удовольствие и поигрались с ней.
Быть в курсе! Оставайтесь благословенными!
Сриджит.
© SrijitMukherjee2020