// Created by N. Exner, C.2001
// Started 4/24/2001
//
import java.awt.*;
import java.applet.Applet;
public class Orthogonal extends Applet {
VectorPanel vp;
CardLayout cl;
Panel cp;
// New
MatrixSteps ms;
public void init(){
setBackground(Color.white);
ms = new MatrixSteps(this);
vp = new VectorPanel();
add(vp);
add(ms);
//add(new Button("Restart"));
cp = getControlPanel();
} //_init()
// Setup panel sequence
public Panel getControlPanel(){
cl = new CardLayout();
Panel p = new Panel();
p.setBackground(Color.white);
p.setLayout(cl);
p.add("First",getSelectVectorPanel());
p.add("Second",new Button("Normalize a1"));
p.add("Third",new Button("Project"));
p.add("Fourth",new Button("Subtract"));
p.add("Fifth",new Button("Normalize a2-x"));
p.add("Sixth",new Button("Reset"));
cl.show(p,"First");
return p;
}
public Panel getSelectVectorPanel(){
Panel p = new Panel();
p.setBackground(Color.white);
p.add(new Label("Click on the graph to select a vector."));
p.add(new Button("Continue"));
return p;
}
public boolean action(Event evt, Object arg){
System.out.println("vp: "+vp.dontSmoke);
if (evt.target instanceof Button) {
if (vp.dontSmoke > 0) {
vp.dontSmoke++;
cl.next(cp);
ms.next();
}
}
// dispatch current
actOn(vp.dontSmoke);
if (arg.equals("Reset")){
System.out.println("Reset");
vp.reset();
}
ms.repaint();
vp.repaint();
return true;
}
public void actOn(int x){
System.out.println("Acton" +x);
switch(x){
case 8:
case 7:
case 1:
case 2:
case 0:
//vp.reset();
vp.reset2();
vp.dontSmoke = 0;
break;
case 3:
System.out.println("Normalize a1");
vp.reset2();
vp.normalizea1();
break;
case 4:
System.out.println("Project for a2-x");
vp.reset2();
vp.normalizea1();
vp.project();
break;
case 5:
System.out.println("Subtract for a2-x");
vp.reset2();
vp.normalizea1();
vp.project();
vp.subtract();
break;
case 6:
System.out.println("Normalize for a2-x");
vp.reset2();
vp.normalizea1();
vp.project();
vp.subtract();
vp.normalizea2x();
break;
}
}
} // _ Orthogonal
class VectorPanel extends Panel{
Dimension size = new Dimension(300,300);
final Color myColor = new Color(255,255,200);
int vectorAX = size.width/2,
vectorAY = size.height/2,
vectorQX = size.width/2,
vectorQY = size.height/2,
vectorA2X = size.width/2,
vectorA2Y = size.height/2,
vectorQ2X = size.width/2,
vectorQ2Y = size.height/2,
vectorQ3X = size.width/2,
vectorQ3Y = size.height/2,
vectorD1X = size.width/2,
vectorD1Y = size.height/2;
boolean project = false,
subtract = false;
static int dontSmoke = 0;
// Export Panel Size
public Dimension getMinimumSize() {return size;}
public Dimension getPreferredSize(){return size;}
public void reset(){
vectorAX = size.width/2;
vectorAY = size.height/2;
vectorA2X = size.width/2;
vectorA2Y = size.height/2;
vectorQX = size.width/2;
vectorQY = size.height/2;
vectorQ2X = size.width/2;
vectorQ2Y = size.height/2;
vectorQ3X = size.width/2;
vectorQ3Y = size.height/2;
vectorD1X = size.width/2;
vectorD1Y = size.height/2;
project = false;
subtract = false;
dontSmoke = 0;
repaint();
}
public void reset2(){
vectorQX = size.width/2;
vectorQY = size.height/2;
vectorQ2X = size.width/2;
vectorQ2Y = size.height/2;
vectorQ3X = size.width/2;
vectorQ3Y = size.height/2;
vectorD1X = size.width/2;
vectorD1Y = size.height/2;
project = false;
subtract = false;
//dontSmoke = 0;
repaint();
}
public VectorPanel(){
setBackground(myColor);
}
public void paint(Graphics g){
drawAxis(g);
// Draw Dashed lines
if (project){
g.setColor(new Color(150,150,150));
if (subtract)
drawDashedLine(scale(vectorA2X),scaleY(vectorA2Y),scale(vectorQ2X),scaleY(vectorQ2Y),g);
drawDashedLine(scale(vectorD1X),scaleY(vectorD1Y),0.0,0.0,g);
drawDashedLine(scale(vectorA2X),scaleY(vectorA2Y),scale(vectorD1X),scaleY(vectorD1Y),g);
}
g.setColor(Color.red);
drawScaleVector("a1",0.0,0.0,scale(vectorAX), scaleY(vectorAY),g);
drawScaleVector("a2",0.0,0.0,scale(vectorA2X), scaleY(vectorA2Y),g);
// Final Green lines q1 & q2
g.setColor(Color.green);
drawScaleVector("q1",0.0,0.0,scale(vectorQX), scaleY(vectorQY),g);
if (subtract)
drawScaleVector("q2",0.0,0.0,scale(vectorQ3X), scaleY(vectorQ3Y),g);
g.setColor(new Color(180,0,180));
drawScaleVector("a2-x",0.0,0.0,scale(vectorQ2X), scaleY(vectorQ2Y),g);
// Draw Frame
g.setColor(Color.black);
g.drawRect(0,0,size.width-1,size.height-1);
}
public boolean mouseDown(Event evt, int x, int y){
System.out.println("X: "+x+" Scale: "+scale(x));
System.out.println("Smoke"+dontSmoke);
if (dontSmoke > 0)
return true;
if (vectorAX == size.width/2 && vectorAY == size.height/2) {
vectorAX = x;
vectorAY = y;
} else {
vectorA2X = x;
vectorA2Y = y;
dontSmoke = 1;
}
System.out.println("Mo9use down");
repaint();
return true;
}
public double scale(int x){
return (x -150.0)/100.0;
}
public int scaleTo(double x){
return (int)Math.round(x*100.0+150.0);
}
public double scaleY(int x){
return ((300-x) -150.0)/100.0;
}
public int scaleYTo(double x){
return 300-(int)Math.round(x*100.0+150.0);
}
public void drawAxis(Graphics g){
g.setColor(new Color(200,200,200));
drawScaleLine(0,-1.5,0,1.5,g);
drawScaleLine(-1.5,0,1.5,0,g);
// DrawTicks
double tickWidth = .03;
drawScaleLine(-1.0,tickWidth ,-1.0,-tickWidth ,g);
drawScaleLine(1.0,tickWidth ,1.0,-tickWidth ,g);
drawScaleLine(tickWidth ,-1.0,-tickWidth ,-1.0,g);
drawScaleLine(tickWidth ,1.0,-tickWidth ,1.0,g);
}
public void drawDashedLine(double x1,double y1,double x2, double y2,Graphics g){
drawDashedLine(g,scaleTo(x1),scaleYTo(y1),scaleTo(x2),scaleYTo(y2),4.0,5.0);
}
public void drawDashedLine(Graphics g,int x1,int y1,int x2,int y2,
double dashlength, double spacelength) {
if((x1==x2)&&(y1==y2)) {
g.drawLine(x1,y1,x2,y2);
return;
}
double linelength=Math.sqrt((x2-x1)*(x2-x1)+(y2-y1)*(y2-y1));
double yincrement=(y2-y1)/(linelength/(dashlength+spacelength));
double xincdashspace=(x2-x1)/(linelength/(dashlength+spacelength));
double yincdashspace=(y2-y1)/(linelength/(dashlength+spacelength));
double xincdash=(x2-x1)/(linelength/(dashlength));
double yincdash=(y2-y1)/(linelength/(dashlength));
int counter=0;
for (double i=0;i 0)
g.drawString(s,scaleTo(x2)+3,scaleYTo(y2)-4);
else if (x2 > 0 && y2 > 0)
g.drawString(s,scaleTo(x2)+3,scaleYTo(y2)+3);
else if (x2 < 0 && y2 < 0)
g.drawString(s,scaleTo(x2)+3,scaleYTo(y2)+11);
else if (x2 > 0 && y2 < 0)
g.drawString(s,scaleTo(x2)+3,scaleYTo(y2)+3);
}
}
public void drawScaleString(String s, double x, double y,Graphics g){
g.drawString(s,scaleTo(x),scaleYTo(y));
}
public void drawArrow(int x1, int y1, int x2, int y2, Graphics g) {
double d = Math.atan((float)((double)(y1 - y2) / (double)(x1 - x2)));
if(x1 - x2 < 0)
d += 3.1415926535897931D;
g.drawLine(x1, y1, x2, y2);
g.drawLine(x2, y2, x2 + (int)(Math.cos(d + 0.29999999999999999D) * 10D), y2 + (int)(Math.sin(d + 0.29999999999999999D) * 10D));
g.drawLine(x2, y2, x2 + (int)(Math.cos(d - 0.29999999999999999D) * 10D), y2 + (int)(Math.sin(d - 0.29999999999999999D) * 10D));
}
public void normalizea1(){
// Get distance of vector a1
double distance = Math.sqrt(scale(vectorAX)*scale(vectorAX)+scaleY(vectorAY)*scaleY(vectorAY));
// Make norm vector q1 of 3/4 a1's size
double scaleFactor = 1.0; //3.0*distance/4.0;
// Use lingear algebra package
Jama.Matrix jm = new Jama.Matrix(2,1);
jm.set(0,0,scaleFactor *scale(vectorAX));
jm.set(1,0,scaleFactor *scaleY(vectorAY));
// Without package can calc norm2 by squared sum of lengths
//double norm2 = scale(vectorAX)*scale(vectorAX)+scale(vectorAY)*scale(vectorAY); //jm.norm2();
double norm2 = jm.norm2();
vectorQX = scaleTo((scaleFactor *jm.get(0,0)/norm2));
vectorQY = scaleYTo((scaleFactor *jm.get(1,0)/norm2));
}
public void normalizea2x(){
// Use lingear algebra package
Jama.Matrix jm = new Jama.Matrix(2,1);
jm.set(0,0,scale(vectorQ2X));
jm.set(1,0,scaleY(vectorQ2Y));
double norm2 = jm.norm2();
vectorQ3X = scaleTo((jm.get(0,0)/norm2));
vectorQ3Y = scaleYTo((jm.get(1,0)/norm2));
}
public void project(){
Jama.Matrix jq = new Jama.Matrix(2,1);
jq.set(0,0,scale(vectorQX));
jq.set(1,0,scaleY(vectorQY));
Jama.Matrix ja2 = new Jama.Matrix(2,1);
ja2.set(0,0,scale(vectorA2X));
ja2.set(1,0,scaleY(vectorA2Y));
Jama.Matrix jqt = jq.transpose();
Jama.Matrix jat = jq.times(jqt.times(ja2));
//Jama.Matrix jat = jq.times(ja2.transpose());
System.out.println("Row Dim: "+jat.getRowDimension());
System.out.println("Col Dim: "+jat.getColumnDimension());
vectorD1X = scaleTo(jat.get(0,0));
vectorD1Y = scaleYTo(jat.get(1,0));
project = true;
}
public void subtract(){
Jama.Matrix jq = new Jama.Matrix(2,1);
jq.set(0,0,scale(vectorD1X));
jq.set(1,0,scaleY(vectorD1Y));
Jama.Matrix ja2 = new Jama.Matrix(2,1);
ja2.set(0,0,scale(vectorA2X));
ja2.set(1,0,scaleY(vectorA2Y));
jq = ja2.minus(jq);
vectorQ2X = scaleTo(jq.get(0,0));
vectorQ2Y = scaleYTo(jq.get(1,0));
subtract = true;
}
} //_VectorPanel
//
//----------------------------------------------------------
//
class MatrixSteps extends Panel {
static int stepNum;
Dimension size = new Dimension(150,140);
String step[];
Orthogonal parent = null;
public MatrixSteps(Orthogonal parent){
this.parent = parent;
step = new String[6];
step[0] = "Select vectors";
step[1] = "Normalize a1";
step[2] = "Project";
step[3] = "Subtract";
step[4] = "Normalize a2-x";
step[5] = "Reset";
stepNum = 0;
setBackground(Color.yellow);
}
public void paint(Graphics g){
g.setColor(Color.black);
for (int i=0;i= 0) {
g.drawOval(7,10+20*stepNum,9,9);
g.fillOval(10,13+20*stepNum,4,4);
}
g.drawRect(0,0,size.width-1,size.height-1);
}
public boolean mouseDown(Event evt, int x, int y){
System.out.println("X: "+x+" Scale: "+y);
int num = (y-7)/20;
System.out.println("Step # clicked on: "+num);
stepNum = num;
switch(num){
//case 0:
// parent.cl.show(parent.cp,"First");
//parent.vp.dontSmoke = n;
// break;
//case 1:
// parent.cl.show(parent.cp,"Second");
// parent.actOn(1);
// parent.vp.dontSmoke = 1;
// break;
//case 2:
// parent.cl.show(parent.cp,"Third");
// parent.actOn(2);
// parent.vp.dontSmoke = 2;
// break;
//case 3:
// parent.cl.show(parent.cp,"Fourth");
// parent.actOn(3);
// parent.vp.dontSmoke = 3;
// break;
//case 4:
// parent.cl.show(parent.cp,"Fifth");
// parent.actOn(4);
// parent.vp.dontSmoke = 4;
// break;
}
if (num >= 5){
parent.vp.reset();
stepNum = 0;
parent.vp.dontSmoke = 0;
parent.actOn(0);
parent.vp.reset();
} else {
parent.actOn(num+2);
parent.vp.dontSmoke = num+2;
}
repaint();
parent.vp.repaint();
parent.repaint();
return true;
}
public static void next(){
stepNum++;
if (stepNum > 4)
stepNum = -1;
}
public static void reset(){
stepNum=0;
}
public Dimension getMinimumSize() {
return size;
}
public Dimension getPreferredSize(){
return size;
}
} // _MatrixSteps