/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 }