Just another update

This commit is contained in:
Ingy döt Net 2015-02-20 00:35:01 -05:00
parent a25938f123
commit 00a190b0a6
6591 changed files with 94363 additions and 23227 deletions

View file

@ -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.

View 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))))))))

View 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

View file

@ -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

View 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''

View file

@ -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
}
}