How to resolve the algorithm Animate a pendulum step by step in the E programming language

Published on 12 May 2024 09:40 PM
#E

How to resolve the algorithm Animate a pendulum step by step in the E programming language

Table of Contents

Problem Statement

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 simple gravity pendulum.

Create a simple physical model of a pendulum and animate it.

Let's start with the solution:

Step by Step solution about How to resolve the algorithm Animate a pendulum step by step in the E programming language

Source code in the e programming language

#!/usr/bin/env rune
pragma.syntax("0.9")

def pi := (-1.0).acos()
def makeEPainter := 
def makeLamportSlot := 
def whenever := 
def colors := 

# --------------------------------------------------------------
# --- Definitions

def makePendulumSim(length_m :float64,
                    gravity_mps2 :float64,
                    initialAngle_rad :float64,
                    timestep_ms :int) {
  var velocity := 0
  def &angle := makeLamportSlot(initialAngle_rad)
  def k := -gravity_mps2/length_m
  def timestep_s := timestep_ms / 1000
  def clock := timer.every(timestep_ms, fn _ {
    def acceleration := k * angle.sin()
    velocity += acceleration * timestep_s
    angle    += velocity     * timestep_s
  })
  return [clock, &angle]
}

def makeDisplayComponent(&angle) {
  def c
  def updater := whenever([&angle], fn { c.repaint() })
  
  bind c := makeEPainter(def paintCallback {
    to paintComponent(g) {
      try {
        def originX := c.getWidth() // 2
        def originY := c.getHeight() // 2
        def pendRadius := (originX.min(originY) * 0.95).round()
        def ballRadius := (originX.min(originY) * 0.04).round()
        def ballX := (originX + angle.sin() * pendRadius).round()
        def ballY := (originY + angle.cos() * pendRadius).round()

        g.setColor(colors.getWhite())
        g.fillRect(0, 0, c.getWidth(), c.getHeight())
        g.setColor(colors.getBlack())
        
        g.fillOval(originX - 2, originY - 2, 4, 4)
        g.drawLine(originX, originY, ballX, ballY)
        g.fillOval(ballX - ballRadius, ballY - ballRadius, ballRadius * 2, ballRadius * 2)
      
        updater[] # provoke interest provided that we did get drawn (window not closed)
      } catch p {
        stderr.println(`In paint callback: $p${p.eStack()}`)
      }
    }
  })
  
  c.setPreferredSize((300, 300))
  return c
}

# --------------------------------------------------------------
# --- Application setup

def [clock, &angle] := makePendulumSim(1, 9.80665, pi*99/100, 10)

# Initialize AWT, move to AWT event thread
when (currentVat.morphInto("awt")) -> {

  # Create the window
  def frame := ("Pendulum")
  frame.setContentPane(def display := makeDisplayComponent(&angle))
  frame.addWindowListener(def mainWindowListener {
    to windowClosing(_) {
      clock.stop()
      interp.continueAtTop()
    }
    match _ {}
  })
  frame.setLocation(50, 50)
  frame.pack()

  # Start and become visible
  frame.show()
  clock.start()
}

interp.blockAtTop()

  

You may also check:How to resolve the algorithm Loops/Do-while step by step in the E programming language
You may also check:How to resolve the algorithm Zig-zag matrix step by step in the E programming language
You may also check:How to resolve the algorithm Runtime evaluation/In an environment step by step in the E programming language
You may also check:How to resolve the algorithm Binary strings step by step in the E programming language
You may also check:How to resolve the algorithm Bulls and cows step by step in the E programming language