import java.awt.*; import java.awt.event.*; public class pendel extends Frame implements Runnable { private Thread jooksja = null; // pendli pikkus ekraanipunktides private int pendlipikkus; // mis nurgast hetkevõnke amplituut algas, 0 kraadi siis kui pendel ripub // radiaanides on asi private double vonkenurk; // mis on pendli hetkenurk private double hetkenurk; // kui kiiresti pendel liigub, tegelikult nurk järgmise sammumi private double kiirus; // määrab ära pendli muutumise kiiruse maksimumi // aplituut seega kiiruse muutumise funktsioonile private double amplituut; // kummale poole võnge toimub 0 - > vasakult paremale, 1 vastupidi private int suund; // koordinaadid private int x,y; public pendel() { setSize(400, 400); setVisible(true); pendlipikkus = 200; kiirus = 0; vonkenurk = Math.PI / 4; // 45 kraadi, 2*PI on 360 // 1 sellepärast, et kohe alguses pööratakse suund ringi // kuna võnke kiirus on null suund = 1; // selleks, et akent saaks ka kinni panna // CloseWindow on allpool defineeritud addWindowListener(new CloseWindow()); start(); } public void start() { jooksja = new Thread(this); jooksja.start(); } public void stop() { jooksja = null; } public void arvutaHetk() { // kiirust kajastab muutumise nurk // kui kiirus on 0, siis hakkab pendel teisele poole kukkuma // et kiirust normaalsena simuleerida, teeme alates // 0.00000 suurusest kiiruse nulliks // selleks korrutame asja 10000, teeme täisarvuks // ja jagame 10000, sellisel juhul kõik arvud // alates viiendast komakohast nullitakse // kiirus = (double)((int)(kiirus * 10000)) / 10000; // mida pikem pendel, seda aeglasemalt liigub // pöördvõrdeline seos amplituut = 100 * (Math.PI / 120) / pendlipikkus; // kui kiirus on null (muutumise nurk, on pendel kuskile äärde jõudnud if ((kiirus == 0) || ( (vonkenurk - Math.abs(hetkenurk)) < 0.001 )) { if (suund == 0) suund = 1; else suund = 0; // iga amplituudi lõppedes vähendame võnkenurka 1 kraadi võrra väiksem vonkenurk = vonkenurk - (2 * Math.PI / 180); if (vonkenurk < ((2 * Math.PI) / 500)) vonkenurk = 0; hetkenurk = vonkenurk - Math.PI / 180; if (suund == 0) hetkenurk = -1 * hetkenurk; } else { if (suund == 0) { hetkenurk = hetkenurk + kiirus; } else { hetkenurk = hetkenurk - kiirus; } } //arvutame kiiruse, mis on hetkenurga koosinusfunktsioon kiirus = amplituut * Math.cos(hetkenurk * (Math.PI / 360) * 340 / vonkenurk + 5 * Math.PI/360) + amplituut; if (kiirus < 0.0001) kiirus = kiirus * 10; if (kiirus < 0.001) kiirus = kiirus * 10; if (kiirus < 0.01) kiirus = kiirus * 5; } // teeb radiaanidest kraadid (to degrees) private double todeg(double i) { return(i * 360 / (Math.PI * 2)); } // teostab pendli joonistamise public void loksuta() { Graphics g = this.getGraphics(); arvutaHetk(); x = (int)(getSize().width / 2 + pendlipikkus * Math.sin(hetkenurk)); y = (int)(pendlipikkus * Math.abs(Math.cos(hetkenurk))); g.setColor(Color.white); g.fillRect(0, 0, getSize().width, getSize().height); g.setColor(Color.black); g.drawOval(x,y,15,15); g.drawLine(getSize().width / 2,0,x,y); } public void run() { while (Thread.currentThread() == jooksja) { if (vonkenurk > 0) loksuta(); try { Thread.sleep(20); } catch (InterruptedException e) { System.out.println ("Kalakatkestus"); } } } public static void main(String[] args) { pendel pd = new pendel(); } } class CloseWindow extends WindowAdapter { public void windowClosing(WindowEvent e) { System.exit(0); } } // Programmi seletus: // Run meetodis käib tsykkel mis kutsub välja loksuta meetodit, see kutsub välja arvutaHetk meetodi, // mis arvutab välja pendli koordinaadid, ning pärast seda väljakutsumist joonistab välja pendli. // Hetkenurk on pendli parajasti käes olev nurk, vonkenurk see, kuhuni pendel võngub // sumbumise käigus vonkenurka muutkui vähendadatakse kuni saab piisavalt väikseks , siis pannakse pendel seisma // Amplituut on pendli pikkusest sõltuv, st, võnkumise kiirus (mis sõltub amplituudist) // sõltub pendli pikkusest //Suund näitab, kummale poole pendel võngub 0 tähendab vasaakult paremale, muidu vastupidi (1) // Kiirus on muutuv suurus, mida liidetakse juurde hetkenurgale, et tekiks liikumine pendlil. // kiirus sõltub hetkenurgast koosinusfunktsiooni järgi, see simuleerib seda kiirenevat kukkumist // pendli lõpus on lisaklass mis kuulab aknale saadetavaid evente ja paneb vajaduse korral proge kinni //(System.exit)