/*
* Copyright 2000 Adam Treat Pendulum Applet
*/
import java.applet.*;
import java.awt.*;
import java.awt.Rectangle;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.plaf.basic.*;
import java.util.*;
import java.util.Observable;
import java.util.Observer;
import java.awt.event.*;
import com.sun.j3d.utils.applet.MainFrame;
import com.sun.j3d.utils.geometry.Sphere;
import com.sun.j3d.utils.geometry.Cylinder;
import com.sun.j3d.utils.universe.*;
import javax.media.j3d.*;
import javax.vecmath.*;
public class Pend8 extends Applet implements ActionListener, ChangeListener, Observer
{
private JPanel card;
private JPanel full;
private JPanel four;
private JPanel tabbedPane;
private Started sta;
private Stopped sto;
private Stream stream;
private Clear clear;
private Rotate rt;
private ZoomIn zmI;
private ZoomOut zmO;
private Theta theta;
private Radius radius;
private Engine eng;
private CanvasFor3d cv3d;
private Phase1 ph1;
private Phase2 ph2;
private Phase3 ph3;
private JTextArea jt;
private JTextArea jo;
private JTextArea ja;
private JTextArea jk;
private JTextArea jp;
private JTextArea jte;
private JButton startb;
private JButton stopb;
private JButton str;
private JButton clr;
private JButton rtc;
private JButton zi;
private JButton zo;
private JButton plot;
private JSlider thetaslide;
private JSlider radiusslide;
private boolean plotter = false;
private double thetas;
private double omegas;
private double alphas;
private double r;
private double kenergy = ((omegas * r) * (omegas * r)) / 2;
private double penergy = (9.8 * (1 - Math.cos(thetas)));
private double tenergy = kenergy + penergy;
public void init()
{
//Define the Look & Feel
UIManager.put("Button.font",new Font("SansSerif",Font.PLAIN, 10));
UIManager.put("Label.font",new Font("SansSerif",Font.PLAIN, 10));
UIManager.put("TabbedPane.font",new Font("SansSerif",Font.PLAIN, 10));
UIManager.put("TextArea.font",new Font("SansSerif",Font.PLAIN, 10));
//Create the objects
card = new JPanel();
full = new JPanel();
four = new JPanel();
tabbedPane = new JPanel();
sta = new Started();
sto = new Stopped();
stream = new Stream();
clear = new Clear();
rt = new Rotate();
zmI = new ZoomIn();
zmO = new ZoomOut();
theta = new Theta();
radius = new Radius();
eng = new Engine();
cv3d = new CanvasFor3d();
ph1 = new Phase1();
ph2 = new Phase2();
ph3 = new Phase3();
//Create the Controls
startb = new JButton("Start");
stopb = new JButton("Stop");
str = new JButton("Stream VS Real");
clr = new JButton("Clear Phase");
rtc = new JButton("Rotate Camera");
zi = new JButton("Zoom In");
zo = new JButton("Zoom Out");
plot = new JButton("View Plots");
thetaslide = new JSlider(0, 360, 45);
radiusslide = new JSlider(200, 1001, 1000);
//Create Observerable/Observer heirarchy
sta.addObserver(eng);
sta.addObserver(cv3d);
sto.addObserver(eng);
stream.addObserver(ph1);
stream.addObserver(ph3);
clear.addObserver(ph2);
rt.addObserver(cv3d);
zmI.addObserver(cv3d);
zmO.addObserver(cv3d);
theta.addObserver(eng);
theta.addObserver(cv3d);
radius.addObserver(eng);
radius.addObserver(cv3d);
eng.addObserver(this);
eng.addObserver(cv3d);
//Providing Action Listeners for controls
startb.addActionListener(this);
stopb.addActionListener(this);
str.addActionListener(this);
clr.addActionListener(this);
rtc.addActionListener(this);
zi.addActionListener(this);
zo.addActionListener(this);
plot.addActionListener(this);
thetaslide.addChangeListener(this);
radiusslide.addChangeListener(this);
//Creating a Control Panel and adding the controls
JPanel controls = new JPanel();
JPanel left = new JPanel();
JPanel right = new JPanel();
JPanel bottom = new JPanel();
controls.setLayout(new BorderLayout(5, 5));
left.setLayout(new GridLayout(4, 2));
right.setLayout(new GridLayout(6, 1));
bottom.setLayout(new BoxLayout(bottom, BoxLayout.Y_AXIS));
controls.add("West", left);
controls.add("East", right);
controls.add("South", bottom);
left.add(startb);
left.add(stopb);
left.add(str);
left.add(clr);
left.add(zi);
left.add(zo);
left.add(rtc);
left.add(plot);
JPanel thetatext = new JPanel();
thetatext.setLayout(new FlowLayout(FlowLayout.RIGHT));
thetatext.add(new JLabel("Theta"));
jt = new JTextArea(Double.toString(thetas), 1, 15);
thetatext.add(jt);
right.add(thetatext);
JPanel omegatext = new JPanel();
omegatext.setLayout(new FlowLayout(FlowLayout.RIGHT));
omegatext.add(new JLabel("Omega"));
jo = new JTextArea(Double.toString(omegas), 1, 15);
omegatext.add(jo);
right.add(omegatext);
JPanel alphatext = new JPanel();
alphatext.setLayout(new FlowLayout(FlowLayout.RIGHT));
alphatext.add(new JLabel("Alpha"));
ja = new JTextArea(Double.toString(alphas), 1, 15);
alphatext.add(ja);
right.add(alphatext);
JPanel kenergytext = new JPanel();
kenergytext.setLayout(new FlowLayout(FlowLayout.RIGHT));
kenergytext.add(new JLabel("K Energy"));
jk = new JTextArea(Double.toString(kenergy), 1, 15);
kenergytext.add(jk);
right.add(kenergytext);
JPanel penergytext = new JPanel();
penergytext.setLayout(new FlowLayout(FlowLayout.RIGHT));
penergytext.add(new JLabel("P Energy"));
jp = new JTextArea(Double.toString(penergy), 1, 15);
penergytext.add(jp);
right.add(penergytext);
JPanel tenergytext = new JPanel();
tenergytext.setLayout(new FlowLayout(FlowLayout.RIGHT));
tenergytext.add(new JLabel("T Energy"));
jte = new JTextArea(Double.toString(tenergy), 1, 15);
tenergytext.add(jte);
right.add(tenergytext);
bottom.add(new JLabel("Adjust Theta", JLabel.CENTER));
thetaslide.setMajorTickSpacing(90);
thetaslide.setMinorTickSpacing(15);
thetaslide.setPaintTicks(true);
thetaslide.setPaintLabels(true);
bottom.add(thetaslide);
bottom.add(new JLabel("Adjust Radius", JLabel.CENTER));
radiusslide.setMajorTickSpacing(200);
radiusslide.setMinorTickSpacing(50);
radiusslide.setPaintTicks(true);
radiusslide.setPaintLabels(true);
bottom.add(radiusslide);
//Creating a Tabbed Pane
tabbedPane.setLayout(new GridLayout(1, 1));
JTabbedPane tabpane = new JTabbedPane();
tabpane.addTab("Controls", controls);
tabpane.setSelectedIndex(0);
Component help = makeTextPanel("HEEEEEEEEEEEEEEEEELLLLLLLLlPPPPPPPPPPPPPP");
tabpane.addTab("Help", help);
tabbedPane.add(tabpane);
//Adding everything to the top
full.setLayout(new GridLayout(1, 1));
full.add(cv3d.c);
card.setBackground(Color.black);
card.setLayout(new CardLayout());
card.add(full, "full");
card.add(four, "four");
//Adding everything to the Applet
setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
tabbedPane.setPreferredSize(new Dimension(600, 300));
tabbedPane.setMinimumSize(new Dimension(600, 300));
card.setPreferredSize(new Dimension(600, 400));
add(card);
add(tabbedPane);
System.out.println("Copyright 2000 Adam Treat Pendulum Applet");
}
protected Component makeTextPanel(String text)
{
JPanel panel = new JPanel(false);
JLabel filler = new JLabel(text);
filler.setHorizontalAlignment(JLabel.CENTER);
panel.setLayout(new GridLayout(1, 1));
panel.add(filler);
return panel;
}
public void stateChanged(ChangeEvent e)
{
if (e.getSource() == thetaslide)
{
theta.set((float) thetaslide.getValue());
}
if (e.getSource() == radiusslide)
{
radius.set((float) radiusslide.getValue());
}
return;
}
public void actionPerformed(ActionEvent e)
{
if (e.getSource() == startb)
{
sta.set(true);
}
if (e.getSource() == stopb)
{
sto.set(true);
}
if (e.getSource() == clr)
{
clear.set(true);
}
if (e.getSource() == str)
{
stream.set(true);
}
if (e.getSource() == rtc)
{
rt.set(true);
}
if (e.getSource() == zi)
{
zmI.set(true);
}
if (e.getSource() == zo)
{
zmO.set(true);
}
if (e.getSource() == plot)
{
if (plotter == true)
{
eng.deleteObserver(ph1);
eng.deleteObserver(ph2);
eng.deleteObserver(ph3);
four.remove(cv3d.c);
full.add(cv3d.c);
CardLayout cl = (CardLayout)(card.getLayout());
cl.first(card);
plotter = false;
}
else
{
eng.addObserver(ph1);
eng.addObserver(ph2);
eng.addObserver(ph3);
full.remove(cv3d.c);
four.setBackground(Color.black);
four.setLayout(new GridLayout(2, 2));
four.add(cv3d.c);
four.add(ph1);
four.add(ph2);
four.add(ph3);
CardLayout cl = (CardLayout)(card.getLayout());
cl.last(card);
plotter = true;
}
}
return;
}
public void update(Observable o, Object arg)
{
if (o instanceof Engine)
{
String t = Double.toString(thetas);
String om = Double.toString(omegas);
String a = Double.toString(alphas);
String k = Double.toString(kenergy);
String p = Double.toString(penergy);
String te = Double.toString(tenergy);
double x[] = new double[4];
x = (double[]) arg;
thetas = x[0];
omegas = x[1];
alphas = x[2];
r = x[3];
kenergy = ((omegas * r) * (omegas * r)) / 2;
penergy = (9.8 * (1 - Math.cos(thetas)));
tenergy = kenergy + penergy;
jt.replaceRange(Double.toString(thetas), 0, t.length());
jo.replaceRange(Double.toString(omegas), 0, om.length());
ja.replaceRange(Double.toString(alphas), 0, a.length());
jk.replaceRange(Double.toString(kenergy), 0, k.length());
jp.replaceRange(Double.toString(penergy), 0, p.length());
jte.replaceRange(Double.toString(tenergy), 0, te.length());
}
}
public static void main(String[] args)
{
new MainFrame(new Pend8(), 600, 700);
}
}
//This is the class that defines the Start button and will notify the Engine of any State changes
class Started extends Observable
{
public void set(boolean t)
{
setChanged();
notifyObservers();
clearChanged();
}
}
//This is the class that defines the Stop button and will notify the Engine of any State changes
class Stopped extends Observable
{
public void set(boolean t)
{
setChanged();
notifyObservers();
clearChanged();
}
}
//This is the class blah blah clear
class Clear extends Observable
{
public void set(boolean t)
{
setChanged();
notifyObservers();
clearChanged();
}
}
//This is the class blah blah stream
class Stream extends Observable
{
public void set(boolean t)
{
setChanged();
notifyObservers();
clearChanged();
}
}
//This is the class blah blah rotate
class Rotate extends Observable
{
public void set(boolean t)
{
setChanged();
notifyObservers();
clearChanged();
}
}
//This is the class blah blah zoom
class ZoomIn extends Observable
{
public void set(boolean t)
{
setChanged();
notifyObservers();
clearChanged();
}
}
//This is the class blah blah xoom
class ZoomOut extends Observable
{
public void set(boolean t)
{
setChanged();
notifyObservers();
clearChanged();
}
}
//This is the class that defines the Theta Scroll and will notify the Engine of any State changes
class Theta extends Observable
{
public void set(float i)
{
setChanged();
notifyObservers(Float.toString(i));
clearChanged();
}
}
//This is the class that defines the Radius Scroll and will notify the Engine of any State changes
class Radius extends Observable
{
public void set(float i)
{
setChanged();
notifyObservers(Float.toString(i));
clearChanged();
}
}
//This is the class that does all the Calculations and will notify the Canvas3d of angle Theta changes / updates
class Engine extends Observable implements Observer, Differential, Runnable
{
private Thread t;
private RungaKutta rk;
double x[] = new double[5];
double x2[] = new double[3];
double ts;
double tf;
double ti = 0.001;
double newtheta = Math.PI / 4;
double newradius = 1.0;
long sysstart;
long sysfinal;
boolean stopper = true;
boolean starter = false;
public void init()
{
Pend8 pend = new Pend8();
Engine traj = new Engine();
rk = new RungaKutta((Differential) traj);
ts = 0;
tf = ti;
sysstart = 0;
sysfinal = 1;
x[0] = newtheta; //theta
x[1] = 0.0; //omega
x[2] = 0.0; //alpha
x[3] = newradius; //radius
x[4] = ti; //dt
x2[0] = 0.0; //copy of theta
x2[1] = 0.0; //copy of omega
x2[2] = 0.0; //copy of omega
this.start();
}
public void start()
{
t = new Thread(this);
t.start();
t.setPriority(Thread.MAX_PRIORITY);
}
public void stop()
{
stopper = true;
starter = false;
}
public void run()
{
while (stopper != true)
{
double processtime = (double)(sysfinal - sysstart);
if (sysstart != sysfinal)
{
sysstart = System.currentTimeMillis();
}
x2[0] = x[0];
x2[1] = x[1];
x2[2] = x[2];
rk.solve(x, ts, tf, x[4]);
if (processtime > 0.0)
{
x[4] = (processtime / 1000.0);
ts = tf;
tf += x[4];
int fps = (int)(1 / x[4]);
System.out.println("FPS = " + fps);
set(1);
//System.out.println(x[0] + " "+ts+" "+tf+" "+x[4]);
}
else
{
x[0] = x2[0];
x[1] = x2[1];
x[2] = x2[2];
//System.out.println(x[0] + " "+x[1]+" "+x[2]+" "+x[4]);
}
sysfinal = System.currentTimeMillis();
}
}
public void deriv(double t, double x[], double dx[])
{
x[2] = (-9.8 / x[3]) * (Math.sin(x[0]));
dx[0] = x[1];
dx[1] = x[2];
dx[2] = 0;
}
public void set(int i)
{
setChanged();
notifyObservers(x);
clearChanged();
}
public void update(Observable o, Object arg)
{
if (o instanceof Started)
{
if (starter != true)
{
stopper = false;
starter = true;
this.init();
}
}
if (o instanceof Stopped)
{
this.stop();
}
if (o instanceof Radius)
{
newradius = Double.parseDouble((String)(arg)) / 1000;
x[3] = newradius;
}
if (o instanceof Theta)
{
newtheta = Double.parseDouble((String)(arg)) * (Math.PI * 2 / 360);
x[0] = newtheta;
}
}
}
//This is the class that specifies the 3d object
class CanvasFor3d extends Applet implements Observer
{
GraphicsConfiguration config = SimpleUniverse.getPreferredConfiguration();
Canvas3D c = new Canvas3D(config);
//This will eventually be to flush the buffer before i write to it...
GraphicsContext3D gc = c.getGraphicsContext3D();
TransformGroup camera;
TransformGroup rotation;
TransformGroup pendulum;
TransformGroup cylscale;
TransformGroup sphere;
Transform3D cam = new Transform3D();
Transform3D zAxis = new Transform3D();
Transform3D scale = new Transform3D();
Transform3D radscale = new Transform3D();
Transform3D tran = new Transform3D();
float newtheta = (float)(Math.PI / 4);
float newradius = 1;
float rot = (float)(Math.PI / 8);
float sca = 1;
public BranchGroup createSceneGraph()
{
// Specifies the colors I will be using
Color3f black = new Color3f(0.0f, 0.0f, 0.0f);
Color3f white = new Color3f(1.0f, 1.0f, 1.0f);
Color3f objColor = new Color3f(0.85f, 0.85f, 0.85f);
Color3f green = new Color3f(0.0f, 1.0f, 0.0f);
Color3f lessgreen = new Color3f(0.0f, 0.3f, 0.0f);
Color3f ambient = new Color3f(0.2f, 0.2f, 0.2f);
// Create the root of the branch graph
BranchGroup compile = new BranchGroup();
// Create the transform group node and initialize it to the
// identity. Enable the TRANSFORM_WRITE capability so that
// our behavior code can modify it at runtime. Add it to the
// root of the subgraph.
rotation = new TransformGroup();
rotation.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
//translate the camera
cam.setTranslation(new Vector3d(0.0d , 0.6d, 0.0d));
camera = new TransformGroup(cam);
camera.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
compile.addChild(camera);
// Bounds
BoundingSphere bounds = new BoundingSphere(new Point3d(0.0, 0.0, 0.0), 100.0);
// Creating the material and textures/colors of the objects..
Material m = new Material(objColor, black, objColor, white, 100.0f);
m.setLightingEnable(true);
Appearance a = new Appearance();
a.setMaterial(m);
// Create the Lights and add them too the Scene
Point3f lPoint = new Point3f(1.5f, 1.5f, 1.5f);
Point3f lPoint2 = new Point3f(-1.0f, 1.0f, 1.5f);
Point3f atten = new Point3f(1.0f, 0.0f, 0.0f);
AmbientLight amb = new AmbientLight(ambient);
PointLight point = new PointLight(green, lPoint, atten);
PointLight point2 = new PointLight(lessgreen, lPoint2, atten);
amb.setInfluencingBounds(bounds);
point.setInfluencingBounds(bounds);
point2.setInfluencingBounds(bounds);
compile.addChild(amb);
compile.addChild(point);
compile.addChild(point2);
// Create a Sphere object, generate one copy of the sphere,
// and add it into the scene graph.
Cylinder cyl = new Cylinder(0.025f, 1.0f, Cylinder.GENERATE_NORMALS, a);
Sphere sph = new Sphere(0.15f, Sphere.GENERATE_NORMALS, 50, a);
//Translate the Sphere so it appears in the correct coordinates relative to
sphere = new TransformGroup();
tran.setTranslation(new Vector3d(0.0d, -0.58d, 0.0d));
sphere.setTransform(tran);
sphere.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
sphere.addChild(sph);
// Create a Transform to scale all objects so they appear in the scene.
scale.setScale(1.0);
scale.setTranslation(new Vector3d(0.0d, -0.5d, 0.0d));
// Create a Transform to scale the Pendulum appear to shorten it's length.
cylscale = new TransformGroup();
cylscale.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
cylscale.addChild(cyl);
// Combine the cylinder and pendulum into a new object
pendulum = new TransformGroup();
pendulum.setTransform(scale);
pendulum.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
pendulum.addChild(sphere);
pendulum.addChild(cylscale);
rotation.addChild(pendulum);
camera.addChild(rotation);
compile.compile();
return compile;
}
public CanvasFor3d()
{
// Create a simple scene and attach it to the virtual universe
BranchGroup scene = createSceneGraph();
//scene.setCapability( BranchGroup.ALLOW_BOUNDS_READ );
SimpleUniverse u = new SimpleUniverse(c);
//u.setJ3DThreadPriority(Thread.MAX_PRIORITY);
// This will move the ViewPlatform back a bit so the
// objects in the scene can be viewed.
u.getViewingPlatform().setNominalViewingTransform();
u.addBranchGraph(scene);
}
public void update(Observable o, Object arg)
{
if (o instanceof Engine)
{
double x[] = new double[4];
x = (double[]) arg;
newtheta = (float) x[0];
zAxis.rotZ(newtheta);
rotation.setTransform(zAxis);
}
if (o instanceof Radius)
{
newradius = Float.parseFloat((String)(arg)) / 1000;
scale.setTranslation(new Vector3d(0.0d, -0.5d + ((1 - newradius) / 2), 0.0d));
pendulum.setTransform(scale);
radscale.setScale(new Vector3d(1.0d, newradius, 1.0d));
cylscale.setTransform(radscale);
tran.setTranslation(new Vector3d(0.0d, -newradius / 2 - 0.08, 0.0d));
sphere.setTransform(tran);
}
if (o instanceof Theta)
{
newtheta = (float)(Double.parseDouble((String)(arg)) * (Math.PI * 2 / 360));
zAxis.rotZ(newtheta);
rotation.setTransform(zAxis);
}
if (o instanceof Rotate)
{
cam.rotY(rot);
cam.setScale(sca);
cam.setTranslation(new Vector3d(0.0d , 0.6 - (1 - sca), 0.0d));
camera.setTransform(cam);
rot += Math.PI / 8;
}
if (o instanceof ZoomIn)
{
sca += 0.1;
cam.setScale(sca);
cam.setTranslation(new Vector3d(0.0d , 0.6d - (1 - sca), 0.0d));
camera.setTransform(cam);
}
if (o instanceof ZoomOut)
{
sca -= 0.1;
cam.setScale(sca);
cam.setTranslation(new Vector3d(0.0d , 0.6 - (1 - sca), 0.0d));
camera.setTransform(cam);
}
}
}
//This is a Phase diagram
class Phase1 extends Canvas implements Observer
{
private boolean stream = true;
private float theta;
private float omega;
private float alpha;
private float dt;
private double time;
private int xoffset = 30;
private int yoffset = 30;
private int height;
private int length;
private int convertTheta = yoffset;
private int convertOmega = yoffset;
private int convertAlpha = yoffset;
private int dtx = xoffset;
private Rectangle ptsTheta;
private Rectangle ptsOmega;
private Rectangle ptsAlpha;
private Rectangle ptTheta;
private Rectangle ptOmega;
private Rectangle ptAlpha;
private Vector ptbinTheta = new Vector(1, 1);
private Vector ptbinOmega = new Vector(1, 1);
private Vector ptbinAlpha = new Vector(1, 1);
public void paint(Graphics g)
{
Graphics2D g2 = (Graphics2D) g;
height = (int)(this.getHeight() - 2 * yoffset);
length = (int)(this.getWidth() - 2 * xoffset);
g2.setColor(Color.white);
g2.drawLine(xoffset, yoffset, xoffset, yoffset + height);
g2.drawLine(xoffset, yoffset + height, xoffset + length, yoffset + height);
g2.setColor(Color.green);
g2.drawString("Theta", (xoffset + length) / 2 - 65, yoffset - 5);
g2.setColor(Color.blue);
g2.drawString("Omega", (xoffset + length) / 2, yoffset - 5);
g2.setColor(Color.red);
g2.drawString("Alpha", (xoffset + length) / 2 + 75, yoffset - 5);
convertTheta = (int)(yoffset - ((height / 4) / Math.PI) * theta + height / 2);
convertOmega = (int)(yoffset - ((height / 4) / Math.PI) * omega + height / 2);
convertAlpha = (int)(yoffset - ((height / 8) / Math.PI) * alpha + height / 2);
dtx = (int)((length / 4) * dt);
ptTheta = new Rectangle(xoffset, convertTheta, 1, 1);
ptOmega = new Rectangle(xoffset, convertOmega, 1, 1);
ptAlpha = new Rectangle(xoffset, convertAlpha, 1, 1);
ptbinTheta.addElement(ptTheta);
ptbinOmega.addElement(ptOmega);
ptbinAlpha.addElement(ptAlpha);
int xAlpha[] = new int[ptbinAlpha.size()];
int yAlpha[] = new int[ptbinAlpha.size()];
int xOmega[] = new int[ptbinOmega.size()];
int yOmega[] = new int[ptbinOmega.size()];
int xTheta[] = new int[ptbinTheta.size()];
int yTheta[] = new int[ptbinTheta.size()];
for (int i = 0; i < ptbinAlpha.size(); i++)
{
ptsAlpha = (Rectangle)(ptbinAlpha.elementAt(i));
double l = ptsAlpha.getLocation().getX();
double h = ptsAlpha.getLocation().getY();
xAlpha[i] = (int) l;
yAlpha[i] = (int) h;
g2.setColor(Color.red);
if (l >= length + xoffset || h >= height + yoffset || h < yoffset)
{
ptbinAlpha.removeElementAt(i);
i = -1;
}
else if (stream == false || l >= length + xoffset || h >= height + yoffset ||
h < yoffset)
{
g2.draw(ptsAlpha);
}
else if (stream == true || l >= length + xoffset || h >= height + yoffset ||
h < yoffset)
{
g2.drawPolyline(xAlpha, yAlpha, i + 1);
}
ptsAlpha.translate(dtx, 0);
}
for (int i = 0; i < ptbinOmega.size(); i++)
{
ptsOmega = (Rectangle)(ptbinOmega.elementAt(i));
double l = ptsOmega.getLocation().getX();
double h = ptsOmega.getLocation().getY();
xOmega[i] = (int) l;
yOmega[i] = (int) h;
g2.setColor(Color.blue);
if (l >= length + xoffset || h >= height + yoffset || h < yoffset)
{
ptbinOmega.removeElementAt(i);
i = -1;
}
else if (stream == false || l >= length + xoffset || h >= height + yoffset ||
h < yoffset)
{
g2.draw(ptsOmega);
}
else if (stream == true || l >= length + xoffset || h >= height + yoffset ||
h < yoffset)
{
g2.drawPolyline(xOmega, yOmega, i + 1);
}
ptsOmega.translate(dtx, 0);
}
for (int i = 0; i < ptbinTheta.size(); i++)
{
ptsTheta = (Rectangle)(ptbinTheta.elementAt(i));
double l = ptsTheta.getLocation().getX();
double h = ptsTheta.getLocation().getY();
xTheta[i] = (int) l;
yTheta[i] = (int) h;
g2.setColor(Color.green);
if (l >= length + xoffset || h >= height + yoffset || h < yoffset)
{
ptbinTheta.removeElementAt(i);
i = -1;
}
else if (stream == false || l >= length + xoffset || h >= height + yoffset ||
h < yoffset)
{
g2.draw(ptsTheta);
}
else if (stream == true || l >= length + xoffset || h >= height + yoffset ||
h < yoffset)
{
g2.drawPolyline(xTheta, yTheta, i + 1);
}
ptsTheta.translate(dtx, 0);
}
}
public void update(Graphics g)
{
g.clearRect(xoffset + 1, yoffset - 1, length + 1, height + 1);
paint(g);
}
public void update(Observable o, Object arg)
{
if (o instanceof Engine)
{
double x[] = new double[4];
x = (double[]) arg;
theta = (float) x[0];
omega = (float) x[1];
alpha = (float) x[2];
dt = (float) x[4];
Graphics g = this.getGraphics();
update(g);
g.dispose();
}
if (o instanceof Stream)
{
if (stream != true)
{
stream = true;
}
else
{
stream = false;
}
}
}
}
//This is a Phase diagram
class Phase2 extends Canvas implements Observer
{
private boolean clear = false;
private float theta;
private float omega;
private float dt;
private float time;
private int xoffset = 30;
private int yoffset = 30;
private int height;
private int length;
private int convertTheta = xoffset;
private int convertOmega = yoffset;
private int dtx = xoffset;
private Rectangle pts;
private Rectangle pt;
private Vector ptbin = new Vector(1, 1);
public void paint(Graphics g)
{
Graphics2D g2 = (Graphics2D) g;
height = (int)(this.getHeight() - 2 * yoffset);
length = (int)(this.getWidth() - 2 * xoffset);
g2.setColor(Color.white);
g2.drawLine(xoffset, yoffset, xoffset, yoffset + height);
g2.drawLine(xoffset, yoffset + height, xoffset + length, yoffset + height);
g2.setColor(Color.green);
g2.drawString("Theta VS Omega", (xoffset + length) / 2 - 30, yoffset - 5);
convertTheta = (int)(xoffset - ((length / 4) / Math.PI) * theta + length / 2);
convertOmega = (int)(yoffset - ((height / 4) / Math.PI) * omega + height / 2);
pt = new Rectangle(convertTheta, convertOmega, 1, 1);
ptbin.addElement(pt);
for (int i = 0; i < ptbin.size(); i++)
{
pts = (Rectangle)(ptbin.elementAt(i));
double l = pts.getLocation().getX();
double h = pts.getLocation().getY();
if (l >= length + xoffset || h >= yoffset + height || l < xoffset || h < yoffset)
{
ptbin.removeElementAt(i);
i = -1;
}
else if (clear == true)
{
ptbin.removeAllElements();
clear = false;
}
else
{
g2.draw(pts);
}
}
}
public void update(Graphics g)
{
g.clearRect(xoffset + 1, yoffset - 1, length + 1, height + 1);
paint(g);
}
public void update(Observable o, Object arg)
{
if (o instanceof Engine)
{
double x[] = new double[4];
x = (double[]) arg;
theta = (float) x[0];
omega = (float) x[1];
dt = (float) x[4];
Graphics g = this.getGraphics();
update(g);
g.dispose();
}
if (o instanceof Clear)
{
clear = true;
}
}
}
//This is a Phase diagram
class Phase3 extends Canvas implements Observer
{
private boolean stream = true;
private float kenergy;
private float penergy;
private float tenergy;
private float theta;
private float omega;
private float r;
private float dt;
private int xoffset = 30;
private int yoffset = 30;
private int height;
private int length;
private int convertKenergy = xoffset;
private int convertPenergy = xoffset;
private int convertTenergy = xoffset;
private int dtx = xoffset;
private int sizeK;
private int sizeP;
private int sizeT;
private Rectangle ptsKenergy;
private Rectangle ptsPenergy;
private Rectangle ptsTenergy;
private Rectangle ptKenergy;
private Rectangle ptPenergy;
private Rectangle ptTenergy;
private Vector ptbinKenergy = new Vector(1, 1);
private Vector ptbinPenergy = new Vector(1, 1);
private Vector ptbinTenergy = new Vector(1, 1);
public void paint(Graphics g)
{
Graphics2D g2 = (Graphics2D) g;
height = (int)(this.getHeight() - 2 * yoffset);
length = (int)(this.getWidth() - 2 * xoffset);
g2.setColor(Color.white);
g2.drawLine(xoffset, yoffset, xoffset, yoffset + height);
g2.drawLine(xoffset, yoffset + height, xoffset + length, yoffset + height);
g2.setColor(Color.green);
g2.drawString("K Energy", (xoffset + length) / 2 - 65, yoffset - 5);
g2.setColor(Color.blue);
g2.drawString("P Energy", (xoffset + length) / 2, yoffset - 5);
g2.setColor(Color.red);
g2.drawString("T Energy", (xoffset + length) / 2 + 65, yoffset - 5);
kenergy = (float)(((omega * r) * (omega * r)) / 2);
penergy = (float)(9.8 * (1 - Math.cos(theta)));
tenergy = kenergy + penergy;
convertKenergy = (int)(yoffset - (height / 20) * kenergy + height);
convertPenergy = (int)(yoffset - (height / 20) * penergy + height);
convertTenergy = (int)(yoffset - (height / 20) * tenergy + height);
dtx = (int)((length / 4) * dt);
ptKenergy = new Rectangle(xoffset, convertKenergy, 1, 1);
ptPenergy = new Rectangle(xoffset, convertPenergy, 1, 1);
ptTenergy = new Rectangle(xoffset, convertTenergy, 1, 1);
ptbinKenergy.addElement(ptKenergy);
ptbinPenergy.addElement(ptPenergy);
ptbinTenergy.addElement(ptTenergy);
int xKenergy[] = new int[ptbinKenergy.size()];
int yKenergy[] = new int[ptbinKenergy.size()];
int xPenergy[] = new int[ptbinPenergy.size()];
int yPenergy[] = new int[ptbinPenergy.size()];
int xTenergy[] = new int[ptbinTenergy.size()];
int yTenergy[] = new int[ptbinTenergy.size()];
for (int i = 0; i < ptbinKenergy.size(); i++)
{
ptsKenergy = (Rectangle)(ptbinKenergy.elementAt(i));
double l = ptsKenergy.getLocation().getX();
double h = ptsKenergy.getLocation().getY();
xKenergy[i] = (int) l;
yKenergy[i] = (int) h;
g2.setColor(Color.green);
if (l >= length + xoffset || h >= height + yoffset || h < yoffset)
{
ptbinKenergy.removeElementAt(i);
i = -1;
}
else if (stream == false || l >= length + xoffset || h >= height + yoffset ||
h < yoffset)
{
g2.draw(ptsKenergy);
}
else if (stream == true || l >= length + xoffset || h >= height + yoffset ||
h < yoffset)
{
g2.drawPolyline(xKenergy, yKenergy, i + 1);
}
ptsKenergy.translate(dtx, 0);
}
for (int i = 0; i < ptbinPenergy.size(); i++)
{
ptsPenergy = (Rectangle)(ptbinPenergy.elementAt(i));
double l = ptsPenergy.getLocation().getX();
double h = ptsPenergy.getLocation().getY();
xPenergy[i] = (int) l;
yPenergy[i] = (int) h;
g2.setColor(Color.blue);
if (l >= length + xoffset || h >= height + yoffset || h < yoffset)
{
ptbinPenergy.removeElementAt(i);
i = -1;
}
else if (stream == false || l >= length + xoffset || h >= height + yoffset ||
h < yoffset)
{
g2.draw(ptsPenergy);
}
else if (stream == true || l >= length + xoffset || h >= height + yoffset ||
h < yoffset)
{
g2.drawPolyline(xPenergy, yPenergy, i + 1);
}
ptsPenergy.translate(dtx, 0);
}
for (int i = 0; i < ptbinTenergy.size(); i++)
{
ptsTenergy = (Rectangle)(ptbinTenergy.elementAt(i));
double l = ptsTenergy.getLocation().getX();
double h = ptsTenergy.getLocation().getY();
xTenergy[i] = (int) l;
yTenergy[i] = (int) h;
g2.setColor(Color.red);
if (l >= length + xoffset || h >= height + yoffset || h < yoffset)
{
ptbinTenergy.removeElementAt(i);
i = -1;
}
else if (stream == false || l >= length + xoffset || h >= height + yoffset ||
h < yoffset)
{
g2.draw(ptsTenergy);
}
else if (stream == true || l >= length + xoffset || h >= height + yoffset ||
h < yoffset)
{
g2.drawPolyline(xTenergy, yTenergy, i + 1);
}
ptsTenergy.translate(dtx, 0);
}
}
public void update(Graphics g)
{
g.clearRect(xoffset + 1, yoffset - 1, length + 1, height + 1);
paint(g);
}
public void update(Observable o, Object arg)
{
if (o instanceof Engine)
{
double x[] = new double[4];
x = (double[]) arg;
theta = (float) x[0];
omega = (float) x[1];
r = (float) x[3];
dt = (float) x[4];
Graphics g = this.getGraphics();
update(g);
g.dispose();
}
if (o instanceof Stream)
{
if (stream != true)
{
stream = true;
}
else
{
stream = false;
}
}
}
}
|