import java.applet.Applet; import java.awt.*; import java.util.*; public class graph extends Applet { char calc[] = new char[100]; char stack[] = new char[100]; double stackg[] = new double[100]; int i,pt,pos,po,fj; int pr[] = new int[100]; int wid=600,hei=500,bai=50; Graphics g; String st; TextField tx; List L; Button del; int nPoint = 0; Vector vGraphx = new Vector(); Vector vGraphy = new Vector(); public void init() { Panel p = new Panel(); Panel p2 = new Panel(); tx = new TextField("",50); L = new List(); del = new Button("全て削除"); setBackground(new Color(255,255,255)); setLayout(new BorderLayout()); p.setLayout(new BorderLayout()); p.add("Center",tx); p.add("South",L); p.add("East",del); p.add("West",new Label("y=")); p2.add(new Button("拡大")); p2.add(new Button("縮小")); add("South",p); add("North",p2); g = getGraphics(); } public void paint(Graphics g) { int i,di,cnt; String buf; g.translate(wid/2,hei/2); g.drawLine(-wid/2,0,wid/2,0); g.drawLine(0,hei/2,0,-hei/2); g.drawString("0",-10,15); g.drawString("x",wid/2-15,-10); g.drawString("y",10,-hei/2+35); for (int iCnt = -(int)wid/bai;iCnt <= (int)wid/bai;iCnt++) { if (iCnt == 0) iCnt++; di=iCnt*bai; buf=String.valueOf(iCnt); g.drawString(buf,di-10,15); g.drawString(buf,-15,-di+15); g.drawLine(di,-5,di,5); g.drawLine(-5,di,5,di); } for (int iCnt = 0;iCnt < vGraphx.size();iCnt++) { drawGraph(iCnt); } } public void ferr() { fj = -1; } public void push(char x,int y) { stack[pos] = x; pr[++pos] = y; } public char pop() { if (pos <= 0) { showStatus("1.演算子の数が正しくありません。"); pos = 0; ferr(); return 0; } return stack[--pos]; } public void addc(char z) { calc[pt++] = z; } public void white() { calc[pt++] = ' '; } public double chk() { return pr[pos]; } public void pushg(double x) { stackg[po++] = x; } public double popg() { if (po <= 0) { showStatus("2.演算子の数が正しくありません。"); po = 0; ferr(); return 0; } return stackg[--po]; } public double faci(double n) { double result = 1; if (n < 0) return 0; else if (n >= 0 && n <= 1) return 1; for (int e = 2;e <= n;e++) result *= e; return result; } public double log10(double i) { return Math.log(i)/Math.log(10); } public void Graph(String st) { int len,s,bx=-100,b=-100; char a; char op[] = new char[100]; g = getGraphics(); g.translate(wid/2,hei/2); st = st.substring(2); len = st.length(); pos = pt = 0; pr[0] = 20; Vector vCoorx = new Vector(); Vector vCoory = new Vector(); nPoint = 0; for (i = 0;i < len;i++) { a = st.charAt(i); switch (a) { case '(': case '{': case '[': if (b == i) { white(); if (5 >= chk()) { while(5 >= chk()) addc(pop()); } push('*',5); } push(a,10); bx = i+1; break; case ')': white(); while (stack[--pos] != '(') { pos++; addc(pop()); if (pos <= 0) { showStatus("カッコの数があっていません。"); ferr(); return; } } pos++; pop(); b = i+1; break; case '}': white(); while (stack[--pos] != '{') { pos++; addc(pop()); if (pos <= 0) { showStatus("カッコの数があっていません。"); ferr(); return; } } pos++; pop(); b = i+1; break; case ']': white(); while (stack[--pos] != '[') { pos++; addc(pop()); if (pos <= 0) { showStatus("カッコの数があっていません。"); ferr(); return; } } pos++; pop(); b = i+1; break; case '+': case '-': if (i == 0 || bx == i) { addc('0'); white(); push(a,3); break; } white(); if (8 >= chk()) { while (8 >= chk()) addc(pop()); } push(a,8); bx = i+1; break; case '*': case '・': case '/': white(); if (5 >=chk()) { while (5 >= chk()) addc(pop()); } push(a,5); bx = i+1; break; case '^': white(); if (2 >= chk()) { while (2 >= chk()) addc(pop()); } push(a,2); bx = i+1; break; default: if (a >= 'a' && a <= 'w' || a == 'z') { white(); op[0] = a; s = 1; if (b == i) { white(); if (5 >= chk()) { while (5 >= chk()) addc(pop()); } push('*',5); } while ((a=st.charAt(++i)) >= 'a' && a <= 'w' || a == 'z') { op[s] = a; s++; } a = st.charAt(--i); op[s] = 0; String ops = new String(op); ops = ops.substring(0,s); if (ops.equals("root")) push('r',7); else if (ops.equalsIgnoreCase("abs")) push('b',7); else if (ops.equalsIgnoreCase("sin")) push('s',7); else if (ops.equalsIgnoreCase("sinh")) push('S',7); else if (ops.equalsIgnoreCase("asin")) push('a',7); else if (ops.equalsIgnoreCase("cos")) push('c',7); else if (ops.equalsIgnoreCase("cosh")) push('C',7); else if (ops.equalsIgnoreCase("acos")) push('A',7); else if (ops.equalsIgnoreCase("tan")) push('t',7); else if (ops.equalsIgnoreCase("tanh")) push('T',7); else if (ops.equalsIgnoreCase("atan")) push('X',7); else if (ops.equalsIgnoreCase("e")) push('e',7); else if (ops.equalsIgnoreCase("log")) push('l',7); else if (ops.equalsIgnoreCase("ln")) push('L',7); else if (ops.equalsIgnoreCase("pi")){ b = i+1; addc('p'); } else { showStatus("未定義の文字列があります。"); ferr(); return; } for (int e = 0;e < 100;e++) op[e] = ' '; } //if else if (a >= '0' && a <='9') { b = i+1; addc(a); } else if (a == 'x' || a == 'X') { if (b == i) { white(); if (5 >= chk()) { while(5 >=chk()) addc(pop()); } push('*',5); } b = i+1; addc('x'); } else if (a == 'y' || a == 'Y') { showStatus("yは使用しないでください。"); ferr(); return; } else if (a == '.' || a == '!') addc(a); else if (a == ' ') { bx++; b++; } else { showStatus("計算できない文字が含まれています。半角で式を入力してください。"); ferr(); return; } } //switch if (fj == -1) return; } //for if (pos > 0) { while (pos > 0) { addc(pop()); if (stack[pos] == '(') { showStatus("カッコの数があっていません。"); ferr(); return; } } } if (fj == -1) return; int dd,j,jj; char c; double m,x,y,dx,dy; dx = dy = jj = 0; for (m = -wid/bai;m <= wid/bai;m += 0.01) { po = 0; for (j = 0;j < pt;j++) { double x1,x2; c = calc[j]; if (c >= '0' && c <= '9') { x1 = c-'0'; while ((c = calc[++j]) >= '0' && c <= '9') x1 = 10*x1+(c-'0'); if (c == '.'){ x2 = 1.0; while ((c = calc[++j]) >= '0' && c <= '9') { x2 = x2/10.0; x1 = x1+x2*(c-'0'); } } pushg(x1); c = calc[--j]; } switch (c) { case '+': pushg(popg()+popg()); break; case '-': x1 = popg(); pushg(popg()-x1); break; case '*': pushg(popg()*popg()); break; case '/': x1 = popg(); if (x1 != 0.0) pushg(popg()/x1); else{ showStatus("0では割れません。"); ferr(); return; } break; case '^': x1 = popg(); pushg(Math.pow(popg(),x1)); break; case '!': pushg(faci(popg())); break; case 'x': pushg(m); break; case 'r': x1 = popg(); fj = 0; if (x1 < 0.0) { fj = -2; jj = 0; break; } pushg(Math.sqrt(x1)); break; case 'b': pushg(Math.abs(popg())); break; case 's': pushg(Math.sin(popg())); break; case 'S': x1 = popg(); pushg((Math.exp(x1)-Math.exp(-x1))/2); break; case 'a': pushg(Math.asin(popg())); break; case 'c': pushg(Math.cos(popg())); break; case 'C': x1 = popg(); pushg((Math.exp(x1)+Math.exp(-x1))/2); break; case 'A': pushg(Math.acos(popg())); break; case 't': pushg(Math.tan(popg())); break; case 'T': x1 = popg(); pushg((Math.exp(x1)-Math.exp(-x1))/(Math.exp(x1)+Math.exp(-x1))); break; case 'X': pushg(Math.atan(popg())); break; case 'e': pushg(Math.exp(popg())); break; case 'l': pushg(log10(popg())); break; case 'L': pushg(Math.log(popg())); break; case 'p': pushg(3.1415926535897932385); break; } if (fj == -1) return; } //for if (fj != -2) { x = m; y = popg(); if (y > 299) y = 299; else if (y < -299) y = -299; x = x*bai; y = -y*bai; if (y > 100*bai && (dy < -100*bai || dy == 0) || y < -100*bai && (dy > 100*bai || dy == 0)) { Integer dbx = new Integer((int)x); Integer dby = new Integer((int)y); vCoorx.addElement(dbx); vCoory.addElement(dby); } else { if (jj != 0) { Integer dbx = new Integer((int)x); Integer dby = new Integer((int)y); vCoorx.addElement(dbx); vCoory.addElement(dby); nPoint++; } jj++; } dx = x; dy = y; } } //for for (i = 0;i < 100;i++) { calc[i] = ' '; stack[i] = ' '; pr[i] = ' '; stackg[i] = ' '; } vGraphx.addElement(vCoorx); vGraphy.addElement(vCoory); } //Graph public boolean action(Event e,Object o) { String buf = ""; if (e.target instanceof TextField) { st = (String)o; st = st.toLowerCase(); if (st.length() != 0) { fj = 0; st = "y="+st; Graph(st); if (fj == 0) { L.addItem(st); tx.setText(""); st = ""; } } } else if (e.target instanceof Button) { Button b = (Button)e.target; if ("全て削除".equals(b.getLabel())) { L.clear(); tx.setText(""); vGraphx.removeAllElements(); vGraphy.removeAllElements(); } else if ("拡大".equals(b.getLabel())) { if (bai < 100) { bai += 10; vGraphx.removeAllElements(); vGraphy.removeAllElements(); for (int iCnt = 0;iCnt < L.getItemCount();iCnt++) { buf=L.getItem(iCnt); Graph(buf); } } else return true; } else if ("縮小".equals(b.getLabel())) { if (bai > 20) { bai -= 10; vGraphx.removeAllElements(); vGraphy.removeAllElements(); for (int iCnt = 0;iCnt < L.getItemCount();iCnt++) { buf=L.getItem(iCnt); Graph(buf); } } else return true; } } repaint(); return true; } public void drawGraph(int i) { int xPoint[] = new int[nPoint]; int yPoint[] = new int[nPoint]; Integer ix,iy; Vector vCoorx = (Vector)vGraphx.elementAt(i); Vector vCoory = (Vector)vGraphy.elementAt(i); for (int ipos = 0;ipos < nPoint;ipos++) { ix = (Integer)vCoorx.elementAt(ipos); iy = (Integer)vCoory.elementAt(ipos); xPoint[ipos] = ix.intValue(); yPoint[ipos] = iy.intValue(); } g = getGraphics(); g.translate(wid/2,hei/2); g.drawPolyline(xPoint,yPoint,nPoint); } }