Another update from ingydotnet^djgoku
This commit is contained in:
parent
91df62d461
commit
948b86eafa
7604 changed files with 108452 additions and 22726 deletions
116
Task/Animate-a-pendulum/Go/animate-a-pendulum.go
Normal file
116
Task/Animate-a-pendulum/Go/animate-a-pendulum.go
Normal file
|
|
@ -0,0 +1,116 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"github.com/google/gxui"
|
||||
"github.com/google/gxui/drivers/gl"
|
||||
"github.com/google/gxui/math"
|
||||
"github.com/google/gxui/themes/dark"
|
||||
omath "math"
|
||||
"time"
|
||||
)
|
||||
|
||||
//Two pendulums animated
|
||||
//Top: Mathematical pendulum with small-angle approxmiation (not appropiate with PHI_ZERO=pi/2)
|
||||
//Bottom: Simulated with differential equation phi'' = g/l * sin(phi)
|
||||
|
||||
const (
|
||||
ANIMATION_WIDTH int = 480
|
||||
ANIMATION_HEIGHT int = 320
|
||||
BALL_RADIUS float32 = 25.0
|
||||
METER_PER_PIXEL float64 = 1.0 / 20.0
|
||||
PHI_ZERO float64 = omath.Pi * 0.5
|
||||
)
|
||||
|
||||
var (
|
||||
l float64 = float64(ANIMATION_HEIGHT) * 0.5
|
||||
freq float64 = omath.Sqrt(9.81 / (l * METER_PER_PIXEL))
|
||||
)
|
||||
|
||||
type Pendulum interface {
|
||||
GetPhi() float64
|
||||
}
|
||||
|
||||
type mathematicalPendulum struct {
|
||||
start time.Time
|
||||
}
|
||||
|
||||
func (p *mathematicalPendulum) GetPhi() float64 {
|
||||
if (p.start == time.Time{}) {
|
||||
p.start = time.Now()
|
||||
}
|
||||
t := float64(time.Since(p.start).Nanoseconds()) / omath.Pow10(9)
|
||||
return PHI_ZERO * omath.Cos(t*freq)
|
||||
}
|
||||
|
||||
type numericalPendulum struct {
|
||||
currentPhi float64
|
||||
angAcc float64
|
||||
angVel float64
|
||||
lastTime time.Time
|
||||
}
|
||||
|
||||
func (p *numericalPendulum) GetPhi() float64 {
|
||||
dt := 0.0
|
||||
if (p.lastTime != time.Time{}) {
|
||||
dt = float64(time.Since(p.lastTime).Nanoseconds()) / omath.Pow10(9)
|
||||
}
|
||||
p.lastTime = time.Now()
|
||||
|
||||
p.angAcc = -9.81 / (float64(l) * METER_PER_PIXEL) * omath.Sin(p.currentPhi)
|
||||
p.angVel += p.angAcc * dt
|
||||
p.currentPhi += p.angVel * dt
|
||||
|
||||
return p.currentPhi
|
||||
}
|
||||
|
||||
func draw(p Pendulum, canvas gxui.Canvas, x, y int) {
|
||||
attachment := math.Point{X: ANIMATION_WIDTH/2 + x, Y: y}
|
||||
|
||||
phi := p.GetPhi()
|
||||
ball := math.Point{X: x + ANIMATION_WIDTH/2 + math.Round(float32(l*omath.Sin(phi))), Y: y + math.Round(float32(l*omath.Cos(phi)))}
|
||||
|
||||
line := gxui.Polygon{gxui.PolygonVertex{attachment, 0}, gxui.PolygonVertex{ball, 0}}
|
||||
|
||||
canvas.DrawLines(line, gxui.DefaultPen)
|
||||
|
||||
m := math.Point{int(BALL_RADIUS), int(BALL_RADIUS)}
|
||||
rect := math.Rect{ball.Sub(m), ball.Add(m)}
|
||||
canvas.DrawRoundedRect(rect, BALL_RADIUS, BALL_RADIUS, BALL_RADIUS, BALL_RADIUS, gxui.TransparentPen, gxui.CreateBrush(gxui.Yellow))
|
||||
}
|
||||
|
||||
func appMain(driver gxui.Driver) {
|
||||
theme := dark.CreateTheme(driver)
|
||||
|
||||
window := theme.CreateWindow(ANIMATION_WIDTH, 2*ANIMATION_HEIGHT, "Pendulum")
|
||||
window.SetBackgroundBrush(gxui.CreateBrush(gxui.Gray50))
|
||||
|
||||
image := theme.CreateImage()
|
||||
|
||||
ticker := time.NewTicker(time.Millisecond * 15)
|
||||
pendulum := &mathematicalPendulum{}
|
||||
pendulum2 := &numericalPendulum{PHI_ZERO, 0.0, 0.0, time.Time{}}
|
||||
|
||||
go func() {
|
||||
for _ = range ticker.C {
|
||||
canvas := driver.CreateCanvas(math.Size{ANIMATION_WIDTH, 2 * ANIMATION_HEIGHT})
|
||||
canvas.Clear(gxui.White)
|
||||
|
||||
draw(pendulum, canvas, 0, 0)
|
||||
draw(pendulum2, canvas, 0, ANIMATION_HEIGHT)
|
||||
|
||||
canvas.Complete()
|
||||
driver.Call(func() {
|
||||
image.SetCanvas(canvas)
|
||||
})
|
||||
}
|
||||
}()
|
||||
|
||||
window.AddChild(image)
|
||||
|
||||
window.OnClose(ticker.Stop)
|
||||
window.OnClose(driver.Terminate)
|
||||
}
|
||||
|
||||
func main() {
|
||||
gl.StartDriver(appMain)
|
||||
}
|
||||
46
Task/Animate-a-pendulum/Kotlin/animate-a-pendulum.kotlin
Normal file
46
Task/Animate-a-pendulum/Kotlin/animate-a-pendulum.kotlin
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
package pendulum
|
||||
|
||||
import java.awt.*
|
||||
import java.util.concurrent.*
|
||||
import javax.swing.*
|
||||
|
||||
class Pendulum(private val length: Int) : JPanel(), Runnable {
|
||||
init {
|
||||
val f = JFrame("Pendulum")
|
||||
f.add(this)
|
||||
f.defaultCloseOperation = JFrame.EXIT_ON_CLOSE
|
||||
f.pack()
|
||||
f.isVisible = true
|
||||
isDoubleBuffered = true
|
||||
}
|
||||
|
||||
override fun paint(g: Graphics) {
|
||||
g.color = Color.WHITE
|
||||
g.fillRect(0, 0, width, height)
|
||||
g.color = Color.BLACK
|
||||
val anchor = Element(width / 2, height / 4)
|
||||
val ball = Element((anchor.x + Math.sin(angle) * length).toInt(), (anchor.y + Math.cos(angle) * length).toInt())
|
||||
g.drawLine(anchor.x, anchor.y, ball.x, ball.y)
|
||||
g.fillOval(anchor.x - 3, anchor.y - 4, 7, 7)
|
||||
g.fillOval(ball.x - 7, ball.y - 7, 14, 14)
|
||||
}
|
||||
|
||||
override fun run() {
|
||||
angleVelocity += -9.81 / length * Math.sin(angle) * dt
|
||||
angle += angleVelocity * dt
|
||||
repaint()
|
||||
}
|
||||
|
||||
override fun getPreferredSize() = Dimension(2 * length + 50, length / 2 * 3)
|
||||
|
||||
private data class Element(val x: Int, val y: Int)
|
||||
|
||||
private val dt = 0.1
|
||||
private var angle = Math.PI / 2
|
||||
private var angleVelocity = 0.0
|
||||
}
|
||||
|
||||
fun main(a: Array<String>) {
|
||||
val executor = Executors.newSingleThreadScheduledExecutor()
|
||||
executor.scheduleAtFixedRate(Pendulum(200), 0, 15, TimeUnit.MILLISECONDS)
|
||||
}
|
||||
|
|
@ -54,7 +54,9 @@ for time = (deltaTime:deltaTime:endTime)
|
|||
acceleration = totalForce / mass; %F = ma
|
||||
velocity = velocity + acceleration * deltaTime;
|
||||
rodLength = rodLength + velocity(1) * deltaTime;
|
||||
theta = theta + velocity(2) * deltaTime;
|
||||
theta = theta + velocity(2) * deltaTime; % Attention!! Mistake here.
|
||||
% Velocity needs to be divided by pendulum length and scaled to degrees:
|
||||
% theta = theta + velocity(2) * deltaTime/rodLength/pi*180;
|
||||
|
||||
position = rodPivotPoint - (rodLength*[-sind(theta) cosd(theta)]);
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue