Trig Drill
<< Birds | OtherProjectsTrailIndex | Guassian Elimination >>
Ngon.java
import java.awt.Polygon; public class Ngon extends Polygon { public Ngon(int sides, int left, int top, int radius){ this(sides, left, top, radius, 0); } public Ngon(int sides, int left, int top, int radius, double degrees){ double start=degrees*Math.PI/180.0; for(double theta=start; theta<2*Math.PI+start; theta+=2*Math.PI/sides) addPoint((int)(radius*Math.cos(theta)), (int)(radius*Math.sin(theta+Math.PI))); translate(left+radius,top+radius); } public int getX(int i){ return this.xpoints[i]; } public int getY(int i){ return this.ypoints[i]; } public int getCenterX(){return getBounds().x + getBounds().width/2;} public int getCenterY(){return getBounds().y + getBounds().height/2;} }
CircleButton.java
import java.awt.Color; import java.awt.Font; import java.awt.Graphics; import java.awt.Rectangle; public class CircleButton { // instance variables - replace the example below with your own private Rectangle bounds; protected Color color; private String name; protected boolean hilight; protected boolean pressed; private Font font=new Font("SansSerif",Font.BOLD, 14); /** * Constructor for objects of class CircleButton */ public CircleButton(int x, int y, int size, String name, Color color) { this(x,y,size,size,name,color); } public CircleButton(int x, int y, int width, int height, String name, Color color) { bounds = new Rectangle(x,y,width,height); this.color = color; this.name = name; this.hilight=false; this.pressed=false; } public void draw(Graphics g) { if (hilight){ g.setColor(Color.BLACK); g.fillOval(bounds.x-4, bounds.y-4, bounds.width+8, bounds.height+8); } if (pressed) g.setColor(Color.BLACK); else g.setColor(color); g.fillOval(bounds.x, bounds.y, bounds.width, bounds.height); g.setFont(font); if (pressed) g.setColor(Color.WHITE); else g.setColor(Color.BLACK); int x=bounds.x+(bounds.width-name.length()*7)/2; int y=bounds.y+(bounds.height/2+4); g.drawString(name, x, y); } public void setHilight(boolean b){ hilight=b;} public boolean isHilighted() {return hilight;} public void setPressed(boolean b){ pressed=b;} public boolean isPressed() { return pressed; } public boolean contains(int x, int y){ return bounds.contains(x,y); } public String getName() {return name;} public void setName(String s){name=s;} public Color getColor(){return color;} public void setColor(Color c){color=c;} public void setBounds(Rectangle r){bounds=r;} public Rectangle getBounds(){return bounds;} public int getX(){return bounds.x;} public int getY(){return bounds.y;} public int getSize(){return bounds.width;} public void setFont(Font f){font=f;} public Font getFont(){return font;} public int getCenterX(){return bounds.x + bounds.width/2;} public int getCenterY(){return bounds.y + bounds.height/2;} }
QuestionButton.java
import java.awt.Color; import java.awt.Font; import java.awt.Graphics; public class QuestionButton extends CircleButton { private boolean visable; private String question,answer; public QuestionButton(int x, int y, int width, int height, String name, Color color) { super(x, y, width, height, name, color); visable=true; } public boolean isVisable(){return visable;} public void setVisable(boolean b){ visable=b;} public void draw(Graphics g){ if (!visable) return; setFont(new Font("serif", Font.ITALIC + Font.BOLD, 36)); if (hilight){ g.setColor(Color.BLACK); g.fillOval(getBounds().x-4, getBounds().y-4, getBounds().width+8, getBounds().height+8); } if (pressed) g.setColor(Color.BLACK); else g.setColor(color); g.fillOval(getBounds().x, getBounds().y, getBounds().width, getBounds().height); if (pressed) g.setColor(Color.WHITE); else g.setColor(Color.BLACK); int x=getBounds().x+(getBounds().width-getName().length()*18)/2; int y=getBounds().y+(getBounds().height/2+10); g.setFont(getFont()); g.drawString(getName(), x, y); } public void setQuestion(String q, String a){ question=q; answer=a; } public void showQuestion(){ this.setName(question); } public void showAnswer(){ this.setName(question+answer); } public String getAnswer() { return answer; } }
AnswerButton.java
import java.awt.Color; import java.awt.Font; import java.awt.Graphics; public class AnswerButton extends CircleButton { private boolean visable; public AnswerButton(int x, int y, int width, int height, String name, Color color) { super(x, y, width, height, name, color); visable=true; } public boolean isVisable(){return visable;} public void setVisable(boolean b){ visable=b;} public void draw(Graphics g){ if (visable){ //g.setFont(new Font("sansserif",Font.BOLD,14)); super.draw(g); } } }
Stats.java
import java.text.DecimalFormat; import java.util.ArrayList; import java.util.Collections; public class Stats { private ArrayList<Double> d; private double sum, sumSq; DecimalFormat df; public Stats(){ d=new ArrayList<Double>(); sum=0; sumSq=0; df=new DecimalFormat("#.##"); } public void add(double x){ d.add(x); sum+=x; sumSq+=x*x; } public double getMean(){ if (d.size()>0) return sum/d.size(); return 0; } public String getMeanString(){ if(d.size()<1) return ""; return df.format(getMean()); } public double getSD(){ if (d.size()<2) return 0; return Math.sqrt((sumSq-(sum*sum/d.size()))/(d.size()-1)); } public String getSDString(){ if(d.size()<2) return ""; return df.format(getSD()); } public double getQuartile(int q){ int n=d.size(); if(n<4) if(n>0) return d.get(0); else return 0; Collections.sort(d); int index=q*n/4; boolean even=n%q==0; if (q==3){ even=n%4==0; } if (even) return 0.5*( d.get(index)+ d.get(index-1)); return d.get(index); } public String getIQRString(){ if (d.size()<4) return ""; return "between "+df.format(getQuartile(1))+" and "+df.format(getQuartile(3)); } public String getQuartileString(int q){ return df.format(getQuartile(q)); } public int n(){ return d.size();} }
TrigDrill3.java
import java.applet.Applet; import java.text.DecimalFormat; import java.util.ArrayList; import java.util.Date; import java.util.HashMap; import java.awt.*; import java.awt.event.*; import java.awt.image.BufferedImage; public class TrigDrill3 extends Applet implements MouseListener,MouseMotionListener { private HashMap<String,String> sin, cos, tan,csc,sec,cot; private Image virtualMem; private BufferedImage img; private Graphics gBuffer; private ArrayList<AnswerButton> btns; private QuestionButton qBtn; private Rectangle easyBtn,resetBtn; private Stats stats; private Font big,small; private boolean easyMode, started; private String message; public static final String pi="\u03c0"; public static final String root="\u221A"; public static final String[] angles={"-"+pi+"/2", "-"+pi+"/3", "-"+pi+"/4", "-"+pi+"/6", "0", pi+"/6", pi+"/4", pi+"/3", pi+"/2", "2"+pi+"/3", "3"+pi+"/4", "5"+pi+"/6", pi, "7"+pi+"/6", "5"+pi+"/4", "4"+pi+"/3", "3"+pi+"/2", "5"+pi+"/3", "7"+pi+"/4", "11"+pi+"/6"}; public static final String[] functions={"arcsin", "arccos", "arctan", "arccsc", "arcsec","arccot"}; public static final String[] ratios = {"0", "1/2",root+"3/3",root+"2/2",root+"3/2","1","2"+root+"3/3", "undefined", "-1/2","-"+root+"3/3","-"+root+"2/2","-"+root+"3/2","-1","-"+root+"2", "-"+root+"3","-2"+root+"3/3"}; private Color btnColor, bgColor; private int centerX, centerY, count, correct; private DecimalFormat df; long startTime; public void initAnswers(){ sin = new HashMap<String,String>(); cos = new HashMap<String,String>(); tan = new HashMap<String,String>(); csc = new HashMap<String,String>(); sec = new HashMap<String,String>(); cot = new HashMap<String,String>(); sec.put(pi, "-1"); sec.put("5"+pi+"/6", "-2"+root+"3/3"); sec.put("3"+pi+"/4","-"+root+"2"); sec.put("2"+pi+"/3", "-2"); sec.put(pi+"/2", "undefined"); sec.put(pi+"/3", "2"); sec.put(pi+"/4",root+"2"); sec.put(pi+"/6", "2"+root+"3/3"); sec.put("0", "1"); cos.put(pi, "-1"); cos.put("5"+pi+"/6", "-"+root+"3/2"); cos.put("3"+pi+"/4","-"+root+"2/2"); cos.put("2"+pi+"/3", "-1/2"); cos.put(pi+"/2", "0"); cos.put(pi+"/3", "1/2"); cos.put(pi+"/4",root+"2/2"); cos.put(pi+"/6", root+"3/2"); cos.put("0", "1"); sin.put(angles[0], "-1"); sin.put(angles[1], "-"+root+"3/2"); sin.put(angles[2], "-"+root+"2/2"); sin.put(angles[3], "-1/2"); sin.put(angles[4], "0"); sin.put(angles[5], "1/2"); sin.put(angles[6], root+"2/2"); sin.put(angles[7], root+"3/2"); sin.put(angles[8], "1"); csc.put(angles[0], "-1"); csc.put(angles[1], "-2"+root+"3/3"); csc.put(angles[2], "-"+root+"2"); csc.put(angles[3], "-2"); csc.put(angles[4], "undefined"); csc.put(angles[5], "2"); csc.put(angles[6], root+"2"); csc.put(angles[7], "2"+root+"3/3"); csc.put(angles[8], "1"); tan.put(angles[0], "undefined"); tan.put(angles[1], "-"+root+"3"); tan.put(angles[2], "-1"); tan.put(angles[3], "-"+root+"3/3"); tan.put(angles[4], "0"); tan.put(angles[5], root+"3/3"); tan.put(angles[6], "1"); tan.put(angles[7], root+"3"); tan.put(angles[8], "undefined"); cot.put(angles[0], "0"); cot.put(angles[1], "-"+root+"3/3"); cot.put(angles[2], "-1"); cot.put(angles[3], "-"+root+"3"); cot.put(angles[4], "undefined"); cot.put(angles[5], root+"3"); cot.put(angles[6], "1"); cot.put(angles[7], root+"3/3"); cot.put(angles[8], "0"); } public void makeQuestion(){ int max=6; if (easyMode) max=3; int f = (int)(max*Math.random()); //for sin,csc,tan,cot, angles 0 through 8 int a = (int)(9*Math.random()); if (f==1 || f==4){//for cos,sec angle 4 through 12 a+=4; } //repair so undefined is ok if ((f==3 || f==2) && a==0)//csc or tan undefined a=8; if ((f==5 ||f==4) && a==12)//sec or cot undefined a=4; String answer=angles[a]; String question=""; if (f==0) question=sin.get(answer); else if (f==1) question=cos.get(answer); else if (f==2) question=tan.get(answer); else if (f==3) question=csc.get(answer); else if (f==4) question=sec.get(answer); else if (f==5) question=cot.get(answer); question=functions[f]+"("+question+")="; qBtn.setQuestion(question, answer); } public void init(){ easyMode=true; started=false; count=0; correct=0; df=new DecimalFormat("##.#"); virtualMem = createImage(getWidth(),getHeight()); gBuffer = virtualMem.getGraphics(); message=" Press Start to begin"; big = new Font("serif", Font.ITALIC + Font.BOLD, 36); small = new Font("Ariel",Font.BOLD,14); //bgColor = new Color(255, 204,167); bgColor = new Color(226, 182,138); btnColor = new Color(255, 230,211); initAnswers(); Ngon shape = new Ngon(16, 30, 110, 180,-90); btns = new ArrayList<AnswerButton>(); for (int i=0; i<16; i++) btns.add(new AnswerButton(shape.getX(i),shape.getY(i),65,25 ,angles[i], btnColor) ); centerX=btns.get(0).getCenterX(); centerY=btns.get(4).getCenterY(); qBtn=new QuestionButton(105,20, 300,55,"Start", Color.YELLOW); easyBtn=new Rectangle(375,525,125,25); resetBtn=new Rectangle(0,0,95,25); stats = new Stats(); addMouseListener(this); addMouseMotionListener(this); } public void paint(Graphics g){ gBuffer.setColor(bgColor); gBuffer.fillRect(0, 0, getWidth(), getHeight()); gBuffer.setColor(Color.BLACK); gBuffer.drawLine(centerX, 110, centerX, 480); gBuffer.drawLine(32, centerY, 400, centerY); gBuffer.setColor(btnColor); //gBuffer.fillRect(easyBtn.x, easyBtn.y, easyBtn.width, easyBtn.height); //gBuffer.fillRect(resetBtn.x, resetBtn.y, resetBtn.width, resetBtn.height); for (int i=0; i<btns.size(); i++){ AnswerButton b=btns.get(i); if (b.isHilighted()){ gBuffer.drawLine(centerX, centerY, b.getCenterX(), b.getCenterY()); gBuffer.drawLine(b.getCenterX(), centerY, b.getCenterX(), b.getCenterY()); } b.draw(gBuffer); } qBtn.draw(gBuffer); gBuffer.setFont(small); gBuffer.drawString(message, 120,100); gBuffer.drawString(correct+" out of "+count+" correct", 20,20); if (count>0) gBuffer.drawString(df.format(100*(double)correct/count)+"%", 20,40); if (easyMode) gBuffer.drawString("Easy Mode On", 380, 545); else gBuffer.drawString("Easy Mode Off", 380, 545); if (stats.n()>3){ gBuffer.drawString("Mean time: "+stats.getMeanString(), 10, 515); gBuffer.drawString("Half your correct times are ", 10, 530); gBuffer.drawString(stats.getIQRString()+" secs", 10, 545); } g.drawImage(virtualMem,0,0,this); } public void mouseClicked(MouseEvent e){} public void mousePressed(MouseEvent e){ int x=e.getX(); int y=e.getY(); for(CircleButton c:btns) c.setPressed(c.contains(x,y)); qBtn.setPressed(qBtn.contains(x,y)); repaint(); } public void mouseReleased(MouseEvent e){ int x=e.getX(); int y=e.getY(); for(AnswerButton c:btns){ c.setPressed(false); if(c.contains(x,y)) doButton(c); } if (qBtn.contains(x,y)){ qBtn.setPressed(false); if (!started){ started=true; message=""; this.makeQuestion(); startTime= new Date().getTime(); qBtn.setColor(Color.YELLOW); qBtn.showQuestion(); } } if (resetBtn.contains(x,y)){ count=0; correct=0; stats=new Stats(); } if (easyBtn.contains(x,y)){ easyMode=!easyMode; } repaint(); } public void mouseEntered(MouseEvent e){} public void mouseExited(MouseEvent e){} public void mouseMoved(MouseEvent e){ int x=e.getX(); int y=e.getY(); //if(!gameOver) for(CircleButton c:btns){ c.setHilight(c.contains(x,y)); } qBtn.setHilight(qBtn.contains(x,y)); repaint(); } public void mouseDragged(MouseEvent e){} public void doButton(AnswerButton b) { if(!started) return; double time=(new Date().getTime()-startTime)/1000.0; started=false; qBtn.showAnswer(); message="Time:"+time; count++; if (b.getName().equals(qBtn.getAnswer() )){ message="Correct! You got that in "+time+" secs."; stats.add(time); correct++; qBtn.setColor(Color.GREEN); }else{ message="No, not "+b.getName(); qBtn.setColor(Color.RED); } repaint(); } public void update(Graphics g){ paint(g); } }