/* Roation applet allows the user to see how they mentally roatate a shape and see how least squares regressions lines are used to explain data. After the experiment it computes R square and least squares regression line Version 1.0 - 10 Oct 1999 Chris Thiel */ import java.lang.*; import java.awt.*; import java.applet.Applet; import java.awt.Graphics; import java.awt.Color; import java.awt.Event; import java.util.*; public class rotation extends Applet { int MAX=72; int step=0, n1=0; String message=null; int x1[] = new int[200]; int y1[] = new int[200]; int left[] = new int[MAX]; int right[] = new int[MAX]; int O[] = new int[MAX]; int Correct=0,Incorrect=0; float xMean, yMean; float B0, B1, R, R_square,Var_x,Var_y; int i=0; double t, angle =0.0; Color buttonColor; int buttonWidth=70; int buttonHeight=40; Rectangle Same,Mirror,Reset,Stat; Font Hel = new Font("Helvetica",1,14); Polygon S[] = new Polygon[12]; boolean ShowStats=false; Date today; long dStart,dEnd, diff; /* Compute is the routine called to compute the Statistical Data */ public void compute(){ // Now calculate regression coeffecients float Sx = 0, Sy =0; float Sxx = 0, Sxy = 0, Syy = 0; for(int i=0; i< n1; i++) { Sx += x1[i]; Sy += y1[i]; } xMean = Sx / n1; yMean = Sy / n1; for(int i=0; i< n1; i++) { Sxx += (x1[i]-xMean) * (x1[i]-xMean); Sxy += (x1[i]-xMean) * (y1[i]-yMean); Syy += (y1[i]-yMean) * (y1[i]-yMean); } B1=Sxy/Sxx; //slope B0 = yMean - B1 * xMean;//intercept R_square=(Sxy*Sxy)/(Sxx*Syy); R =(float)( Math.sqrt(R_square) ); if (B1<0) R *= -1; } private int DegreeDiff(int n){ return (int)(20*Math.abs( right[n] - left[n])) % 120; } public void init() { //setup the buttons and such buttonColor = new Color( 200,250, 220); setBackground(new Color(0xF0F0D0)); Same = new Rectangle ( size().width-buttonWidth-10,size().height-buttonHeight-10,buttonWidth,buttonHeight); Mirror= new Rectangle ( size().width-buttonWidth-10, size().height-buttonHeight-10-buttonHeight,buttonWidth,buttonHeight); Reset= new Rectangle ( 10, 10,buttonWidth,25); Stat= new Rectangle ( size().width-buttonWidth-10,10,buttonWidth,25); // Set up Array of Polygons double a,r; S[0] = new Polygon(); // "S" Shape S[0].addPoint(-40,60); S[0].addPoint(0,60); S[0].addPoint(0,20); S[0].addPoint(40,20); S[0].addPoint(40,-10); S[0].addPoint(40,-60); S[0].addPoint(0,-60); S[0].addPoint(0,-20); S[0].addPoint(-40,-20); S[0].addPoint(-40,20); // "L" Shape /* S[0].addPoint(-40,60); S[0].addPoint(0,60); S[0].addPoint(0,-20); S[0].addPoint(40,-20); S[0].addPoint(40,-60); S[0].addPoint(-40,-60); */ //Make the Mirror Image S[6]= new Polygon(S[0].xpoints, S[0].ypoints,S[0].npoints); int xM[]=S[6].xpoints; for (int i=0;i< S[6].npoints; i++){ xM[i] *=-1; } S[6].xpoints=xM; // Make array in increments of 30 degrees for (int j=1; j< 6; j++){ S[j+6] = new Polygon(S[6].xpoints, S[6].ypoints, S[6].npoints); S[j] = new Polygon(S[0].xpoints, S[0].ypoints, S[0].npoints); xM = S[j+6].xpoints; int yM[]=S[j+6].ypoints; int nM = S[j+6].npoints; int xS[]=S[j].xpoints; int yS[]=S[j].ypoints; int nS = S[j].npoints; for (int i=0;i< S[j+6].npoints; i++){ a = j*(Math.PI/10.0) +Math.atan2(yM[i],xM[i]); r = Math.sqrt(Math.pow(xM[i],2)+Math.pow(yM[i],2)); xM[i] = (int)(r * Math.cos(a)); yM[i] = (int)(r * Math.sin(a)); a = j*(Math.PI/10.0) +Math.atan2(yS[i],xS[i]); r = Math.sqrt(Math.pow(xS[i],2)+Math.pow(yS[i],2)); xS[i] = (int)(r * Math.cos(a)); yS[i] = (int)(r * Math.sin(a)); } S[j+6].xpoints=xM; S[j+6].ypoints=yM; S[j+6].translate(200,150); S[j].xpoints=xS; S[j].ypoints=yS; S[j].translate(200,150); } // Now Translate the originals S[0].translate(200,150); S[6].translate(200,150); //Initialze the Slides for diffent combos of Rotations and Mirror Image Pairs //to grade, trials 0-35 are rotations, trails 36-71 are mirror images // to see the degree difference, // or my matrix of 6x6, first row 0, 2nd=20¡, 3rd=40¡ etc... 6th=100¡ int k=0; //rotations for (int i=0; i< 6; i++){ for (int j=0; j< 6; j++){ left [k] =i; right[k] =(i+j)%6; k++; }} //mirror images for (int i=0; i<36; i++){ left[k] = left[i]; right[k] = right[i]+6; k++; } // Shuffle the Order for (int i=0; i< MAX; i++){ O[i]=i; } for (int i=0; i<300; i++){ int rnd1 = (int)((MAX-1)*Math.random()); int rnd2 = (int)((MAX-1)*Math.random()); int buff = O[rnd1]; O[rnd1]=O[rnd2]; O[rnd2]=buff; } //Initailize the timing variables today = new Date(); dStart=today.getTime(); message="Click or "; n1=0; repaint(); } private int CY(int y0){ return size().height-20-(y0/20); } private int CX(int x0){ return (int)(70+2.7*x0); } public void paint( Graphics g ) { if (ShowStats){ compute(); g.setColor(Color.red); g.drawString(" n = "+n1+" (Correct Same responses under 5 seconds)", 70 ,20); g.drawString(" y = "+B1+"x + "+B0, 70 ,35); g.drawString("r = "+R_square, 70 ,50); g.drawString("2", 75 ,47); g.drawString("^", 74 ,32); //Draw axes and labels g.setColor(Color.black); g.drawLine(CX(-10),280,CX(160),280); g.drawLine(CX(-10),20,CX(-10),CY(0)); for (int i=0;i<101;i+=20) { g.drawLine(CX(i), CY(50) ,CX(i), CY(0)); g.drawString(i+"¡",CX(i)-5,295); } for (int i=500;i<5001;i+=500) { g.drawLine(CX(-10), CY(i) ,CX(-8), CY(i)); g.drawString(i+" ms",5,CY(i)+5); } //Draw observations and regression line g.setColor(Color.blue); for (int i=0;i100)&&(diff<6000)){ // record if Correct and done in reasonable time x1[n1]= DegreeDiff(O[step]); y1[n1]=(int)(diff); n1++; } } else { message="No, last one was a mirror image"; Incorrect++; } step++; if (step >71) step=0; //reset stopwatch today = new Date(); dStart=today.getTime(); } else if ( Mirror.inside(x0,y0) ) { today = new Date(); dEnd=today.getTime(); diff=dEnd-dStart; if (O[step] > 35){ message="Correct!"; Correct++; if ((diff>100)&&(diff<6000)){ // record if Correct and done in reasonable time x1[n1]= DegreeDiff(O[step]); y1[n1]=(int)(diff); n1++; } } else { message="No, the last one was the same"; Incorrect++; } step++; if (step >71) step=0; //reset stopwatch today = new Date(); dStart=today.getTime(); } else if ( Reset.inside(x0,y0) ) { // Shuffle the Order for (int i=0; i< MAX; i++){ O[i]=i; } for (int i=0; i<300; i++){ int rnd1 = (int)((MAX-1)*Math.random()); int rnd2 = (int)((MAX-1)*Math.random()); int buff = O[rnd1]; O[rnd1]=O[rnd2]; O[rnd2]=buff; } //Initailize the timing variables today = new Date(); dStart=today.getTime(); n1=0; step=0; Correct=0; Incorrect=0; message ="All statistics reset!"; repaint(); } else if ( Stat.inside(x0,y0) ) { //show stats if( n1 <3 ) { message = "Not enough data yet!"; } else { ShowStats =!ShowStats; } } repaint(); return true; } public boolean mouseMove(java.awt.Event evt, int x, int y) { y= (int)((size().height-20-y)*20); x= (int)((x-70)/2.7); if (ShowStats) getAppletContext().showStatus("Location of mouse: (" + x + ", " + y + ")"); return true; } public void mouseEnter() { repaint(); } public void mouseExit() { repaint(); } }//of applet