Java GUI Anwendung: Lissajou Figuren

Diese Seite verwendet Cookies. Durch die Nutzung unserer Seite erklären Sie sich damit einverstanden, dass wir Cookies setzen. Weitere Informationen

  • Java GUI Anwendung: Lissajou Figuren

    Durch räumliche Überlagerung harmonischer Schwingungen entstehen
    die, nach dem französichen Physiker Jules Antoine Lissasjous (1822–1880) benannten,
    Lissajou-Figuren. Diese Figuren zeigen sich z. B. wenn bei einem Oszilloskop
    sowohl am Eingang für die x-, als auch für die y-Ablenkung eine harmonische
    Wechselspannung angelegt wird.

    //Voraussetzung: Java3D

    Quellcode

    1. package Lissajou;
    2. import java.awt.*;
    3. import java.awt.event.*;
    4. import javax.vecmath.*;
    5. public class LissajouApplication {
    6. public static int xPeriod = 1, yPeriod = 1;
    7. public static boolean cancel=false;
    8. public static boolean trajectory;
    9. public static void main(String[] args) {
    10. new LissajouGUI(800, 600);
    11. }
    12. @SuppressWarnings("serial")
    13. static class LissajouGUI extends Frame {
    14. private LissaJouCanvas canvas = new LissaJouCanvas();
    15. /**
    16. * Konstruktor der GUI
    17. */
    18. public LissajouGUI(int width, int height) {
    19. super("Lissajou Figures");
    20. //Optionen fuer die Zeichenflaeche
    21. canvas.setBackground(Color.LIGHT_GRAY);
    22. canvas.setSize(width, height);
    23. //Fenster schliessen
    24. addWindowListener(new WindowAdapter() {
    25. public void windowClosing(WindowEvent e) {
    26. System.exit(0);
    27. }
    28. });
    29. //Layout Initialisierung
    30. GridBagLayout gridB = new GridBagLayout();
    31. GridBagConstraints layout = new GridBagConstraints();
    32. setLayout(gridB);
    33. layout.gridwidth = 1;
    34. layout.gridheight = 8;
    35. layout.gridx = 1;
    36. layout.gridy = 1;
    37. //Layout defaults
    38. layout.fill = GridBagConstraints.BOTH; //horizontal und vertikal auf MAX
    39. gridB.setConstraints(canvas, layout);
    40. add(canvas);
    41. //Hier beginnt die rechte Spalte
    42. layout.gridheight = 1;
    43. layout.gridx = 2;
    44. layout.gridy = 1;
    45. // Label x- period
    46. Label labelx = new Label("x-period");
    47. gridB.setConstraints(labelx, layout);
    48. add(labelx);
    49. layout.gridy++;
    50. // Choice x-period
    51. Choice xxx = new Choice();
    52. for (int x = 1; x <= 16; x += 1)
    53. xxx.add(x + "");
    54. xxx.addItemListener(new ItemAdapter() {
    55. public void itemStateChanged(ItemEvent event) {
    56. xPeriod = ((Choice) event.getSource()).getSelectedIndex() + 1;
    57. System.out.println("x-periode: "+xPeriod);
    58. }
    59. });
    60. gridB.setConstraints(xxx, layout);
    61. add(xxx);
    62. layout.gridy++;
    63. // Label y-Period
    64. Label labely = new Label("y-period");
    65. gridB.setConstraints(labely, layout);
    66. add(labely);
    67. layout.gridy++;
    68. // Choice y-period
    69. Choice yyy = new Choice();
    70. for (int y = 1; y <= 16; y += 1)
    71. yyy.add(y + "");
    72. gridB.setConstraints(yyy, layout);
    73. yyy.addItemListener(new ItemAdapter() {
    74. public void itemStateChanged(ItemEvent event) {
    75. yPeriod = ((Choice) event.getSource()).getSelectedIndex() + 1;
    76. System.out.println("y-periode: "+yPeriod);
    77. }
    78. });
    79. add(yyy);
    80. layout.gridy++;
    81. // checkBox trajectory
    82. Checkbox checkTrajectory = new Checkbox("show trajectory");
    83. gridB.setConstraints(checkTrajectory, layout);
    84. checkTrajectory.addItemListener(new ItemAdapter() {
    85. public void itemStateChanged(ItemEvent event) {
    86. Checkbox tmp = (Checkbox) event.getSource();
    87. System.out.println("Trajectory: "+tmp.getState());
    88. if (tmp.getState())
    89. trajectory = true;
    90. else
    91. trajectory = false;
    92. }
    93. });
    94. add(checkTrajectory);
    95. layout.gridy++;
    96. // Clear Button
    97. Button clearBut = new Button("clear");
    98. gridB.setConstraints(clearBut, layout);
    99. clearBut.addActionListener(new ActionAdapter() {
    100. public void actionPerformed(ActionEvent e) {
    101. canvas.repaint();
    102. }
    103. });
    104. add(clearBut);
    105. layout.gridy++;
    106. // Stop Button
    107. Button stopBut = new Button("Stop");
    108. gridB.setConstraints(stopBut, layout);
    109. stopBut.addActionListener(new ActionAdapter() {
    110. public void actionPerformed(ActionEvent e) {
    111. LissajouApplication.cancel = true;
    112. }
    113. });
    114. add(stopBut);
    115. layout.gridy++;
    116. // Start Button
    117. Button startBut = new Button("Start");
    118. gridB.setConstraints(startBut, layout);
    119. startBut.addActionListener(new ActionAdapter() {
    120. public void actionPerformed(ActionEvent e) {
    121. canvas.startAnimation();
    122. }
    123. });
    124. add(startBut);
    125. setSize(width,height);
    126. setLocation(150,100);
    127. setVisible(true);
    128. pack();
    129. }
    130. abstract class ItemAdapter extends Object implements ItemListener {
    131. public abstract void itemStateChanged(ItemEvent event);
    132. }
    133. abstract class ActionAdapter extends Object implements ActionListener {
    134. public abstract void actionPerformed(ActionEvent e);
    135. }
    136. }
    137. @SuppressWarnings("serial")
    138. static class LissaJouCanvas extends Canvas implements Runnable {
    139. /**
    140. * startet den Thread fuer die Animation
    141. */
    142. public void startAnimation() {
    143. try {
    144. LissajouApplication.cancel = false;
    145. new Thread(this).start();
    146. } catch (Exception e){}
    147. }
    148. // public void repaint() {
    149. // wird zum clearen benutzt.. daher ist das original OK
    150. // }
    151. /**
    152. * zeichnet die Lissajou Kurve wieder und wieder
    153. */
    154. public void run() {
    155. while(true) //Wenn fertig gezeichnet, dann zeichne nochmal
    156. new Lissajou(getGraphics(), this.getWidth()/2, this.getHeight()/2, xPeriod, yPeriod, trajectory);
    157. }
    158. }
    159. static class Lissajou {
    160. /**
    161. * Konstruktor - Zeichnet die Lissajou Figur
    162. * @param g Graphics Objekt
    163. * @param startX
    164. * @param startY
    165. * @param xPeriod X Position
    166. * @param yPeriod Y Position
    167. * @param trajectory Kometenschweif
    168. */
    169. public Lissajou(Graphics g, int startX, int startY, int xPeriod, int yPeriod, boolean trajectory) {
    170. final double deltaT = 0.01;
    171. double t;
    172. Point2d p;
    173. Vector2d v;
    174. int kgv =Kgv(xPeriod,yPeriod);
    175. int stop = (int)(kgv/deltaT); //Abbruchbedingug
    176. int[] x = new int[stop+1], y = new int[stop+1]; //Polyline Array
    177. for(int s=1, counter=0; s<=stop && !LissajouApplication.cancel; s++) {
    178. t = s * deltaT;
    179. p = makePoint2d(t, startX, startY, xPeriod, yPeriod);
    180. v = makeVector2d(t, xPeriod, yPeriod);
    181. //Kometenschweif anzeigen?
    182. if(LissajouApplication.trajectory) {
    183. x[counter] = (int)p.x;
    184. y[counter] = (int)p.y;
    185. g.drawPolyline(x, y, counter);
    186. counter++;
    187. }
    188. //ueberzeichne mit Hintergrundfarbe
    189. g.fillPolygon(arrow(p,v,5,2));
    190. g.setColor(Color.LIGHT_GRAY);
    191. //Das ist eine menschlich sichtbare Animation, also schlafe ein wenig
    192. try {
    193. Thread.sleep(40);
    194. } catch (Exception e) {}
    195. //ueberzeichne schwarz
    196. g.fillPolygon(arrow(p,v,5,2));
    197. g.setColor(Color.BLACK);
    198. }
    199. }
    200. /**
    201. * zeichnet einen gerichteten Pfeil
    202. * @param pos Position
    203. * @param dir Richtung
    204. * @param s hoehe
    205. * @param r breite
    206. * @return Polygon
    207. */
    208. private Polygon arrow(Point2d pos, Vector2d dir, double s, double r) {
    209. dir.normalize();
    210. dir.scale(s);
    211. Vector2d vec = new Vector2d(-dir.y, dir.x);
    212. dir.scale(2 * r);
    213. Polygon polygon = new Polygon();
    214. polygon.addPoint((int) (pos.x + vec.x), (int) (pos.y + vec.y));
    215. polygon.addPoint((int) (pos.x + dir.x), (int) (pos.y + dir.y));
    216. polygon.addPoint((int) (pos.x - vec.x), (int) (pos.y - vec.y));
    217. return polygon;
    218. }
    219. private Point2d makePoint2d(double t,int startX, int startY, int xPeriod,int yPeriod){
    220. Point2d ret = new Point2d();
    221. ret.x = startX + startX *Math.cos((2*Math.PI/xPeriod)*t);
    222. ret.y = startY + startY *Math.sin((2*Math.PI/yPeriod)*t);
    223. return ret;
    224. }
    225. private Vector2d makeVector2d(double t, int xPeriod,int yPeriod){
    226. Vector2d ret = new Vector2d();
    227. ret.x = -1*(2*Math.PI/xPeriod)*Math.sin((2*Math.PI/xPeriod)*t);
    228. ret.y = (2*Math.PI/yPeriod)*Math.cos((2*Math.PI/yPeriod)*t);
    229. return ret;
    230. }
    231. private int Kgv(int xPeriod, int yPeriod) {
    232. int tmp = xPeriod * yPeriod;
    233. return tmp/ggt(xPeriod, yPeriod);
    234. }
    235. /**
    236. * kleinstes gemeinsames Vielfaches
    237. * groesster gemeinsamer Teiler
    238. * @param a Zahl 1
    239. * @param b Zahl 2
    240. * @return ggT
    241. */
    242. private int ggt(int a, int b) {
    243. if(a % b == 0)
    244. return b;
    245. else
    246. return ggt(b, a % b);
    247. }
    248. }
    249. }
    Alles anzeigen
    Bilder
    • lissajou-figuren-java.png

      46,31 kB, 646×466, 1.791 mal angesehen
    Dateien
    • lissajou.jar

      (65,09 kB, 503 mal heruntergeladen, zuletzt: )