Just another update
This commit is contained in:
parent
a25938f123
commit
00a190b0a6
6591 changed files with 94363 additions and 23227 deletions
|
|
@ -1,3 +1,4 @@
|
|||
One good way of making an animation is by simulating a physical system and illustrating the variables in that system using a dynamically changing graphical display. The classic such physical system is a [[wp:Pendulum|simple gravity pendulum]].
|
||||
One good way of making an animation is by simulating a physical system and illustrating the variables in that system using a dynamically changing graphical display.
|
||||
The classic such physical system is a [[wp:Pendulum|simple gravity pendulum]].
|
||||
|
||||
For this task, create a simple physical model of a pendulum and animate it.
|
||||
|
|
|
|||
45
Task/Animate-a-pendulum/Common-Lisp/animate-a-pendulum.lisp
Normal file
45
Task/Animate-a-pendulum/Common-Lisp/animate-a-pendulum.lisp
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
(defvar *frame-rate* 30)
|
||||
(defvar *damping* 0.99 "Deceleration factor.")
|
||||
|
||||
(defun make-pendulum (length theta0 x)
|
||||
"Returns an anonymous function with enclosed state representing a pendulum."
|
||||
(let* ((theta (* (/ theta0 180) pi))
|
||||
(acceleration 0))
|
||||
(if (< length 40) (setf length 40)) ;;avoid a divide-by-zero
|
||||
(lambda ()
|
||||
;;Draws the pendulum, updating its location and speed.
|
||||
(sdl:draw-line (sdl:point :x x :y 1)
|
||||
(sdl:point :x (+ (* (sin theta) length) x)
|
||||
:y (* (cos theta) length)))
|
||||
(sdl:draw-filled-circle (sdl:point :x (+ (* (sin theta) length) x)
|
||||
:y (* (cos theta) length))
|
||||
20
|
||||
:color sdl:*yellow*
|
||||
:stroke-color sdl:*white*)
|
||||
;;The magic constant approximates the speed we want for a given frame-rate.
|
||||
(incf acceleration (* (sin theta) (* *frame-rate* -0.001)))
|
||||
(incf theta acceleration)
|
||||
(setf acceleration (* acceleration *damping*)))))
|
||||
|
||||
|
||||
(defun main (&optional (w 640) (h 480))
|
||||
(sdl:with-init ()
|
||||
(sdl:window w h :title-caption "Pendulums"
|
||||
:fps (make-instance 'sdl:fps-fixed))
|
||||
(setf (sdl:frame-rate) *frame-rate*)
|
||||
(let ((pendulums nil))
|
||||
(sdl:with-events ()
|
||||
(:quit-event () t)
|
||||
(:idle ()
|
||||
(sdl:clear-display sdl:*black*)
|
||||
(mapcar #'funcall pendulums) ;;Draw all the pendulums
|
||||
|
||||
(sdl:update-display))
|
||||
(:key-down-event (:key key)
|
||||
(cond ((sdl:key= key :sdl-key-escape)
|
||||
(sdl:push-quit-event))
|
||||
((sdl:key= key :sdl-key-space)
|
||||
(push (make-pendulum (random (- h 100))
|
||||
(random 90)
|
||||
(round w 2))
|
||||
pendulums))))))))
|
||||
74
Task/Animate-a-pendulum/Fortran/animate-a-pendulum.f
Normal file
74
Task/Animate-a-pendulum/Fortran/animate-a-pendulum.f
Normal file
|
|
@ -0,0 +1,74 @@
|
|||
!Implemented by Anant Dixit (October, 2014)
|
||||
program animated_pendulum
|
||||
implicit none
|
||||
double precision, parameter :: pi = 4.0D0*atan(1.0D0), l = 1.0D-1, dt = 1.0D-2, g = 9.8D0
|
||||
integer :: io
|
||||
double precision :: s_ang, c_ang, p_ang, n_ang
|
||||
|
||||
write(*,*) 'Enter starting angle (in degrees):'
|
||||
do
|
||||
read(*,*,iostat=io) s_ang
|
||||
if(io.ne.0 .or. s_ang.lt.-90.0D0 .or. s_ang.gt.90.0D0) then
|
||||
write(*,*) 'Please enter an angle between 90 and -90 degrees:'
|
||||
else
|
||||
exit
|
||||
end if
|
||||
end do
|
||||
call system('clear')
|
||||
|
||||
c_ang = s_ang*pi/180.0D0
|
||||
p_ang = c_ang
|
||||
|
||||
call display(c_ang)
|
||||
do
|
||||
call next_time_step(c_ang,p_ang,g,l,dt,n_ang)
|
||||
if(abs(c_ang-p_ang).ge.0.05D0) then
|
||||
call system('clear')
|
||||
call display(c_ang)
|
||||
end if
|
||||
end do
|
||||
end program
|
||||
|
||||
subroutine next_time_step(c_ang,p_ang,g,l,dt,n_ang)
|
||||
double precision :: c_ang, p_ang, g, l, dt, n_ang
|
||||
n_ang = (-g*sin(c_ang)/l)*2.0D0*dt**2 + 2.0D0*c_ang - p_ang
|
||||
p_ang = c_ang
|
||||
c_ang = n_ang
|
||||
end subroutine
|
||||
|
||||
subroutine display(c_ang)
|
||||
double precision :: c_ang
|
||||
character (len=*), parameter :: cfmt = '(A1)'
|
||||
double precision :: rx, ry
|
||||
integer :: x, y, i, j
|
||||
rx = 45.0D0*sin(c_ang)
|
||||
ry = 22.5D0*cos(c_ang)
|
||||
x = int(rx)+51
|
||||
y = int(ry)+2
|
||||
do i = 1,32
|
||||
do j = 1,100
|
||||
if(i.eq.y .and. j.eq.x) then
|
||||
write(*,cfmt,advance='no') 'O'
|
||||
else if(i.eq.y .and. (j.eq.(x-1).or.j.eq.(x+1))) then
|
||||
write(*,cfmt,advance='no') 'G'
|
||||
else if(j.eq.x .and. (i.eq.(y-1).or.i.eq.(y+1))) then
|
||||
write(*,cfmt,advance='no') 'G'
|
||||
else if(i.eq.y .and. (j.eq.(x-2).or.j.eq.(x+2))) then
|
||||
write(*,cfmt,advance='no') '#'
|
||||
else if(j.eq.x .and. (i.eq.(y-2).or.i.eq.(y+2))) then
|
||||
write(*,cfmt,advance='no') 'G'
|
||||
else if((i.eq.(y+1).and.j.eq.(x+1)) .or. (i.eq.(y-1).and.j.eq.(x-1))) then
|
||||
write(*,cfmt,advance='no') '#'
|
||||
else if((i.eq.(y+1).and.j.eq.(x-1)) .or. (i.eq.(y-1).and.j.eq.(x+1))) then
|
||||
write(*,cfmt,advance='no') '#'
|
||||
else if(j.eq.50) then
|
||||
write(*,cfmt,advance='no') '|'
|
||||
else if(i.eq.2) then
|
||||
write(*,cfmt,advance='no') '-'
|
||||
else
|
||||
write(*,cfmt,advance='no') ' '
|
||||
end if
|
||||
end do
|
||||
write(*,*)
|
||||
end do
|
||||
end subroutine
|
||||
|
|
@ -2,7 +2,7 @@ require 'gl2 trig'
|
|||
coinsert 'jgl2'
|
||||
|
||||
DT =: %30 NB. seconds
|
||||
ANGLE=: 0.25p1 NB. radians
|
||||
ANGLE=: 0.45p1 NB. radians
|
||||
L =: 1 NB. metres
|
||||
G =: 9.80665 NB. ms_2
|
||||
VEL =: 0 NB. ms_1
|
||||
|
|
@ -33,8 +33,7 @@ drawPendulum=: verb define
|
|||
width=. {. glqwh''
|
||||
ps=. (-: width) , 40
|
||||
pe=. ps + 280 <.@* (cos , sin) 0.5p1 + y NB. adjust orientation
|
||||
glrgb 91 91 91
|
||||
glbrush''
|
||||
glbrush glrgb 91 91 91
|
||||
gllines ps , pe
|
||||
glellipse (,~ ps - -:) 40 15
|
||||
glellipse (,~ pe - -:) 20 20
|
||||
52
Task/Animate-a-pendulum/J/animate-a-pendulum-2.j
Normal file
52
Task/Animate-a-pendulum/J/animate-a-pendulum-2.j
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
require 'gl2 trig'
|
||||
coinsert 'jgl2'
|
||||
|
||||
DT =: %30 NB. seconds
|
||||
ANGLE=: 0.45p1 NB. radians
|
||||
L =: 1 NB. metres
|
||||
G =: 9.80665 NB. ms_2
|
||||
VEL =: 0 NB. ms_1
|
||||
|
||||
PEND=: noun define
|
||||
pc pend;pn "Pendulum";
|
||||
minwh 320 200; cc isi isigraph type flush;
|
||||
)
|
||||
|
||||
pend_run=: verb define
|
||||
wd PEND,'pshow'
|
||||
wd 'timer ',":DT * 1000
|
||||
)
|
||||
|
||||
pend_close=: verb define
|
||||
wd 'timer 0; pclose'
|
||||
)
|
||||
|
||||
sys_timer_z_=: verb define
|
||||
recalcAngle_base_ ''
|
||||
wd 'psel pend; set isi invalid'
|
||||
)
|
||||
|
||||
pend_isi_paint=: verb define
|
||||
drawPendulum ANGLE
|
||||
)
|
||||
|
||||
recalcAngle=: verb define
|
||||
accel=. - (G % L) * sin ANGLE
|
||||
VEL =: VEL + accel * DT
|
||||
ANGLE=: ANGLE + VEL * DT
|
||||
)
|
||||
|
||||
drawPendulum=: verb define
|
||||
width=. {. glqwh''
|
||||
ps=. (-: width) , 20
|
||||
pe=. ps + 150 <.@* (cos , sin) 0.5p1 + y NB. adjust orientation
|
||||
glclear''
|
||||
glbrush glrgb 91 91 91 NB. gray
|
||||
gllines ps , pe
|
||||
glellipse (,~ ps - -:) 40 15
|
||||
glrect 0 0, width, 20
|
||||
glbrush glrgb 255 255 0 NB. yellow
|
||||
glellipse (,~ pe - -:) 15 15 NB. orb
|
||||
)
|
||||
|
||||
pend_run''
|
||||
|
|
@ -1,33 +1,26 @@
|
|||
import scala.swing._
|
||||
import scala.swing.Swing._
|
||||
import scala.actors._
|
||||
import scala.actors.Actor._
|
||||
|
||||
import java.awt.{Color, Graphics}
|
||||
import java.awt.Color
|
||||
import scala.actors.Actor
|
||||
import scala.swing.{ Graphics2D, MainFrame, Panel, SimpleSwingApplication }
|
||||
import scala.swing.Swing.pair2Dimension
|
||||
|
||||
object Pendulum extends SimpleSwingApplication {
|
||||
|
||||
val length = 100
|
||||
|
||||
val prefSizeX = 2*length+50
|
||||
val prefSizeY = length/2*3
|
||||
val length = 100
|
||||
|
||||
lazy val ui = new Panel {
|
||||
import math._
|
||||
import scala.math.{ cos, Pi, sin }
|
||||
background = Color.white
|
||||
preferredSize = (prefSizeX, prefSizeY)
|
||||
preferredSize = (2 * length + 50, length / 2 * 3)
|
||||
peer.setDoubleBuffered(true)
|
||||
|
||||
var angle: Double = Pi/2;
|
||||
var angle: Double = Pi / 2
|
||||
|
||||
def pendular = new Actor {
|
||||
var angleAccel, angleVelocity = 0.0;
|
||||
var dt = 0.1
|
||||
var angleVelocity = 0.0
|
||||
val dt = 0.1
|
||||
|
||||
def act() {
|
||||
while (true) {
|
||||
angleAccel = -9.81 / length * sin(angle)
|
||||
angleVelocity += angleAccel * dt
|
||||
angleVelocity += (-9.81 / length * sin(angle)) * dt
|
||||
angle += angleVelocity * dt
|
||||
repaint()
|
||||
Thread.sleep(15)
|
||||
|
|
@ -38,14 +31,11 @@ object Pendulum extends SimpleSwingApplication {
|
|||
override def paintComponent(g: Graphics2D) = {
|
||||
super.paintComponent(g)
|
||||
|
||||
g.setColor(Color.white);
|
||||
g.fillRect(0, 0, size.width, size.height);
|
||||
val anchorX = size.width / 2
|
||||
val anchorY = size.height / 4
|
||||
val ballX = anchorX + (sin(angle) * length).toInt
|
||||
val ballY = anchorY + (cos(angle) * length).toInt
|
||||
val (anchorX, anchorY) = (size.width / 2, size.height / 4)
|
||||
val (ballX, ballY) =
|
||||
(anchorX + (sin(angle) * length).toInt, anchorY + (cos(angle) * length).toInt)
|
||||
g.setColor(Color.lightGray)
|
||||
g.drawLine(anchorX-2*length, anchorY, anchorX+2*length, anchorY)
|
||||
g.drawLine(anchorX - 2 * length, anchorY, anchorX + 2 * length, anchorY)
|
||||
g.setColor(Color.black)
|
||||
g.drawLine(anchorX, anchorY, ballX, ballY)
|
||||
g.fillOval(anchorX - 3, anchorY - 4, 7, 7)
|
||||
|
|
@ -58,7 +48,7 @@ object Pendulum extends SimpleSwingApplication {
|
|||
def top = new MainFrame {
|
||||
title = "Rosetta Code >>> Task: Animate a pendulum | Language: Scala"
|
||||
contents = ui
|
||||
centerOnScreen
|
||||
ui.pendular.start
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue