Another update from ingydotnet^djgoku

This commit is contained in:
Ingy döt Net 2015-11-18 06:14:39 +00:00
parent 91df62d461
commit 948b86eafa
7604 changed files with 108452 additions and 22726 deletions

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

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

View file

@ -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)]);