Back to index

wims  3.65+svn20090927
GetallenLijn.java
Go to the documentation of this file.
00001 /* 
00002 No copyright...
00003 
00004 Example of usage:
00005 
00006 <html>
00007 <head></head>
00008 <body>
00009     <script language="javascript" type="text/javascript">                                                                                      
00010        function readthis(){                                                                                                                           
00011            var input=document.applets[0].ReadApplet(); 
00012            if(input.indexOf(error)!=-1){
00013               alert(input);
00014            }
00015            else
00016            {                                                                          
00017               alert("we will send to WIMS:"+input);
00018            }
00019        }                                                                                                                                         
00020     </script>                                                                                                                                  
00021     <center>
00022     <applet code="NumberLine.class" width=600 height=240>
00023     <!--- no params needed ; defaults are fine --->
00024        <param name="xmax" value="50">
00025        <param name="fontsize" value="16">
00026        <param name="join" value="no">
00027        <param name="language" value="nl">
00028        <param name="pencolor" value="0,0,255><!--- input field foreground color --->
00029        <param name="bgcolor1" value="255,255,255><!--- input field background color --->
00030        <param name="bgcolor2" value="255:255;255"><!--- canvas color : may conflict with arrow colors...--->
00031        <param name="exercise" value="an exercise, if not given in a wims phml page">
00032     </applet>
00033     <input type="button" name=".....TEST......" value=".....TEST....." onclick="javascript:readthis();">
00034 </body>
00035 </html>
00036 
00037 the WIMS reply type format:
00038  
00039 boolean,"verbatim reply"
00040 true,123-23=100
00041 false,123-23=99
00042 false,error \n multiple = -signs [e.g. 123-23=100-0=100]
00043 false,error \n mathematical error [Arity error exception]
00044 
00045 todo: dynamic scaling of xmax/xmin/step [with mouse drag ?/]
00046 
00047 Arity usage example: 
00048 fun="sin(2*pi/2)"
00049 fun="(1.2345678-2.345678)/12345678"
00050 try { y=symbols.eval(fun);} catch (SyntaxException e) {System.out.println("error "+e); } 
00051 */
00052 
00053 
00054 import java.awt.*;
00055 import java.applet.*;
00056 import java.util.*;
00057 import org.javia.arity.*;
00058 
00059 
00060 public class GetallenLijn extends Applet {
00061     
00062     int xmax=100;int xmin=-100;
00063     int xmax_org=xmax;int xmin_org=xmin;
00064     double step=3.0D;int x_pix=600;int y_pix=240;int x_nul=300;int y_nul=60;
00065     int font_size=36;int minmax=200;boolean start= false;
00066     String op[]={"+","-"};
00067     Graphics g;int vectors=0;
00068     boolean join = false;
00069     boolean conclusion_drawn=false;
00070     int arrowdistance=10;// moet in verhouding met hoogte...
00071     private TextField input;
00072     double fragment[];
00073     int now=0;
00074     int kleuren[][]={ {255,0,0},{0,255,0},{0,0,255},{238,154,0},{255,255,0},{160,32,240},{144,238,144},{173,216,230},{0,255,255},{165,24,24},{250,128,114},{255,192,203} };
00075     // 11 kleuren ... zie changecolor()
00076     Color arrowcolor;
00077     Color pencolor;
00078     int R1=225;int G1=255;int B1=255;Color bgcolor1;
00079     int R2=255;int G2=255;int B2=255;Color bgcolor2;
00080     // java 1.4 can not use replaceAll(); 
00081     String illegalchars[]={"a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z","(",")","{","}","[","]","@","#","~","!","$","%","^","&","_",":",";",">","<","|"};
00082     // 46 items : prepare();
00083     String cijfers[]={"0","1","2","3","4","5","6","7","8","9"};
00084     double multiplication[];
00085     String param;String title;String exercise="";String inputtext;
00086     String rem1="Error: wrong answer type (multiple = -signs)";
00087     String rem2="Mathematical error";
00088     String rem3="Error: = sign forgotten";
00089     double tmpsum=1.0D;
00090 
00091     
00092     public void init(){
00093        Font myfont = new Font("Helvetica", Font.BOLD, font_size);
00094        setLayout(new GridLayout(4, 1));
00095        input=new TextField(40);
00096        input.setFont(myfont);add(input);setVisible(true);
00097        arrowcolor=new Color(kleuren[now][0],kleuren[now][1],kleuren[now][2]);
00098        param=getParameter("language");
00099        if(param!=null && param.length()>0){
00100            if(param.equalsIgnoreCase("nl")){
00101               rem1="Fout:verkeerd type antwoord (meerdere = -tekens)";
00102               rem2="Wiskundige fout";
00103               rem3="Fout:je hebt het = teken vergeten";
00104            }
00105            if(param.equalsIgnoreCase("de")){
00106               rem1="Fehler";
00107               rem2="Mathematik Fehler";
00108               rem3="Fehler: = Zeichen vergessen";
00109            }
00110            if(param.equalsIgnoreCase("fr")){
00111               rem1="Erreur";
00112               rem2="Erreur mathematique";
00113               rem3="Erreur: vous avez oubliť d'utiliser un = signe";
00114            }
00115        }
00116        param=getParameter("title");
00117        if(param!=null){title=param;}else{title="";}
00118        param=getParameter("xmax");
00119        if(param!=null && param.length()>0 ){xmax = Integer.parseInt(param, 10);}
00120 //     param=getParameter("xmin");
00121 //     if(param!=null){xmin = Integer.parseInt(param, 10);}
00122        param=getParameter("fontsize");
00123        if(param!=null && param.length()>0){font_size = Integer.parseInt(param, 10);}
00124        param=getParameter("join");
00125        if(param!=null){if(param.equals("1") || param.equalsIgnoreCase("yes")){join = true;}}
00126        param=getParameter("exercise");
00127        if(param!=null && param.length()>0){exercise = param; input.setText(exercise);}
00128        param=getParameter("pencolor"); // foreground color of inputfield "input"
00129        if (param != null && param.length()>0){
00130            param=param.replace(':',',');param=param.replace(';',',');
00131            StringTokenizer q = new StringTokenizer(param, ",");
00132            String k;int rgb;
00133            for( int a=0; a<3 ; a++){
00134               k=q.nextToken();
00135               rgb=Integer.parseInt(k, 10);
00136               if(rgb<0){rgb=0;}
00137               if(rgb>255){rgb=255;}
00138               if(a == 0){R1 = rgb;}
00139               else if(a == 1){G1 = rgb;}
00140               else if(a == 2){B1 = rgb;}
00141            }
00142            pencolor=new Color(R1,G1,B1);
00143            input.setForeground(pencolor);
00144        }
00145 
00146        param=getParameter("bgcolor1"); // Background color of inputfield "input"
00147        if (param != null && param.length()>0){
00148            param=param.replace(':',',');param=param.replace(';',',');
00149            StringTokenizer q = new StringTokenizer(param, ",");
00150            String k;int rgb;
00151            for( int a=0; a<3 ; a++){
00152               k=q.nextToken();
00153               rgb=Integer.parseInt(k, 10);
00154               if(rgb<0){rgb=0;}
00155               if(rgb>255){rgb=255;}
00156               if(a == 0){R1 = rgb;}
00157               else if(a == 1){G1 = rgb;}
00158               else if(a == 2){B1 = rgb;}
00159            }
00160            bgcolor1=new Color(R1,G1,B1);
00161            input.setBackground(bgcolor1);
00162        }
00163 
00164        param=getParameter("bgcolor2"); // Background color of canvas
00165        if (param != null && param.length()>0){
00166            param=param.replace(':',',');param=param.replace(';',',');
00167            StringTokenizer q = new StringTokenizer(param, ",");
00168            String k;int rgb;
00169            for( int a=0; a<3 ; a++){
00170               k=q.nextToken();
00171               rgb=Integer.parseInt(k, 10);
00172               if(rgb<0){rgb=0;}
00173               if(rgb>255){rgb=255;}
00174               if(a == 0){R2 = rgb;}
00175               else if(a == 1){G2 = rgb;}
00176               else if(a == 2){B2 = rgb;}
00177            }
00178            bgcolor2=new Color(R2,G2,B2);
00179        }
00180        // needs changing !
00181        xmin=-1*xmax;
00182        xmax_org=xmax;
00183        xmin_org=xmin;
00184        minmax=Math.abs(xmax-xmin);
00185        if(minmax == 0){xmax=25;xmin=-25;minmax=50;}
00186        x_pix = getSize().width;
00187        y_pix = getSize().height;
00188        y_nul=(int)y_pix/4;
00189        // xnul is at center for now
00190        x_nul =(int) ((xmax-xmin)/2)*x_pix/(minmax); // x_nul is positie  op graphics in pixels
00191        step=(double)x_pix/(minmax);
00192        input.requestFocus();
00193    }
00194        
00195 
00196     public boolean keyUp(Event event, int key){
00197        prepare();
00198        return true;
00199     }
00200 
00201     public void prepare(){
00202        inputtext=input.getText();
00203        int len=inputtext.length();
00204        if(len>0){
00205            boolean found = false; String last; 
00206            inputtext=inputtext.toLowerCase();
00207            for(int i=0;i<46;i++){
00208               inputtext=replace(inputtext,illegalchars[i],"");
00209            }
00210            inputtext=replace(inputtext,",",".");
00211            inputtext=replace(inputtext,"*","\u2217");
00212            input.setText(inputtext);
00213            len=inputtext.length();
00214            last = inputtext.substring(inputtext.length()-1,inputtext.length());
00215            for(int i=0;i<10;i++){
00216               if(last.equals(cijfers[i])){ found = true;}
00217            }
00218            if( found ){convert();}else{repaint();} 
00219        }
00220        input.setCaretPosition(len);
00221        input.requestFocus();    
00222     }
00223     
00224     public void changecolor(){
00225        now++;// 11 kleuren, niet meer...
00226        if( now > 11 ){ now = (int) (11*(Math.random())); }
00227        arrowcolor=new Color(kleuren[now][0],kleuren[now][1],kleuren[now][2]);
00228     }
00229     
00230     public void convert(){
00231        // arity lib throws errors +-5-+3------23 etc
00232        Symbols symbols=new Symbols();
00233        String S=input.getText();
00234        for(int s=0;s<10;s++){
00235            S=replace(S,"+-","-");
00236            S=replace(S,"-+","-");
00237            S=replace(S,"--","+");
00238            S=replace(S,"++","+");
00239        }
00240        S=replace(S,"/","@1/");
00241        S=replace(S,"+","#+");
00242        S=replace(S,"-","#-");
00243        S=replace(S,"==","=");
00244        S=replace(S,"=","#=#");
00245        S=replace(S,"\u2217#+","@");       
00246        S=replace(S,"\u2217#-","@-");      
00247        S=replace(S,"\u2217","@");
00248        //System.out.println("S in nu:"+S); 
00249        int L=S.length();
00250        if(S != null || L > 0){
00251            String tmp1[]=S.split("#");int n=0;int sign=1;double t1=1D;double t2=1D;
00252            fragment =new double[L];
00253            multiplication = new double[L];
00254            int idx;
00255            tmpsum=0;
00256            for(int i=0;i<tmp1.length;i++){
00257               if(tmp1[i].length()!=0){
00258                   if(tmp1[i].indexOf("=")!= -1){
00259                      multiplication[n]=-1;
00260                      fragment[n]=1.23456789;n++;
00261                   }
00262                   else
00263                   {
00264                      if(tmp1[i].indexOf("@")!=-1){
00265                          String tmp2[]=tmp1[i].split("@");
00266                          t1=Double.parseDouble(replace(tmp2[0],"+",""));
00267                          tmp2[1]=replace(tmp2[1],"--","");
00268                          if(tmp2[1].indexOf("/")!=-1){
00269                             try { t2=symbols.eval(replace(tmp2[1],"+",""));} catch (SyntaxException e) {input.setText("?");System.out.println("error "+e+"\n caused by "+fragment[n]); }
00270                          }
00271                          else
00272                          {
00273                             t2=Double.parseDouble(replace(tmp2[1],"+",""));
00274                          }
00275                          if(t1<0){sign=-1;}else{sign=1;} // -5*3 -> -1*3 -1*3 -1*3 -1*3 -1*3
00276                          t1=Math.abs(t1);
00277                          for(int p=0;p<t1;p++){
00278                             if(n >= L){
00279                                 idx=(int)(t1)+n;
00280                                 L=idx;
00281                                 fragment = GrowArray(fragment,idx,n);
00282                                 multiplication = GrowArray(multiplication,idx,n);
00283     
00284                             }
00285                             multiplication[n]=1;
00286                             fragment[n]=sign*t2;n++;
00287                          }
00288                      }
00289                      else
00290                      {
00291                          multiplication[n] = 0;
00292                          try { fragment[n]=symbols.eval(tmp1[i]);n++;} catch (SyntaxException e) {input.setText("?");System.out.println("error "+e+"\n caused by "+fragment[n]); } 
00293                      }
00294                   }
00295                   if(join){
00296                      tmpsum=tmpsum+(fragment[n-1]);
00297                   }else{
00298                      if((Math.abs(fragment[n-1]))>(Math.abs(tmpsum))){tmpsum=Math.abs(fragment[n-1]);}
00299                   }
00300               }
00301            }
00302            start=true;
00303            tmpsum=Math.abs(tmpsum);
00304            if(tmpsum>1000){tmpsum=1000;}
00305            double tmp;
00306            if(tmpsum<100){
00307               tmp=Math.ceil(tmpsum/10);
00308               xmax=10*((int)tmp);
00309            }
00310            else
00311            {
00312               tmp=Math.ceil(tmpsum/100);
00313               xmax=100*(int)(tmp);
00314            }
00315            xmin=-1*xmax;// let op nog steeds x=0 symmetrisch op x_pix/2
00316            repaint();
00317        }
00318     }
00319         
00320     public boolean action(Event event, Object currentTarget){
00321        // enter ...not used for now
00322        return true;
00323     }
00324 
00325     public void paint(Graphics g){
00326        step=(double)x_pix/(xmax - xmin);  
00327        if(step == 0){step=1;}
00328        now=0;int y=y_nul+vectors+60;double x1=0.0D;double x2=0.0D;double previous=0.0D;
00329        g.setColor(bgcolor2);g.fillRect(0,y_nul,x_pix,y_pix);
00330        if(start){
00331            for(int p=0;p<fragment.length;p++){
00332               x2=fragment[p];
00333                if(multiplication[p] < 1){changecolor();}else{arrowcolor=new Color(255,30,30);}
00334               if(x2 != 0.0){
00335                   if(x2 == 1.23456789){
00336                      y=y+arrowdistance;
00337                       tekenconclusie( 0, y , x_pix , y, g);
00338                       y=y+2*arrowdistance;
00339                      previous=x_nul;
00340                       x2=fragment[p+1];p++;
00341                      conclusion_drawn=true;
00342                   }
00343                   if(join){
00344                      if( p == 0){
00345                          x1=(double) x_nul;
00346                          x2=x1+(x2*step);
00347                          previous=x2;
00348                      }
00349                      else
00350                      {
00351                          x1=previous;
00352                          if(x1 == 0.0){x1=x_nul;}
00353                          x2=x1+(x2*step);
00354                          previous=x2;
00355                      }
00356                   }
00357                   else
00358                   {
00359                      x1=x_nul;
00360                       x2=x1+(x2*step);
00361                   }
00362                   tekenVector( (int)x1, y , (int)x2 , y, conclusion_drawn, g);
00363                   //System.out.println("x1="+x1+" x2="+x2+" x_nul="+x_nul);
00364                   y=y+arrowdistance;
00365               }
00366            }
00367        }
00368        drawSchaal(g);
00369        input.requestFocus();
00370     }
00371        
00372     public void drawSchaal(Graphics g){
00373        Graphics2D g2 = (Graphics2D) g;
00374        g2.setStroke( new BasicStroke(1.1f) );
00375        g2.setColor(Color.black);
00376        int t=0;int sc; 
00377        int sc1=(int)(Math.abs(xmin));
00378        int sc2=(int)(Math.abs(xmax));
00379        if(sc1 > sc1){sc=sc1;}else{sc=sc2;}
00380        int[] i=new int[3];
00381        int[] s=new int[3];
00382        s[0]=30;
00383        s[1]=20;
00384        s[2]=10;
00385        if(sc>0 && sc<11){
00386            i[0]=5;
00387            i[1]=1;
00388            i[2]=1;
00389        }
00390        else
00391        {
00392            if(sc>10 && sc<51){
00393               i[0]=10;
00394               i[1]=5;
00395               i[2]=1;
00396            }
00397            else
00398            {
00399               if(sc>50 && sc<101){
00400                   i[0]=20;
00401                   i[1]=10;
00402                   i[2]=2;
00403               
00404               }
00405               else
00406               {
00407                   if(sc>100 && sc<501){
00408                      i[0]=50;
00409                       i[1]=25;
00410                       i[2]=5;
00411                   }
00412                   else
00413                   { // sc<1000
00414                      i[0]=100;
00415                       i[1]=50;
00416                      i[2]=25;
00417                   }
00418               }
00419            }
00420        }      
00421        
00422        if(xmax>0){
00423            for(int r=0;r<3;r++){
00424               for(int p=0;p<xmax;p=p+i[r]){
00425                   t=(int) ((p*x_pix/(xmax - xmin))  - xmin*x_pix/(xmax - xmin));
00426                   g2.drawLine(t,y_nul,t,y_nul+s[r]);
00427                   if(r==0){
00428                      g2.drawString(""+p+"",t-(g.getFontMetrics().stringWidth(" "+p+" "))/2,y_nul+50);
00429                   }
00430               }
00431            }
00432        }
00433        if(xmin<0){
00434            for(int r=0;r<3;r++){
00435               for(int p=0;p>xmin;p=p-i[r]){
00436                   t=(int) ((p*x_pix/(xmax - xmin))  - xmin*x_pix/(xmax - xmin));
00437                   g2.drawLine(t,y_nul,t,y_nul+s[r]);
00438                   if(r==0){
00439                      g2.drawString(""+p+"",t-(g.getFontMetrics().stringWidth(" "+p+" "))/2,y_nul+50);
00440                   }
00441               }
00442            }
00443        }
00444     }
00445 
00446     public void tekenVector(int x1, int y1, int x2, int y2,  boolean con ,Graphics g ){
00447        double d = Math.atan((float)((double)(y1 - y2) / (double)(x1 - x2)));
00448        Graphics2D g2 = (Graphics2D) g;
00449        g2.setColor(arrowcolor);
00450        if(Math.abs(x2-x1) < step*10){g2.setStroke( new BasicStroke(2.0f) );}else{g2.setStroke( new BasicStroke(3.0f) );}
00451        if(x1 - x2 < 0){d += 3.1415926535897931D;}
00452        g2.drawLine(x1, y1, x2, y2);
00453        g2.drawLine(x2, y2, x2 + (int)(Math.cos(d + 0.6D) * 10D), y2 + (int)(Math.sin(d + 0.6D) * 10D)); 
00454        g2.drawLine(x2, y2, x2 + (int)(Math.cos(d - 0.6D) * 10D), y2 + (int)(Math.sin(d - 0.6D) * 10D));
00455        if(con){//we have drawn a dashed conclusion line : no we mark the and of the final ? arrow with a vertical line
00456            g2.setStroke( new BasicStroke(4f) );
00457            g2.setColor(Color.red);
00458            g2.drawLine(x2,0,x2,y2);
00459            conclusion_drawn=false;
00460        }
00461 
00462     } 
00463 
00464     public void tekenconclusie(int x1, int y1, int x2, int y2, Graphics g){
00465        Graphics2D g2 = (Graphics2D) g;
00466        g2.setStroke(dashed);
00467        g2.setColor(Color.black);
00468        g2.drawLine(x1, y1, x2, y2);
00469     }
00470     
00471     public static int[] Shuffle(int[] S){
00472        int ll= S.length;
00473        for (int i=0;i<ll;i++){
00474            int r = (int) (Math.random() * (i+1));
00475            int swap = S[r];
00476            S[r] = S[i];
00477            S[i] = swap;
00478        }  
00479        return S;  
00480     } 
00481      
00482     public static String replace(String source, String pattern, String replace){
00483        if (source!=null){
00484            final int len = pattern.length();
00485            StringBuffer sb = new StringBuffer();
00486            int found = -1;
00487            int start = 0;
00488            while( (found = source.indexOf(pattern, start) ) != -1){
00489               sb.append(source.substring(start, found));
00490               sb.append(replace);
00491               start = found + len;
00492            }
00493            sb.append(source.substring(start));
00494            return sb.toString();
00495         }
00496         else return "";
00497     }
00498     
00499     final static float dash1[] = {10.0f};
00500     
00501     final static BasicStroke dashed = new BasicStroke(1.0f, 
00502                                           BasicStroke.CAP_BUTT, 
00503                                           BasicStroke.JOIN_MITER, 
00504                                           10.0f, dash1, 0.0f);
00505 
00506     public String ReadApplet(){
00507        Symbols symbols=new Symbols();
00508        String reply=input.getText();
00509        reply=replace(reply,"\u2217","*");
00510        String con=reply;
00511        for(int s=0;s<10;s++){
00512            con=replace(con,"+-","-");
00513            con=replace(con,"-+","-");
00514            con=replace(con,"--","+");
00515            con=replace(con,"++","+");
00516        }
00517        String tmp[]=con.split("=");
00518        // answer must be: 123 - 23 = 100 ...so a single = sign is expected
00519        double r1=0.0;double r2=1.0;boolean answer = false;
00520        if(tmp.length < 2){
00521            reply="error \n"+rem3;input.setText(rem3);
00522        }
00523        else
00524        {
00525            if(tmp.length > 2){
00526               reply="error \n"+rem1;input.setText(rem1);
00527            }
00528            else
00529            {
00530               String tmp0=tmp[0];// trouble with +5-4=+1
00531               String tmp1=tmp[1];
00532               if(tmp0.charAt(0)=='+'){tmp0=tmp0.substring(1,tmp0.length());}
00533               if(tmp1.charAt(0)=='+'){tmp1=tmp1.substring(1,tmp1.length());}
00534               try { r1=symbols.eval(tmp0);} catch (SyntaxException e) {input.setText(rem2);reply="error \n"+rem2;} 
00535               try { r2=symbols.eval(tmp1);} catch (SyntaxException e) {input.setText(rem2);reply="error \n"+rem2;}
00536               if(r1 == r2){ answer = true;}else{ answer = false;}
00537            }
00538        }
00539        return answer+","+reply;
00540     }
00541     
00542     public double[] GrowArray(double array[], int newlength ,int oldlength){
00543        double[] grow;
00544        grow = new double[ newlength ];
00545        for(int i=0; i < oldlength; i++){
00546            grow[i] = array[i];
00547            //System.out.println("grow[p]="+grow[i]);
00548        }
00549        return grow;
00550     }    
00551     public void start(){}
00552     
00553     public void stop(){}
00554 
00555     public void run(){}
00556        
00557 }
00558