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