/** 数学のグラフを描くのに便利なパッケージを作ってみました。 *  これを使うとJavaの座標を考えずに *  数学の座標だけを考えてグラフを描く事ができます。 * *  名前は気にしないで下さい。自己満足の世界です。 * * 関数の数には満足のいく物がありますが、等高線を描くメソッドを * 作れなかったことを大変悔やみます。もう少し考える時間があれば * 何とかなったかもしれないのがつらいです。 * * * メッソド一覧 現在16個 privateなメソッドは入っていません。 * 共通のメソッド * setGraphics,setColor * 二次元グラフのメッソド * set,move,draw * 三次元グラフのメソッド * set2,move2,draw2,changeAng,changePosi,changeSize, * changeReflect,drawBirdView,fillBirdView,hideBirdView,drawHideView * * このプログラムではMitsuiWorldをパッケージとして扱っています。 * もしこのままパッケージとして使いたいならMitsuiというディレクトリを作り * そのなかにこのMitsuiWorldのファイルをいれ、そこでこのファイルを * コンパイルします。 * * 使い方はMitsuiWorldを使うプログラムと同じディレクトリ内に上で作った * Mitsuiディレクトリを置きます。 * 例えばc:/usr/home% というディレクトリにMitsuiWorldを使うWave.java * があったとするとMitsuiディレクトリをhomeディレクトリにおき、 * Wave.javaの初めに必ず * import Mitsui.*; * と書きます。 * これで普通どうりにjavac Wave.javaとするとコンパイルできます。 */ package Mitsui; import java.awt.*; public class MitsuiWorld_2{ //Javaの座標 private int current_x, current_y, next_x, next_y; //仮のZ座標 private double next_z; //[a,b]x軸 [c,d]y軸 [e,f]z軸 private double xmin, xmax, ymin, ymax, zmin, zmax; //グラフの高さと幅 private int h, w; //カラー private Color color; //グラフ private Graphics g,gg; //角度を変える private double angX=0,angY=0; //場所を変える private int p_x=0,p_y=0; //三次元グラフの大きさ private int dlx=0,dly=0,dlz=0; //透視投影のサイズ private double s=400,d=500; //このZBに全ての点でのz座標が格納される private float[][] ZB; //このBUにZBと比較するz座標が格納される private float[][] BU; //色を変更する private Color[] col={Color.black,Color.white,Color.blue,Color.red, Color.yellow,Color.green,Color.darkGray,Color.gray, Color.lightGray,Color.pink,Color.orange, Color.magenta,Color.cyan}; //Graphicsをセットするメソッド。 public void setGraphics(Graphics g){ this.g = g; } //描写画面のサイズのセットをするメソッド。 public void setScreenSize(int width,int height){ w = width; h = height; } //色をセットするメソッド。 public void setColor(Color col){ color = col; g.setColor(color); } //色をセットするメソッドパート2 番号指定 public void setColor(int c){ if(c>12) c=0; color = col[c]; g.setColor(color); } //出力画面を[a,b]×[c,d]にするメソッド。 public void setArea(double a,double b,double c,double d){ xmin = a; xmax = b; ymin = c; ymax = d; } //ポイントを[X,Y]にもっていくメソッド。 public void move(double x,double y){ next_x = (int)((x-xmin)*w/(xmax-xmin)); next_y = (int)((ymax-y)*h/(ymax-ymin)); } //[X,Y]まで線を引くメソッド。 public void draw(double x,double y){ current_x = next_x; current_y = next_y; move(x,y); g.drawLine(current_x,current_y,next_x,next_y); } //出力画面を[a,b]×[c,d]×[e,f]にするメソッド。(x軸×y軸×z軸) //枠も一緒に作成しています。 public void setArea2(double a,double b,double c, double d,double e,double f){ xmin = a; xmax = b; ymin = c; ymax = d; zmin = e; zmax = f; drawAxis2(); } //枠の作成*******************************************private private void drawAxis2(){ g.setColor(Color.black); move2(xmin,ymin,zmin);draw2(xmax,ymin,zmin); draw2(xmax,ymax,zmin);draw2(xmin,ymax,zmin); draw2(xmin,ymin,zmin);draw2(xmin,ymin,zmax); move2(xmax,ymin,zmin);draw2(xmax,ymin,zmax); move2(xmax,ymax,zmin);draw2(xmax,ymax,zmax); move2(xmin,ymax,zmin);draw2(xmin,ymax,zmax); g.setColor(color); } //(x,y,z)にポイントを移動する。 public void move2(double x,double y,double z){ //数学座標をそのままJava座標に変換したものをいれる変数 int jx,jy,jz; //jx,jy,jzから求められる3次元対応に変換したものを入れる変数 double x1,y1,z1,z0; //枠の長さ int lx = w/2 + dlx; int ly = w/2 + dly; int lz = 3*h/10 + dlz; //数学の座標からjavaの座標に変換 jx = (int)((x-xmin)*lx/(xmax-xmin)); jy = (int)((z-zmin)*lz/(zmax-zmin)); jz = (int)((y-ymin)*ly/(ymax-ymin)); //座標の位置(原点) int x0 = 5*w/12 + p_x; int y0 = h/2 - p_y; //座標の視覚 double RAD = Math.PI/180.0; //角度をラジアンに直している double baseAngY = 20.0*RAD; double baseAngX = -35.0*RAD; //視覚の角度 double angx = baseAngX + angX*RAD; double angy = baseAngY + angY*RAD; //Math.Math.と書くのがめんどくさいしこの方がきれいに書ける double cosY = Math.cos(angy); double sinY = Math.sin(angy); double sinX = Math.sin(angx); double cosX = Math.cos(angx); //3D対応の変換 x1 = jx*cosX+jz*sinX; z0 = -jx*sinX+jz*cosX; y1 = jy*cosY-z0*sinY; z1 = jy*sinY+z0*cosY; x1 = s/(d-z1)*x1; //透視投影 y1 = s/(d-z1)*y1; //透視投影 next_x=x0+(int)Math.rint(x1); next_y=y0-(int)Math.rint(y1); next_z=z1; } //三次元グラフの角度を変えるメソッド public void changeAngle(double x,double y){ angX = x; angY = y; } //三次元グラフの位置を変えるメソッド public void changePosition(int x,int y){ p_x = x; p_y = y; } //三次元グラフの大きさを変える。 public void changeSize(int x,int y,int z){ dlx=x; dly=y; dlz=z; } //透視投影のサイズを変える。 public void changeReflect(int s,int d){ this.s=s; this.d=d; } //線を描くメソッド public void draw2(double x,double y,double z){ current_x=next_x; current_y=next_y; move2(x,y,z); g.drawLine(current_x,current_y,next_x,next_y); } //バードビュウで見るメソッド public void drawBirdView(double u[][],int nx,int ny,int h){ double x,y; double dx = (xmax-xmin)/nx; double dy = (ymax-ymin)/ny; for(int i=0;i<=nx;i+=h){ x = xmin + i * dx; move2(x,ymin,u[i][0]); for(int j=0;j<=ny;j++){ y = ymin + j * dy; draw2(x,y,u[i][j]); } } for(int j=0;j<=ny;j+=h){ y = ymin + j * dy; move2(xmin,y,u[0][j]); for(int i=0;i<=nx;i++){ x = xmin + i * dx; draw2(x,y,u[i][j]); } } drawAxis2(); } //色つきバードビュウ public void fillBirdView(double u[][],int nx,int ny,int h){ double x,y; double dx = (xmax-xmin)/nx; double dy = (ymax-ymin)/ny; int[] polyx = new int[4]; int[] polyy = new int[4]; //最小の四角形を片っ端から求めていく for(int i=0;iXMAX) XMAX=X[i]; if(X[i]YMAX) YMAX=Y[i]; if(Y[i] ZB[x][y]){ ZB[x][y] = BU[x][y]; g.setColor(Color.black); g.drawLine(x,y,x,y); g.setColor(color); } } } //この部分で四角形(多角形)の内部のZ座標を決める for(int y=YMIN+1;yXMIN;xe--){ if(BU[xe][y] != -9999){ //終了位置を探す for(int xs=XMIN;xs ZB[x][y]){ ZB[x][y] = BU[x][y]; g.drawLine(x,y,x,y); } } } } }