/Users/lyon/j4p/src/bookExamples/ch26Graphics/carl/phasor/PhasorJComponent.java

1    package bookExamples.ch26Graphics.carl.phasor; 
2     
3    /*  Illustrates the sum of two phasors in real-time. 
4     
5       omega1 and amp1 are associated with the green vector and 
6       omega2 and amp2 with the red vector. 
7     The tips of the vectors are black dots for omega1 and bluish for omega2. 
8     Interpret in terms of the text in pages 15 and 16 of Steiglitz. 
9     
10    If you un-comment one of the other two lines in the "paint" method, you will see 1) 
11    the individual steps of the vector addition or 2)the sine-wave 
12    beat, making sure that only one line is uncommented and the other 
13    two are commented out. 
14    
15   */ 
16    
17   import javax.swing.JComponent; 
18   import javax.swing.JFrame; 
19   import javax.swing.Timer; 
20   import javax.swing.JPanel; 
21   import java.awt.Color; 
22   import java.awt.Container; 
23   import java.awt.Dimension; 
24   import java.awt.FlowLayout; 
25   import java.awt.Graphics; 
26   import java.awt.event.ActionEvent; 
27   import java.awt.event.ActionListener; 
28    
29   class PhasorJComponent extends JPanel { 
30   // Geometry of starting points of vectors 
31       int x1 = 150; 
32       int y1 = 150; 
33       int x2 = 150; 
34       int y2 = 150; 
35       int xcen = 250; 
36       int ycen = 250; 
37       int xOffset = 0; 
38    
39    
40   // Initial parameters of 2 phasors 
41       static double omega1 = 1; 
42   //  static double omega2 = 1.1; 
43       static double omega2 = 2.0; 
44       double amp1 = 60; 
45       double amp2 = 10; 
46       double phi1 = 0;    // phase lag 
47       double phi2 = 0;    // phase lag 
48       double theta = 0; 
49       static Timer ticker; 
50       static TickListener tocker; 
51       double t = 0; 
52       static double delt = .05;  // time increment per display sample 
53       static int milliseconds = 50; //Display timer 
54       boolean firstStep; 
55    
56       PhasorJComponent(double om1, double om2, double am1, double am2, double ph1, double ph2) { 
57           // set up phasor parameters 
58           omega1 = om1; 
59           omega2 = om2; 
60           amp1 = am1; 
61           amp2 = am2; 
62           phi1 = ph1; 
63           phi2 = ph2; 
64           firstStep = true; 
65           Container c = this; 
66           tocker = new TickListener(); 
67       } 
68    
69       public Dimension getPreferredSize() { 
70           return new Dimension(400, 400); 
71       } 
72    
73       public Dimension getMinimumSize() { 
74           return new Dimension(400, 400); 
75       } 
76    
77       private class TickListener implements ActionListener { 
78           public void actionPerformed(ActionEvent e) { 
79               //System.out.print(" Tick "); 
80               upDateGeometry(); 
81               repaint(); 
82           } 
83       } 
84    
85       public void paint(Graphics g) { 
86           //super.paint(g); 
87           drawPhasor(g); 
88           drawSine(g); 
89       } 
90    
91       public void drawPhasor(Graphics g1) { 
92           if (firstStep) { 
93               firstStep = false; 
94               return; 
95           } 
96           //g1.setPaintMode(); 
97           g1.setColor(Color.green); 
98           int xtip = xcen + x1; 
99           int ytip = ycen + y1; 
100          g1.drawLine(xcen, ycen, xtip, ytip); 
101          g1.setColor(Color.red); 
102          // g1.setXORMode(Color.MAGENTA); 
103          g1.drawLine(xtip, ytip, xtip + x2, ytip + y2); 
104          g1.setColor(Color.cyan); 
105          g1.fillOval(xtip, ytip, 4, 4); 
106          g1.setColor(Color.black); 
107          g1.fillOval(xtip + x2, ytip + y2, 4, 4); 
108      } 
109   
110      public void drawSine(Graphics gg) { 
111          if (firstStep) return; 
112          gg.setColor(Color.black); 
113          xOffset += 2; 
114          gg.drawOval(xOffset, ycen + (y1 + y2), 4, 4); 
115          if (xOffset > 400) { 
116              super.paint(gg); 
117  //      gg.clearRect(0,0,500,500); 
118              xOffset = 0; 
119          } 
120      } 
121   
122      public void upDateGeometry() { 
123          t += delt; 
124          double theta1 = t * omega1; 
125          double theta2 = t * omega2; 
126          x1 = (int) (amp1 * Math.cos(-theta1 - phi1)); 
127          y1 = (int) (amp1 * Math.sin(-theta1 - phi1)); 
128          x2 = (int) (amp2 * Math.cos(-theta2 - phi2)); 
129          y2 = (int) (amp2 * Math.sin(-theta2 - phi2)); 
130      } 
131   
132      static void setSampleTime(double st) { 
133          // sample time expressed as number of samples per omega wave 
134          delt = 2 * Math.PI / (st * omega1); 
135      } 
136   
137      static void setDisplayTick(int tick) { 
138          milliseconds = tick; 
139          ticker = new Timer(milliseconds, tocker); 
140      } 
141   
142      public static void main(String args[]) { 
143          // omega1, omega2, amp1, amp2, phi1, phi2 
144          PhasorJComponent pc = new PhasorJComponent(-1., -2.1, 60., 40., 0., 0); 
145          PhasorJComponent.setSampleTime(77.77); 
146   
147          // slow down for closer look (argument is in milliseconds) 
148          PhasorJComponent.setDisplayTick(50); 
149          pc.setDoubleBuffered(true); 
150          ticker.start(); 
151          JFrame jf = new JFrame("This is Phasor Demo3"); 
152          jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
153          Container c = jf.getContentPane(); 
154          c.setLayout(new FlowLayout()); 
155          c.add(pc); 
156          jf.setSize(400, 400); 
157          jf.show(); 
158   
159   
160          // Orderly window closing: 
161   
162  /*        pjf.addWindowListener(new WindowAdapter() { 
163              public void windowClosing(WindowEvent e) { 
164                  System.exit(0); 
165              } 
166          })*/; 
167      } 
168  }