import java.awt.*; import java.lang.*; public class Xrayc extends java.applet.Applet { int X0=120,Y0=320,H=250,W=250; int KX0=10,KY0=450,KH=50,KW=450; int KobjX0=10,KobjY0=380; int MAXATOMS = 5; final int HRange=5,KRange=5; int x[] = new int[MAXATOMS+1]; int y[] = new int[MAXATOMS+1]; int xobj[] = new int[MAXATOMS+1]; int yobj[] = new int[MAXATOMS+1]; int highlight[] = new int[MAXATOMS+1]; int xtest,ytest,xmill; final int nk=(2*HRange+1)*(2*KRange+1); double cost,newcost; double h[] = new double[nk+1]; double k[] = new double[nk+1]; double Ire[] = new double[nk+1]; double Iim[] = new double[nk+1]; double Itestre[] = new double[nk+1]; double Itestim[] = new double[nk+1]; double Intensity[] = new double[nk+1]; double testIntensity[] = new double[nk+1]; double objIntensity[] = new double[nk+1]; boolean highlighted = false; boolean isTestAtom = false; boolean newDiffPattern = false; boolean showObj = false; boolean showMiller = false; String msg,newmsg,millmsg,heldmsg; TextArea pD; TextField message; public void init() { xobj[1]=yobj[1]=x[1]=y[1]=0; for (int n = 2;n<=MAXATOMS;n++) { xobj[n] = (int)(W*Math.random()); yobj[n] = (int)(H*Math.random()); x[n] = (int)(W*Math.random()); y[n] = (int)(H*Math.random()); highlight[n] = 0; } for (int f=1;f<=nk;f++) { h[f] = (f-1)/(2*HRange+1) - HRange; k[f] = (f-1)%(2*KRange+1) - KRange; Intensity[f] = 0; } diffractObjective(); diffract(); cost = findCost(Intensity,objIntensity); setLayout(new FlowLayout() ); msg = String.valueOf((float)cost); message = new TextField("cost = "+msg,30); add(message); add(new Button("Restart")); add(new Button("Accept")); add(new Button("Reject")); add(new Button("Show")); Choice trans = new Choice(); trans.addItem("Move along X"); trans.addItem("Move along Y"); trans.addItem("Flip about X"); trans.addItem("Flip about Y"); trans.addItem("Flip about diagonal"); trans.addItem("Rotate 90 degrees"); add(trans); }//end init void restart(){ removeTestAtom(); highlighted = false; isTestAtom = false; newDiffPattern = false; showObj = false; for (int n = 2;n<=MAXATOMS;n++) { xobj[n] = (int)(W*Math.random()); yobj[n] = (int)(H*Math.random()); x[n] = (int)(W*Math.random()); y[n] = (int)(H*Math.random()); highlight[n] = 0; } for (int f=1;f<=nk;f++) { Intensity[f] = 0; testIntensity[f] = 0; } diffractObjective(); diffract(); cost = findCost(Intensity,objIntensity); msg = String.valueOf((float)cost); message.setText("cost = "+msg); repaint(); } public boolean action(Event e, Object arg) { if (e.target instanceof Button) { String command = (String)arg; if (command.equals("Restart")) { restart(); } if (command.equals("Accept")) { if(isTestAtom==true && highlighted==true) { updateDiffractionPattern(); newDiffPattern = false; cost = newcost; msg = String.valueOf((float)cost); message.setText("cost = "+newmsg); isTestAtom = false; highlighted = false; for (int n = 1;n<=MAXATOMS;n++) highlight[n] = 0; } } if (command.equals("Reject")) { isTestAtom = false; newDiffPattern = false; msg = String.valueOf((float)cost); message.setText("cost = "+newmsg); } if (command.equals("Show")) { showObj = true; } repaint(); } if(e.target instanceof Choice) { String command = (String)arg; if (command.equals("Move along X")){ translateX(xobj,10); } if (command.equals("Move along Y")){ translateY(yobj,10); } if (command.equals("Flip about X")){ flipAboutX(yobj); } if (command.equals("Flip about Y")){ flipAboutY(xobj); } if (command.equals("Flip about diagonal")){ flipAboutDiagonal(xobj,yobj); } if (command.equals("Rotate 90 degrees")){ rotate(xobj,yobj); } System.out.println("this far"); repaint(); } return true; }//End action public boolean mouseDown (Event e, int xin, int yin) { if (xin>=X0&&xin<=X0+W&&yin>=Y0-H&&yin<=Y0) { if (highlighted == false && isTestAtom == false) { for (int i = 1;i<=MAXATOMS;i++) highlight[i] = 0; boolean found = locateAtom(xin,yin); if (found == true) { removeTestAtom(); highlighted = true; } } else if (highlighted == true && isTestAtom == false) { addTestAtom(xin,yin); isTestAtom = true; newDiffPattern = true; newDiffract(); newcost = findCost(testIntensity,objIntensity); newmsg = String.valueOf((float)newcost); message.setText("cost = "+msg+"newcost= "+newmsg); } else if (highlighted == true && isTestAtom == true) { int highAtom = 0; for (int i = 1;i<=MAXATOMS;i++) if (highlight[i] == 1) { highAtom = i; highlight[i] = 0; } removeTestAtom(); boolean found = locateAtom(xin,yin); if (found == true) { highlighted = true; isTestAtom = false; newDiffPattern = false; } else { highlight[highAtom] = 1; addTestAtom(xin,yin); isTestAtom = true; newDiffract(); newcost = findCost(testIntensity,objIntensity); newmsg = String.valueOf((float)newcost); message.setText("cost = "+msg+"newcost= "+newmsg); newDiffPattern = true; } } } else { message.setText("Click on the blue area"); } //Clicked on Frequency region if (xin>=KX0&&xin<=KX0+KW&&yin>=KY0-KH&&yin<=KY0) { for(int f=0;f=(KX0+3.15*f)&&xin<(KX0+3.15*(f+1))) { xmill = (int)(KX0+3.15*f); millmsg = "(h,k) = ("+String.valueOf(h[f])+"," +String.valueOf(k[f])+")"; } } heldmsg = message.getText(); message.setText(millmsg); repaint(); showMiller = true; } repaint(); return true; }//End mouseDown public boolean mouseUp(Event e, int x, int y) { if (showMiller == true) { showMiller = false; message.setText(heldmsg); } repaint(); return true; } public boolean keyDown(Event e, int key) { if (isTestAtom == true) { switch (key) { case Event.LEFT: xtest -= 5; break; case Event.RIGHT: xtest += 5; break; case Event.UP: ytest += 5; break; case Event.DOWN: ytest -= 5; break; } if (xtest>=W) xtest -= W; if (xtest<0) xtest += W; if (ytest>=H) ytest -= H; if (ytest<0) ytest += H; newDiffract(); newcost = findCost(testIntensity,objIntensity); newmsg = String.valueOf((float)newcost); message.setText("cost = "+msg+"newcost= "+newmsg); repaint(); } return true; } void addAtom(int current, int xin , int yin) { x[current] = -X0+xin; y[current] = Y0-yin; } void addTestAtom(int xin , int yin) { xtest=xin-X0; ytest=Y0-yin; } void removeTestAtom() { xtest = 0; ytest = 0; } boolean locateAtom(int xin, int yin){ int found = 0; int xspot = xin-X0; int yspot = Y0-yin; for (int i=1; i<=MAXATOMS; i++) { for (int ii=-5;ii<=5;ii++) for (int jj=-5;jj<=5;jj++) if(x[i]+ii==xspot&&y[i]+jj==yspot) { highlight[i] = 1; System.out.println("Spot #"+i+"x = "+xin+"y = "+yin); found = 1; } } if (found == 0) return false; else return true; } void diffractObjective() { double re,im,arg;//,vol=0; double xmid[] = new double[nk+1]; double ymid[] = new double[nk+1]; int n,f; for(n=1;n<=MAXATOMS;n++) { xmid[n] = (double)(xobj[n])/W; ymid[n] = (double)(yobj[n])/H; } for(f=1;f<=nk;f++) { re = im = 0; for(n=1;n<=MAXATOMS;n++) { arg = (double)( 2*3.14159*( h[f]*xmid[n]+k[f]*ymid[n] ) ); re += (double)(Math.cos(arg)); im += (double)(Math.sin(arg)); objIntensity[f] = re*re+im*im; } } }//End diffract void diffract() { double arg; double xmid[] = new double[nk+1]; double ymid[] = new double[nk+1]; int n,f; for(n=1;n<=MAXATOMS;n++) { xmid[n] = (double)(x[n])/W; ymid[n] = (double)(y[n])/H; } for(f=1;f<=nk;f++) { Ire[f] = Iim[f] = 0; for(n=1;n<=MAXATOMS;n++) { arg = (double)( 2*3.14159*( h[f]*xmid[n]+k[f]*ymid[n] ) ); Ire[f] += (double)(Math.cos(arg)); Iim[f] += (double)(Math.sin(arg)); Intensity[f] = Ire[f]*Ire[f]+Iim[f]*Iim[f]; } } }//End diffract void newDiffract() { double argnew,argold; double xold=0,yold=0,xnew=0,ynew=0; int n,f; for(n=1;n<=MAXATOMS;n++) { if (highlight[n] == 1) { xold = (double)(x[n])/W; yold = (double)(y[n])/H; xnew = (double)(xtest)/W; ynew = (double)(ytest)/H; //System.out.println("xm = "+xmid[n]+"ym = "+ymid[n]); } } for(f=1;f<=nk;f++) { argold = (double)( 2*3.14159*( h[f]*xold+k[f]*yold ) ); argnew = (double)( 2*3.14159*( h[f]*xnew+k[f]*ynew ) ); Itestre[f] = Ire[f]+(double)((Math.cos(argnew)-Math.cos(argold)) ); Itestim[f] = Iim[f]+(double)((Math.sin(argnew)-Math.sin(argold)) ); testIntensity[f] = Itestre[f]*Itestre[f]+Itestim[f]*Itestim[f]; } }//End newDiffract double findCost(double i1[], double i2[]) { double cst=0; for(int f=1;f<=nk;f++) { cst += (i1[f]-i2[f])*(i1[f]-i2[f]); } return cst; } void updateDiffractionPattern() { for (int n=1;n<=MAXATOMS;n++) { if (highlight[n] == 1) { System.out.print("Atom # "+n+" updated from "+x[n]+", "+y[n]); x[n] = xtest; y[n] = ytest; removeTestAtom(); System.out.println(" to "+x[n]+", "+y[n]); } } for (int f=1;f<=nk;f++) { Ire[f] = Itestre[f]; Iim[f] = Itestim[f]; Intensity[f] = testIntensity[f]; Itestre[f] = Itestim[f] = testIntensity[f] = 0; } }//End updateDiffractionPattern void translateX(int xin[], int xt) { for(int n=1;n<=nk;n++) { xin[n] += xt; while(xin[n]>=W) {xin[n]-=W;} while(xin[n]<0) {xin[n]+=W;} } } void translateY(int yin[], int yt) { for(int n=1;n<=nk;n++) { yin[n] += yt; while(yin[n]>=H) {yin[n]-=H;} while(yin[n]<0) {yin[n]+=H;} } } void flipAboutX(int yin[]) { for(int n=1;n<=nk;n++) { yin[n] = H-yin[n]; } } void flipAboutY(int xin[]) { for(int n=1;n<=nk;n++) { xin[n] = W-xin[n]; } } void flipAboutDiagonal(int xin[], int yin[]) { int temp; for (int n=1;n<=nk;n++) { temp = yin[n]; yin[n] = xin[n]; xin[n] = temp; } } void rotate(int xin[], int yin[]) { int temp; for (int n=1;n<=nk;n++) { temp = yin[n]; yin[n] = xin[n]; xin[n] = H-temp; } } public void paint(Graphics g) { int xdraw,ydraw; int kxdraw[] = new int[nk+1]; int kydraw[] = new int[nk+1]; int kxndraw[] = new int[nk+1]; int kyndraw[] = new int[nk+1]; //Set up Atomic box and Frequency domain g.setColor(Color.blue); g.fillRect(X0,Y0-H,W,H); //Add coordinate axes g.setColor(Color.black); g.drawLine(X0,Y0-H,X0,Y0); g.drawLine(X0,Y0,X0+W,Y0); g.drawLine(KX0,KY0-KH,KX0,KY0); g.drawLine(KX0,KY0,KX0+KW,KY0); g.drawLine(KobjX0,KobjY0-KH,KobjX0,KobjY0); g.drawLine(KobjX0,KobjY0,KobjX0+KW,KobjY0); //Display atoms in the field for (int n=1;n<=MAXATOMS;n++) { if (highlight[n] == 0) g.setColor(Color.red); else if (highlight[n] == 1) g.setColor(Color.orange); xdraw = X0+x[n]; ydraw = Y0-y[n]; g.fillOval(xdraw-5,ydraw-5,10,10); } //Add the test spot, if necessary if(isTestAtom == true) { g.setColor(Color.white); xdraw = X0+xtest; ydraw = Y0-ytest; g.fillOval(xdraw-5,ydraw-5,10,10); } if (showObj == true) { for (int n=1;n<=MAXATOMS;n++) { g.setColor(Color.black); xdraw = X0+xobj[n]; ydraw = Y0-yobj[n]; g.fillOval(xdraw-5,ydraw-5,10,10); } } //Add the frequency components //Objective Intensity for (int f=1;f<=nk;f++) { kxdraw[f] = (int)(KobjX0+3.75*f); kydraw[f] = (int)(KobjY0-2.5*objIntensity[f]); } g.setColor(Color.black); for (int f=1;f<=nk-1;f++) { g.drawLine(kxdraw[f],kydraw[f],kxdraw[f+1],kydraw[f+1]); } //Currently Accepted Intensity for (int f=1;f<=nk;f++) { kxdraw[f] = (int)(KX0+3.75*f); kydraw[f] = (int)((KY0-2.5*Intensity[f])); } g.setColor(Color.black); for (int f=1;f<=nk-1;f++) { g.drawLine(kxdraw[f],kydraw[f],kxdraw[f+1],kydraw[f+1]); } //Possible Future Intensity if(newDiffPattern == true) { for (int f=1;f<=nk;f++) { kxdraw[f] = (int)(KX0+3.75*f); kydraw[f] = (int)(KY0-2.5*testIntensity[f]); } g.setColor(Color.red); for (int f=1;f<=nk-1;f++) { g.drawLine(kxdraw[f],kydraw[f],kxdraw[f+1],kydraw[f+1]); } } //Show the miller indices if (showMiller == true) { g.setColor(Color.yellow); g.fillRect(xmill,KY0-40,4,40); } }//End paint }