📄 machine.java
字号:
rI=(int)(50.0*Math.sqrt((x1-x)*(x1-x)+(y1-y)*(y1-y)));
gs.setColor(Color.green);
gs.drawOval(xI-rI,yI-rI,rI*2,rI*2);
rO=rI;
break;
}
}
}
public void mouseUpThis(Event ev) {
int xIndex,yIndex;
xIndex=ev.x;yIndex=ev.y;
double val,ang,sheetLength;
Double valD= new Double(0.0); //There has to be an easier way to do this!!
Double angD= new Double(0.0);
xO=0;rO=0;
valD=Double.valueOf(root.strength.getText());
angD=Double.valueOf(root.angle.getText());
val=valD.doubleValue();
ang=angD.doubleValue();
ang*=Math.PI/180.;
if(xIndex>=xImin && xIndex<=xImax && yIndex>=yImin && yIndex<=yImax) {
switch (root.options.getSelectedIndex()) {
case 0: //Free stream
freeStreamU=val*Math.cos(ang);
freeStreamV=val*Math.sin(ang);
nst=0;
break;
case 1: //Source
f[nf]=new Sing(x,y,val/Math.PI/2.0,1);
nf++;
nst=0;
break;
case 2: //Vortex
f[nf]=new Sing(x,y,val/Math.PI/2.0,2);
nf++;
nst=0;
break;
case 3: //Doublet
f[nf]=new Sing(x,y,ang,val/Math.PI/2.0,3);
nf++;
nst=0;
break;
case 4: //Source Panel
sheetLength=Math.sqrt((x1-x)*(x1-x)+(y1-y)*(y1-y));
f[nf]=new Sing(x,y,x1,y1,val/Math.PI/2.0,(x1-x)/sheetLength,(y1-y)/sheetLength,4);
nf++;
nst=0;
break;
case 5: //Vortex Panel
sheetLength=Math.sqrt((x1-x)*(x1-x)+(y1-y)*(y1-y));
f[nf]=new Sing(x,y,x1,y1,-val/Math.PI/2.0,(x1-x)/sheetLength,(y1-y)/sheetLength,5);
nf++;
nst=0;
break;
case 6: //Circle
circleOn=true;kuttaOn=false;
circlex=x;circley=y;circler=Math.sqrt((x1-x)*(x1-x)+(y1-y)*(y1-y));
nst=0;
break;
case 7: //Circle with Kutta condition
circleOn=true;kuttaOn=true;kuttat=Math.atan2(y1-y,x1-x);
circlex=x;circley=y;circler=Math.sqrt((x1-x)*(x1-x)+(y1-y)*(y1-y));
nst=0;
break;
case 8: //Add dye
xstream[nst]=x;ystream[nst]=y;nst++;
drawStreamline(x,y);
if(root.map!=null && root.map.isShowing()) root.map.drawing.drawStreamline(x,y);
}
if(root.options.getSelectedIndex()!=8) {
repaint();
if(root.map!=null) {
if(root.map.isShowing()) {
root.map.drawing.repaint();
}
}
}
}
}
void drawStreamline(double xx, double yy) {
double u,v,vmag=0.0,vmag1=0.0,Uinf,xs,ys,xs0,ys0,xs1,ys1,u1,v1,streamStep=.02;
double kuttag=0.0,xr,yr,r2;
int xI,yI,xI1,yI1,uI,uI1,vI,vI1,step,maxStep=1000,SKIP=3;
float hue;
Velocity vel=new Velocity(0.0,0.0);
String s;
Graphics gs;
gs=this.getGraphics();
s="";
xs=xx;ys=yy;
gs.setColor(Color.gray);
xI=(int)Math.round((xs+x0)*50.0)+xImin;
yI=(int)Math.round((y0-ys)*50.0)+yImin;
step=0;
if(kuttaOn) {
vel=totalV(circlex+circler*Math.cos(kuttat),circley+circler*Math.sin(kuttat));
if(vel.inf==true) kuttaOn=false;
else {
if(Math.cos(kuttat)>0.7) kuttag=-circler*vel.v/Math.cos(kuttat);
else kuttag=+circler*vel.u/Math.sin(kuttat);
}
}
while(step++<maxStep && xI<xImax && xI>xImin && yI<yImax && yI>yImin) {
vel=totalV(xs,ys);
u=vel.u;v=vel.v;
if(kuttaOn) {
xr=xs-circlex;yr=ys-circley;r2=xr*xr+yr*yr;
if(r2==0.0) vel.inf=true;
else {
u-=kuttag/r2*yr;
v+=kuttag/r2*xr;
}
}
if(vel.inf==true) break;
vmag = Math.sqrt(Math.abs(u * u + v * v)); //Estimate next point in streamline
if(vmag==0.0) break;
xs1=xs+u/vmag*streamStep;
ys1=ys+v/vmag*streamStep;
vel=totalV(xs1,ys1);
u1=vel.u;v1=vel.v;
if(kuttaOn) {
xr=xs1-circlex;yr=ys1-circley;r2=xr*xr+yr*yr;
if(r2==0.0) vel.inf=true;
else {
u1-=kuttag/r2*yr;
v1+=kuttag/r2*xr;
}
}
if(vel.inf==true) break;
vmag1 = Math.sqrt(Math.abs(u1 * u1 + v1 * v1)); //Re-estimate next point in streamline
if(vmag1==0.0) break;
xs1=xs+(u/vmag+u1/vmag1)*streamStep/2.0;
ys1=ys+(v/vmag+v1/vmag1)*streamStep/2.0;
if(step%SKIP==0) {
xI1=(int)Math.round((xs1+x0)*50.0)+xImin;
yI1=(int)Math.round((y0-ys1)*50.0)+yImin;
if((xI<xImax && xI>xImin && yI<yImax && yI>yImin)&&(xI1<xImax && xI1>xImin && yI1<yImax && yI1>yImin)) {
hue=1.0f-(float)(vmag/2.);
if(hue<0.0f) hue=0.0f;
gs.setColor(Color.getHSBColor(hue,1.0f,1.0f));
gs.drawLine(xI,yI,xI1,yI1);
}
xI=xI1;
yI=yI1;
if(record) s+=fformat(xs)+"\t"+fformat(ys)+"\t"+fformat(u)+"\t"+fformat(v)+"\n";
}
xs=xs1;ys=ys1;
}
if(record) root.out.addData(s);
}
Velocity totalVk(double xs, double ys) {
Velocity vel=new Velocity(0.0,0.0);
double xr,yr,r2;
double kuttag=0.0;
if(kuttaOn) {
vel=totalV(circlex+circler*Math.cos(kuttat),circley+circler*Math.sin(kuttat));
if(vel.inf==true) kuttaOn=false;
else {
if(Math.cos(kuttat)>0.7) kuttag=-circler*vel.v/Math.cos(kuttat);
else kuttag=+circler*vel.u/Math.sin(kuttat);
}
}
vel=totalV(xs,ys);
if(kuttaOn) {
xr=xs-circlex;yr=ys-circley;r2=xr*xr+yr*yr;
if(r2==0.0) vel.inf=true;
else {
vel.u-=kuttag/r2*yr;
vel.v+=kuttag/r2*xr;
}
}
return vel;
}
Velocity totalV(double xs, double ys) {
double mtx,mty,mtu,mtv,mtr2;
Velocity vel=new Velocity(0.0,0.0);
Velocity res=new Velocity(0.0,0.0);
res.u=freeStreamU;res.v=freeStreamV; //Determine velocity vector at current point
for(int i=0;i<nf;i++) {
vel=f[i].V(xs,ys);
res.u+=vel.u;
res.v+=vel.v;
if(vel.inf==true) break;
}
if(vel.inf==true) {res.inf=true;return res;}
if(circleOn) { //Add in Milne Thompson contribution if necessary
mtr2=(xs-circlex)*(xs-circlex)+(ys-circley)*(ys-circley);
mtx=circlex+circler*circler*(xs-circlex)/mtr2;
mty=circley+circler*circler*(ys-circley)/mtr2;
mtu=freeStreamU;mtv=freeStreamV;
for(int i=0;i<nf;i++) {
vel=f[i].V(mtx,mty);
mtu+=vel.u;
mtv+=vel.v;
if(vel.inf==true) break;
}
res.u-=circler*circler/mtr2/mtr2*(mtu*((xs-circlex)*(xs-circlex)-(ys-circley)*(ys-circley))+mtv*2.*(xs-circlex)*(ys-circley));
res.v-=circler*circler/mtr2/mtr2*(mtu*2.*(xs-circlex)*(ys-circley)-mtv*((xs-circlex)*(xs-circlex)-(ys-circley)*(ys-circley)));
}
if(vel.inf==true) res.inf=true;
return res;
}
String format(double d,int fdigits) {
String out="",buf;
String[] zeros={"0.","0.0","0.00"};
int mant,exp,sgn=1;
int sdigits=4; //number of digits to show in scientific format
int sci=4; //absolute magnitude of numbers below which to display floating-point format
if(d>0.0) sgn=1;
else if(d<0.0) sgn=-1;
else return(" 0.00");
d=Math.abs(d);
exp=(int)(Math.log(d*1.0000001)/Math.log(10));
if(d<1.0) exp--;
if(exp<4 & exp>=0) {
mant=(int)Math.round(d*Math.pow(10.,(double)(fdigits-1-exp)));
buf=String.valueOf(mant);
out=buf.substring(0,buf.length()-fdigits+exp+1)+"."+buf.substring(buf.length()-fdigits+exp+1); //insert point
//while(out.lastIndexOf("0")==out.length()-1) out=out.substring(0,out.length()-1); //strip trailing zeros
//if(out.lastIndexOf(".")==out.length()-1) out=out.substring(0,out.length()-1); //strip trailing point if necessary
if(sgn==-1) out="-"+out;
else out=" "+out;
}
else if(exp<0 & exp>-4) {
mant=(int)Math.round(d*Math.pow(10.,(double)(fdigits-1)));
buf=String.valueOf(mant);
out=zeros[-exp-1]+buf; //insert point
//while(out.lastIndexOf("0")==out.length()-1) out=out.substring(0,out.length()-1); //strip trailing zeros
if(sgn==-1) out="-"+out;
else out=" "+out;
}
else {
mant=(int)Math.round(d*Math.pow(10.,(double)(sdigits-1-exp)));
buf=String.valueOf(mant);
out=buf.substring(0,1)+"."+buf.substring(1); //insert point
while(out.lastIndexOf("0")==out.length()-1) out=out.substring(0,out.length()-1); //strip trailing zeros
if(out.lastIndexOf(".")==out.length()-1) out=out.substring(0,out.length()-1); //strip trailing point if necessary
if(sgn==-1) out="-"+out;
if(exp>0) out=out+"e+"+String.valueOf(exp);
else out=out+"e"+String.valueOf(exp);
}
return(out);
}
String fformat(double d) { //fixed scientific format
String out="",buf;
String[] zeros={"0.","0.0","0.00"};
int mant,exp,sgn=1,esgn=1;
int sdigits=5; //number of digits to show in scientific format
if(d>0.0) sgn=1;
else if(d<0.0) sgn=-1;
else return("0.0000e+000");
d=Math.abs(d);
exp=(int)(Math.log(d*1.0000001)/Math.log(10));
if(d<1.0) exp--;
mant=(int)Math.round(d*Math.pow(10.,(double)(sdigits-1-exp)));
buf=String.valueOf(mant);
out=buf.substring(0,1)+"."+buf.substring(1); //insert point
if(sgn==-1) out="-"+out;
else out=" "+out;
if(exp>=0) out=out+"e+";
else out=out+"e-";
if(Math.abs(exp)>99) out=out+String.valueOf(Math.abs(exp));
else if(Math.abs(exp)>9) out=out+"0"+String.valueOf(Math.abs(exp));
else out=out+"00"+String.valueOf(Math.abs(exp));
return(out);
}
}
class Legend extends Canvas {
machine root;
Legend(machine target) {
root=target;
setBackground(Color.white);
}
public void paint (Graphics g){
int w,h;
Font l=new Font("TimesRoman",Font.PLAIN,12); //Legend font
float hue;
w=size().width;h=size().height;
for(int i=0;i<30;i++) { //Draw Legend
hue=.99f-(float)i/29.0f*.98f;
g.setColor(Color.getHSBColor(hue,1.0f,1.0f));
g.fillRect((int)(w*(0.6*i/29+.2)),0,(int)(w*.6/20),h);
}
g.setFont(l); //Draw Legend labels
g.setColor(Color.black);
g.drawString("0",(int)(w*.17),(int)(h*.4+5));
g.drawString("2",(int)(w*.85),(int)(h*.4+5));
//g.drawString("Velocity",(int)(w*.5-23),(int)(h*.5-3));
}
}
class Sing {
double x,y,x1,y1;
double s,a,cos,sin;
int id; //1=source, 2=vortex, 3=doublet, 4=source panel, 5=doublet panel
Sing(double xx,double yy, double ss, int idd) {s=ss;id=idd;x=x1=xx;y=y1=yy;a=0.0;} //Source, Vortex Constructor
Sing(double xx,double yy, double aa, double ss, int idd) {s=ss;id=idd;x=x1=xx;y=y1=yy;a=aa;} //Doublet Constructor
Sing(double xx,double yy,double xx1,double yy1, double ss, double ccos, double ssin, int idd) {s=ss;id=idd;x=xx;x1=xx1;y=yy;y1=yy1;cos=ccos;sin=ssin;a=0.0;} //Source, Vortex Sheet Constructor
Velocity V(double xf, double yf) {
double r12,xr1,yr1,r2,xr,yr,al;
Velocity vel=new Velocity(0.0,0.0);
xr=xf-x;yr=yf-y;
r2=xr*xr+yr*yr;
switch (id) {
case 1: //Source & Sink
if(r2>0.0) {
vel.u=s/r2*xr;
vel.v=s/r2*yr;
vel.inf=false;}
else vel.inf=true;
break;
case 2: //Vortex
if(r2>0.0) {
vel.u=-s/r2*yr;
vel.v=s/r2*xr;
vel.inf=false;}
else vel.inf=true;
break;
case 3: //Doublet
if(r2>0.0) {
vel.u=s/r2/r2*((xr*xr-yr*yr)*Math.cos(a)+2.*xr*yr*Math.sin(a));
vel.v=s/r2/r2*(-(xr*xr-yr*yr)*Math.sin(a)+2.*xr*yr*Math.cos(a));
vel.inf=false;}
else vel.inf=true;
break;
case 4: //Source Panel
xr1=xf-x1;yr1=yf-y1;r12=xr1*xr1+yr1*yr1;
if(r2>0.0 && r12>0.0) {
al=Math.atan2(xr,yr)-Math.atan2(xr1,yr1);
if (al>Math.PI) al-=2.0*Math.PI;
if (al<-Math.PI) al+=2.0*Math.PI;
vel.u=s*Math.log(r2/r12)/2.0*cos-s*al*sin;
vel.v=s*al*cos+s*Math.log(r2/r12)/2.0*sin;
vel.inf=false;}
else vel.inf=true;
break;
case 5: //Vortex Panel
xr1=xf-x1;yr1=yf-y1;r12=xr1*xr1+yr1*yr1;
if(r2>0.0 && r12>0.0) {
al=Math.atan2(xr,yr)-Math.atan2(xr1,yr1);
if (al>Math.PI) al-=2.0*Math.PI;
if (al<-Math.PI) al+=2.0*Math.PI;
vel.v=-s*Math.log(r2/r12)/2.0*cos+s*al*sin;
vel.u=s*al*cos+s*Math.log(r2/r12)/2.0*sin;
vel.inf=false;}
else vel.inf=true;
break;
}
return vel;
}
}
class Velocity {
double v;
double u;
boolean inf;
Velocity(double uu, double vv) {u=uu;v=vv;inf=false;}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -