Kirjautuminen

Haku

Tehtävät

Keskustelu: Koodit: Java: Heiluri

Sivun loppuun

Hipo [08.10.2002 13:26:49]

#

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>

Hipo [09.10.2002 01:18:25]

#

No ähh, muokkaus-ominaisuuden tilaus myös koodivinkkeihin, kun unohtu ääkköset korjata kommenteista.

thefox [10.10.2002 14:55:05]

#

Tuo käännetty appletti ei tunnu toimivan..

Hipo [10.10.2002 16:01:06]

#

Kyl se itelläni Sunin appletviewerillä ja Mozillalla toimii. Linuxissa siis. Windowsissakin Netscapella. Mut kai se edes jotain sanoo, kun ei toimi?

KimmKM [10.10.2002 17:18:40]

#

Tuolla alapalkissa (missä kaikki Valmis ja yhdistetään jutut on) vilahtaa ehkä puolen sekunnin ajan Aplett Not found

(nimetön) [11.10.2002 15:58:34]

#

joo toimiihan toi mutta se heiluri bugaa pienen odottamisen jälkeen:P

Fisher [21.06.2004 19:07:04]

#

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

Niiskuneiti [08.02.2010 21:54:05]

#

:D


Sivun alkuun

Vastaus

Aihe on jo aika vanha, joten et voi enää vastata siihen.

Tietoa sivustosta