Jonkinlainen heiluri, koulusta opittua suurin osa, mutta osa asioista on tehty mutu-periaatteella. Kommentteja on fysiikkapuolella vähän enemmänkin.
import java.awt.*; import java.awt.event.*; import java.awt.geom.*; import java.awt.image.*; import javax.swing.*; import java.util.*; class Pendulum { class Vector2D { double x, y; Vector2D(double x, double y) { set(x, y); } void set(double x, double y) { this.x = x; this.y = y; } void scale(double s) { x*=s; y*=s; } double dot(Vector2D b) { return x*b.x + y*b.y; } double length() { return Math.sqrt(dot(this)); } } Vector2D o, p; double kv=0, radius; /* Kulmanopeus */ double ballradius = 0.3; Pendulum(double ox, double oy, double a, double l) { o = new Vector2D(ox, oy); p = new Vector2D(Math.cos(3.1415926*a/180.0) * l, Math.sin(3.1415926*a/180.0) * l); radius = l; } void move(double dt) { addVelocity(new Vector2D(0*dt, 10*dt)); /* Pyöritetään kulmanopeuden verran */ double rad = kv*dt / radius * 2 * 3.1415926; /* kulmanopeus -> rad */ Vector2D backup = p; p.x = Math.cos(rad)*backup.x + Math.sin(rad)*backup.y; p.y = -Math.sin(rad)*backup.x + Math.cos(rad)*backup.y; fixPosition(); kv *= 1 - 0.1*dt; /* Kitka & ilmanvastus */ } void fixPosition() { p = getNormal(); p.scale(radius); } Vector2D getNormal() { double l = 1.0 / p.length(); return new Vector2D(p.x * l, p.y * l); } void checkCollision(Pendulum b) { Vector2D delta = new Vector2D((b.o.x + b.p.x) - (o.x + p.x), (b.o.y + b.p.y) - (o.y + p.y)); double deltal = delta.length(); if(deltal <= ballradius+b.ballradius) { delta.scale(1.0 / deltal); Vector2D v1 = getVelocity(); /* Delta velocity */ Vector2D v2 = b.getVelocity(); Vector2D dv = new Vector2D(v2.x-v1.x, v2.y-v1.y); /* Projektoidaan nopeus törmäysnormaalille ja lisätään */ double dot = delta.dot(dv); addVelocity(new Vector2D(dot*delta.x, dot*delta.y)); b.addVelocity(new Vector2D(-dot*delta.x, -dot*delta.y)); /* Tökitään irti toisistaan */ deltal = (ballradius + b.ballradius - deltal) / 2; p.x -= delta.x * deltal; p.y -= delta.y * deltal; fixPosition(); b.p.x += delta.x * deltal; b.p.y += delta.y * deltal; b.fixPosition(); } } Vector2D getVelocity() { Vector2D n = getNormal(); return new Vector2D(n.y*kv, -n.x*kv); } void addVelocity(Vector2D v) { /* Projektoidaan voima tangentille ennen lisäystä */ Vector2D n = getNormal(); double len = n.dot(v); v.x = v.x - len*n.x; v.y = v.y - len*n.y; if(n.y*v.x - n.x*v.y < 0) kv -= v.length(); else kv += v.length(); } void paint(Graphics2D g, double s) { double sx = o.x*s + p.x*s; /* Pallon paikka skaalattuna */ double sy = o.y*s + p.y*s; double r = ballradius*s; Vector2D n = getNormal(); g.setPaint(Color.black); g.setStroke(new BasicStroke((float) s*0.1f)); g.draw(new Line2D.Double(o.x*s, o.y*s, sx-r*n.x, sy-r*n.y)); g.setStroke(new BasicStroke((float) s*0.1f)); g.draw(new Ellipse2D.Double(sx-r+0.05*s, sy-r+0.05*s, r*2-0.05*s, r*2-0.05*s)); } } public class PendulumApplet extends JApplet implements Runnable { BufferedImage dblbuf; Thread thread; Vector pendulums; public void init() { setBackground(Color.white); pendulums = new Vector(); for(int i=0; i<2; i++) { pendulums.add(new Pendulum(1.0 + i*0.61, 2.0, 90+179, 1.5)); } for(int i=2; i<6; i++) { pendulums.add(new Pendulum(1.0 + i*0.61, 2.0, 90, 1.5)); } } public void paint(Graphics g) { int w = getSize().width, h = getSize().height; if(dblbuf==null || dblbuf.getWidth()!=w || dblbuf.getHeight()!=h) { dblbuf = (BufferedImage) createImage(w, h); } Graphics2D g2 = dblbuf.createGraphics(); g2.setBackground(getBackground()); g2.clearRect(0, 0, w, h); g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); for(int i=0; i<pendulums.size(); i++) { ((Pendulum) pendulums.get(i)).paint(g2, w / 5.0); } g2.dispose(); g.drawImage(dblbuf, 0, 0, this); } public void start() { thread = new Thread(this); thread.setPriority(Thread.MIN_PRIORITY); thread.start(); } public void run() { Thread me = Thread.currentThread(); while (thread == me) { repaint(); try { thread.sleep(10); for(int t=0; t<10; t++) { for(int i=0; i<pendulums.size(); i++) { ((Pendulum) pendulums.get(i)).move(1.0 / 1000.0); } for(int i=0; i<pendulums.size(); i++) { for(int j=i+1; j<pendulums.size(); j++) { ((Pendulum) pendulums.get(i)).checkCollision((Pendulum) pendulums.get(j)); } } } } catch (InterruptedException e) { break; } } thread = null; } }
<applet code="PendulumApplet.class" width="300" height="300">Java applet</applet>
No ähh, muokkaus-ominaisuuden tilaus myös koodivinkkeihin, kun unohtu ääkköset korjata kommenteista.
Tuo käännetty appletti ei tunnu toimivan..
Kyl se itelläni Sunin appletviewerillä ja Mozillalla toimii. Linuxissa siis. Windowsissakin Netscapella. Mut kai se edes jotain sanoo, kun ei toimi?
Tuolla alapalkissa (missä kaikki Valmis ja yhdistetään jutut on) vilahtaa ehkä puolen sekunnin ajan Aplett Not found
joo toimiihan toi mutta se heiluri bugaa pienen odottamisen jälkeen:P
C:\java\bin>javac PendulumApplet.java PendulumApplet.java:3: Package java.awt.geom not found in import. import java.awt.geom.*; ^ PendulumApplet.java:5: Package javax.swing not found in import. import javax.swing.*; ^ PendulumApplet.java:122: Superclass JApplet of class PendulumApplet not found. public class PendulumApplet extends JApplet implements Runnable { ^ 3 errors
eli ei toimi
:D
Aihe on jo aika vanha, joten et voi enää vastata siihen.