// // diffeq.java // diffeq // // Created by me on Sun Apr 13 2003. // Copyright (c) 2003 __MyCompanyName__. All rights reserved. // A simple Java applet // import java.awt.*; import java.applet.*; import java.awt.event.*; public class diffeq extends Applet { double delta_t=0.001; // delta t double delta_xy=1.0E-10; // regard the point is fixed if move is less than delta_xy long count; long maxCount=10000; //Stop plot after 10,000 th iterations double x0=-10.0, y0=-10.0, x1=10.0, y1=10.0; //coord of left-top and right-bottom points // double a=3.0, b=1.0, m=0.5, c=4.0, d=1.0, n=1.0; //coefficients of diff. eq. double a1=-1.0, h1=-0.5, b1=0.0, p1=3.0, q1=0.0, r1=0.0; //coefficients of diff. eq. double a2=0.0, h2=-1.0, b2=-1.0, p2=0.0, q2=4.0, r2=0.0; //coefficients of diff. eq. double xpressed, ypressed, xreleased, yreleased; boolean dragging=false; Label label1_1, label1_2; Label label2_1, label2_2; Label label31, label32; Label label41, label42; Label label51, label52; Label label61, label62; Label label71, label72; Label label81, label82; Label label7; Label label8; Label label9; Label label10; Label label11; Label label12; Label label13; Label label14; TextField a1Text, a2Text; TextField h1Text, h2Text; TextField b1Text, b2Text; TextField p1Text, p2Text; TextField q1Text, q2Text; TextField r1Text, r2Text; TextField x0Text; TextField y0Text; TextField x1Text; TextField y1Text; TextField xText; TextField yText; Button set_a_B; Button set_x_B; Button zoom_B; // Button show_fp_B; nCanvas plane; class vec{ public double x; public double y; vec(double xval, double yval){ x=xval; y=yval; } } public void paint(Graphics gtmp){ int red_xPoints[]={135,135,145}; int red_yPoints[]={67,73,70}; int blue_xPoints[]={175,175,185}; int blue_yPoints[]={67,73,70}; gtmp.setColor(Color.red); gtmp.drawLine(120,70,160,70); gtmp.fillPolygon(red_xPoints,red_yPoints,3); gtmp.setColor(Color.blue); gtmp.drawLine(160,70,200,70); gtmp.fillPolygon(blue_xPoints,blue_yPoints,3); } public void init() { setLayout(null); resize(640,440); setBackground(Color.lightGray); label1_1 = new Label("x' = a1 x^2 + h1 xy + b1 y^2"); label1_2 = new Label("+ p1 x + q1 y + r1"); label1_1.reshape(5,2,200,15); label1_2.reshape(30,18,200,15); add(label1_1); add(label1_2); label2_1 = new Label("y' = a2 x^2 + h2 xy + b2 y^2"); label2_2 = new Label("+ p2 x + q2 y + r2"); label2_1.reshape( 5, 34,200,15); label2_2.reshape(30,50,200,15); add(label2_1); add(label2_2); // a1 label31 = new Label("a1"); label31.reshape(20,80,25,15); add(label31); a1Text = new TextField(); a1Text.setText(String.valueOf(a1)); a1Text.reshape(50,80,55,15); a1Text.setBackground(Color.white); add(a1Text); // h1 label41 = new Label("h1"); label41.reshape(20,100,25,15); add(label41); h1Text = new TextField(); h1Text.setText(String.valueOf(h1)); h1Text.reshape(50,100,55,15); h1Text.setBackground(Color.white); add(h1Text); // b1 label51 = new Label("b1"); label51.reshape(20,120,25,15); add(label51); b1Text = new TextField(); b1Text.setText(String.valueOf(b1)); b1Text.reshape(50,120,55,15); b1Text.setBackground(Color.white); add(b1Text); // p1 label61 = new Label("p1"); label61.reshape(20,140,25,15); add(label61); p1Text = new TextField(); p1Text.setText(String.valueOf(p1)); p1Text.reshape(50,140,55,15); p1Text.setBackground(Color.white); add(p1Text); // q1 label71 = new Label("q1"); label71.reshape(20,160,25,15); add(label71); q1Text = new TextField(); q1Text.setText(String.valueOf(q1)); q1Text.reshape(50,160,55,15); q1Text.setBackground(Color.white); add(q1Text); // r1 label81 = new Label("r1"); label81.reshape(20,180,25,15); add(label81); r1Text = new TextField(); r1Text.setText(String.valueOf(r1)); r1Text.reshape(50,180,55,15); r1Text.setBackground(Color.white); add(r1Text); // a2 label32 = new Label("a2"); label32.reshape(115,80,25,15); add(label32); a2Text = new TextField(); a2Text.setText(String.valueOf(a2)); a2Text.reshape(145,80,55,15); a2Text.setBackground(Color.white); add(a2Text); // h2 label42 = new Label("h2"); label42.reshape(115,100,25,15); add(label42); h2Text = new TextField(); h2Text.setText(String.valueOf(h2)); h2Text.reshape(145,100,55,15); h2Text.setBackground(Color.white); add(h2Text); // b2 label52 = new Label("b2"); label52.reshape(115,120,25,15); add(label52); b2Text = new TextField(); b2Text.setText(String.valueOf(b2)); b2Text.reshape(145,120,55,15); b2Text.setBackground(Color.white); add(b2Text); // p2 label62 = new Label("p2"); label62.reshape(115,140,25,15); add(label62); p2Text = new TextField(); p2Text.setText(String.valueOf(p2)); p2Text.reshape(145,140,55,15); p2Text.setBackground(Color.white); add(p2Text); // q2 label72 = new Label("q2"); label72.reshape(115,160,25,15); add(label72); q2Text = new TextField(); q2Text.setText(String.valueOf(q2)); q2Text.reshape(145,160,55,15); q2Text.setBackground(Color.white); add(q2Text); // r2 label82 = new Label("r2"); label82.reshape(115,180,25,15); add(label82); r2Text = new TextField(); r2Text.setText(String.valueOf(r2)); r2Text.reshape(145,180,55,15); r2Text.setBackground(Color.white); add(r2Text); //set_a_B set_a_B = new Button("set a,h,c,.."); set_a_B.reshape(100,205,100,20); set_a_B.addMouseListener(new set_a_ma()); add(set_a_B); label7 = new Label("x0"); label7.reshape(20,240,30,15); add(label7); x0Text = new TextField(); x0Text.setText(String.valueOf(x0)); x0Text.reshape(50,240,150,15); x0Text.setBackground(Color.white); add(x0Text); label8 = new Label("y0"); label8.reshape(20,260,30,15); add(label8); y0Text = new TextField(); y0Text.setText(String.valueOf(y0)); y0Text.reshape(50,260,150,15); y0Text.setBackground(Color.white); add(y0Text); label9 = new Label("x1"); label9.reshape(20,280,30,15); add(label9); x1Text = new TextField(); x1Text.setText(String.valueOf(x1)); x1Text.reshape(50,280,150,15); x1Text.setBackground(Color.white); add(x1Text); label10 = new Label("y1"); label10.reshape(20,300,30,15); add(label10); y1Text = new TextField(); y1Text.setText(String.valueOf(y1)); y1Text.reshape(50,300,150,15); y1Text.setBackground(Color.white); add(y1Text); //set_x_B set_x_B = new Button("set x's & y's"); set_x_B.reshape(100,325,100,20); set_x_B.addMouseListener(new set_x_ma()); add(set_x_B); //zoom_B zoom_B = new Button("zoom out"); zoom_B.reshape(100,350,100,20); zoom_B.addMouseListener(new zoom_ma()); add(zoom_B); /* //show_fp_B show_fp_B = new Button("show fixed pt"); show_fp_B.reshape(100,345,100,20); //set_a_B.addMouseListener(new clear_ma()); add(show_fp_B); */ // x, y label11 = new Label("x"); label11.reshape(20,380,30,15); add(label11); xText = new TextField(); xText.setText(""); xText.reshape(50,380,150,15); xText.setBackground(Color.white); add(xText); label12 = new Label("y"); label12.reshape(20,400,30,15); add(label12); yText = new TextField(); yText.setText(""); yText.reshape(50,400,150,15); yText.setBackground(Color.white); add(yText); //canvas plane = new nCanvas(); plane.reshape(220,20,400,400); plane.setBackground(Color.white); plane.addMouseMotionListener(new plane_mma()); plane.addMouseListener(new plane_ma()); add(plane); plane.makeBuffer(); plane.screen(x0,y0,x1,y1); plane.eraseBuff(); //draw axis drawAxis(); } /////////// EVENT HANDLERS // MouseAdapter for set_a button class set_a_ma extends MouseAdapter{ public void mouseClicked(MouseEvent e){ set_a_B_Clicked(); } } void set_a_B_Clicked() { get_a(); plane.eraseBuff(); drawAxis(); } // MouseAdapter for set_x button class set_x_ma extends MouseAdapter{ public void mouseClicked(MouseEvent e){ set_x_B_Clicked(); } } void set_x_B_Clicked() { get_x(); plane.screen(x0,y0,x1,y1); plane.eraseBuff(); drawAxis(); } // MouseAdapter for zoom button class zoom_ma extends MouseAdapter{ public void mouseClicked(MouseEvent e){ zoom_B_Clicked(); } } void zoom_B_Clicked() { double xc,yc,wx,wy; xc=(x0+x1)/2; yc=(y0+y1)/2; wx=x1-x0; wy=y1-y0; x0=xc-wx; x1=xc+wx; y0=yc-wy; y1=yc+wy; x0Text.setText(String.valueOf(x0)); x1Text.setText(String.valueOf(x1)); y0Text.setText(String.valueOf(y0)); y1Text.setText(String.valueOf(y1)); plane.screen(x0,y0,x1,y1); plane.eraseBuff(); drawAxis(); } // MouseAdapter for plane class plane_ma extends MouseAdapter{ public void mousePressed(MouseEvent e){ plane_MousePressed(e); } public void mouseReleased(MouseEvent e){ plane_MouseReleased(e); } } void plane_MousePressed(MouseEvent event) { xpressed=plane.eventRX(event); ypressed=plane.eventRY(event); } void plane_MouseReleased(MouseEvent event) { plane.update(plane.getGraphics()); xreleased=plane.eventRX(event); yreleased=plane.eventRY(event); if(dragging){ // zoom in double xmin, ymin, xmax, ymax; xmin=Math.min(xpressed, xreleased); ymin=Math.min(ypressed, yreleased); xmax=Math.max(xpressed, xreleased); ymax=Math.max(ypressed, yreleased); set_x(xmin, ymin, xmax, ymax); dragging=false; } else { // draw orbit drawOrbit(xreleased, yreleased); } } //MouseMotionAdapter for plane class plane_mma extends MouseMotionAdapter{ public void mouseMoved(MouseEvent e){ plane_MouseMoved(e); } public void mouseDragged(MouseEvent e){ plane_MouseDragged(e); } } void plane_MouseMoved(MouseEvent event){ // show small green disk and write the coord of pointer double xtmp,ytmp; plane.update(plane.getGraphics()); xtmp=plane.eventRX(event); ytmp=plane.eventRY(event); plane.setForeground(Color.green); plane.drawMarkTemp(xtmp,ytmp); xText.setText(String.valueOf(xtmp)); yText.setText(String.valueOf(ytmp)); } void plane_MouseDragged(MouseEvent event) { double xtmp,ytmp; int xi0,yi0,xi1,yi1; int xd,yd; Graphics gtmp=plane.getGraphics(); dragging=true; plane_MouseMoved(event); // write the coord of pointer xtmp=plane.eventRX(event); ytmp=plane.eventRY(event); xi0=plane.xInt(xpressed); xi1=plane.xInt(xtmp); yi0=plane.yInt(ypressed); yi1=plane.yInt(ytmp); xd=Math.abs(xi1-xi0); yd=Math.abs(yi1-yi0); xi0=Math.min(xi0,xi1); yi0=Math.min(yi0,yi1); plane.repaint(); gtmp.setColor(Color.green); gtmp.drawRect(xi0,yi0,xd,yd); } // draw axis public void drawAxis(){ plane.setForeground(Color.green); plane.drawLine(x0, 0.0 , x1 ,0.0); plane.drawLine(0.0, y0 , 0.0 , y1); } void getNumbers(){ // get a,... and x0,... get_a(); get_x(); } void get_a(){ //get a,b,c,d try{ a1=Double.valueOf(a1Text.getText()).doubleValue(); }catch(NumberFormatException e){ a1Text.setText(String.valueOf(a1)); }; try{ a2=Double.valueOf(a2Text.getText()).doubleValue(); }catch(NumberFormatException e){ a2Text.setText(String.valueOf(a2)); }; try{ h1=Double.valueOf(h1Text.getText()).doubleValue(); }catch(NumberFormatException e){ h1Text.setText(String.valueOf(h1)); }; try{ h2=Double.valueOf(h2Text.getText()).doubleValue(); }catch(NumberFormatException e){ h2Text.setText(String.valueOf(h2)); }; try{ b1=Double.valueOf(b1Text.getText()).doubleValue(); }catch(NumberFormatException e){ b1Text.setText(String.valueOf(b1)); }; try{ b2=Double.valueOf(b2Text.getText()).doubleValue(); }catch(NumberFormatException e){ b2Text.setText(String.valueOf(b2)); }; try{ p1=Double.valueOf(p1Text.getText()).doubleValue(); }catch(NumberFormatException e){ p1Text.setText(String.valueOf(p1)); }; try{ p2=Double.valueOf(p2Text.getText()).doubleValue(); }catch(NumberFormatException e){ p2Text.setText(String.valueOf(p2)); }; try{ q1=Double.valueOf(q1Text.getText()).doubleValue(); }catch(NumberFormatException e){ q1Text.setText(String.valueOf(q1)); }; try{ q2=Double.valueOf(q2Text.getText()).doubleValue(); }catch(NumberFormatException e){ q2Text.setText(String.valueOf(q2)); }; try{ r1=Double.valueOf(r1Text.getText()).doubleValue(); }catch(NumberFormatException e){ r1Text.setText(String.valueOf(r1)); }; try{ r2=Double.valueOf(r2Text.getText()).doubleValue(); }catch(NumberFormatException e){ r2Text.setText(String.valueOf(r2)); }; } void get_x(){ //get x0,y0,x1,y1 try{ x0=Double.valueOf(x0Text.getText()).doubleValue(); }catch(NumberFormatException e){ x0Text.setText(String.valueOf(x0)); }; try{ y0=Double.valueOf(y0Text.getText()).doubleValue(); }catch(NumberFormatException e){ y0Text.setText(String.valueOf(y0)); }; try{ x1=Double.valueOf(x1Text.getText()).doubleValue(); }catch(NumberFormatException e){ x1Text.setText(String.valueOf(x1)); }; try{ y1=Double.valueOf(y1Text.getText()).doubleValue(); }catch(NumberFormatException e){ y1Text.setText(String.valueOf(y1)); }; } void set_x(double xmin, double ymin, double xmax, double ymax){ //set text field x0Text.setText(String.valueOf(xmin)); y0Text.setText(String.valueOf(ymin)); x1Text.setText(String.valueOf(xmax)); y1Text.setText(String.valueOf(ymax)); } //Draw orbit through (xgiven,ygiven) void drawOrbit(double xgiven, double ygiven){ double x,y, xnew,ynew; vec v = new vec(0.0,0.0); // draw FORWARD orbit in BLUE x=xgiven; y=ygiven; plane.setForeground(Color.blue); count=0; while(true){ plane.drawPoint(x,y); //xnew=next_x(x,y,delta_t); //ynew=next_y(x,y,delta_t); v=next_xy(x,y,delta_t); xnew=v.x; ynew=v.y; if(x<=x0 || x>=x1 || y<=y0 || y>=y1) break; if(Math.abs(xnew-x)maxCount) break; x=xnew; y=ynew; } // draw BACKWORD orbit in RED x=xgiven; y=ygiven; plane.setForeground(Color.red); count=0; while(true){ plane.drawPoint(x,y); //xnew=next_x(x,y,-delta_t); //ynew=next_y(x,y,-delta_t); v=next_xy(x,y,-delta_t); xnew=v.x; ynew=v.y; if(x<=x0 || x>=x1 || y<=y0 || y>=y1) break; if(Math.abs(xnew-x)maxCount) break; x=xnew; y=ynew; } } // get next x and y by EULER METHOD public double next_x(double x, double y, double dt){ double xnew; xnew=x+f(x,y)*dt; return(xnew); } public double next_y(double x, double y, double dt){ double ynew; ynew=y+g(x,y)*dt; return(ynew); } // get next x and y as a vector by RUNGE-KUTTA METHOD public vec next_xy(double x, double y, double dt){ double xnew, ynew; double kx1, kx2, kx3, kx4, ky1, ky2, ky3, ky4; kx1=dt*f(x,y); ky1=dt*g(x,y); kx2=dt*f(x+kx1/2,y+ky1/2); ky2=dt*g(x+kx1/2,y+ky1/2); kx3=dt*f(x+kx2/2,y+ky2/2); ky3=dt*g(x+kx2/2,y+ky2/2); kx4=dt*f(x+kx3,y+ky3); ky4=dt*g(x+kx3,y+ky3); xnew=x+(kx1+2*kx2+2*kx3+kx4)/6; ynew=y+(ky1+2*ky2+2*ky3+ky4)/6; return(new vec(xnew, ynew)); } // dx/dt = f(x,y) public double f(double x, double y){ return(a1*x*x + h1*x*y + b1*y*y + p1*x + q1*y + r1); } // dy/dt = g(x,y) public double g(double x, double y){ return(a2*x*x + h2*x*y + b2*y*y + p2*x + q2*y + r2); } }