/* # ==================================================================== # Calculate some information on different dome frequencies and display # ==================================================================== # # a Java adaptation of # a perl shell script adaptation of # a BASIC program # # Written in BASIC by: Joseph D. Clinton June 1, 1991 # Converted to perl by: David Boldt August 28, 1992 # Converted to Java by: Kirby Urner March 27, 1996 # # v.01 Initial conversion to Java applet # //{{using Cafe Java IDE by Symantec # -------------------------------------------------------------------- Technical notes: dome.class passes a reference to itself to DomePanel.class so the two can talk to one another (DomePanel manipulates screen controls, and vice versa). Dome is the whole applet whereas DomePanel is the drawing panel, instantiated as DrawPanel in the dome applet. DomePanel contains all the guts of the BASIC/Perl program, rewritten as Java methods (used same procedure and variable names -- basically a cut and paste operation, followed by syntax conversion). Several methods from the original were omitted (e.g. the procedures to list chords, count how many, and sort them into ascending order), since this applet has to live in an essentially read-only environment (Java security forbids outputting files, for the most part). But that's OK, since we can draw the results immediately to the screen. */ import java.awt.*; import java.applet.*; public class dome extends Applet { DomePanel DrawPanel; //{{DECLARE_CONTROLS CheckboxGroup group1; Checkbox check1; Checkbox check2; Scrollbar scrollbar1; Button button1; Label label1; Label label2; Label label3; Label lbl; Label label4; Label label5; //}} // stub to support stand-alone version (unused by applet) public static void main(String args[]){ Frame f = new Frame("My Window"); dome myapp = new dome(); myapp.init(); myapp.start(); f.add("Center",myapp); f.resize(450,450); f.show(); } public void init() { super.init(); //lots of nit-picky positioning of screen controls, automated by Symantec Cafe //(I used a visual form designer tool) //{{INIT_CONTROLS setLayout(null); addNotify(); resize(insets().left + insets().right + 343, insets().top + insets().bottom + 311); DrawPanel=new DomePanel(this); DrawPanel.setLayout(null); add(DrawPanel); DrawPanel.reshape(insets().left + 7,insets().top + 8,263,225); group1= new CheckboxGroup(); check1=new Checkbox("1/20",group1, true); add(check1); check1.reshape(insets().left + 280,insets().top + 64,53,17); check2=new Checkbox("5/8",group1, false); add(check2); check2.reshape(insets().left + 280,insets().top + 86,49,21); scrollbar1= new Scrollbar(Scrollbar.VERTICAL, 1,1,1,11); add(scrollbar1); scrollbar1.reshape(insets().left + 291,insets().top + 137,13,94); button1=new Button("Manual"); add(button1); button1.reshape(insets().left + 277,insets().top + 17,56,30); label1=new Label("Frequency"); label1.setFont(new Font("TimesRoman",Font.PLAIN,12)); add(label1); label1.reshape(insets().left + 268,insets().top + 114,65,15); label2=new Label("Synergetics on the Web"); label2.setFont(new Font("TimesRoman",Font.ITALIC,14)); add(label2); label2.reshape(insets().left + 14,insets().top + 238,189,21); label3=new Label("Java by K. Urner based on a program by Joseph Clinton"); label3.setFont(new Font("Dialog",Font.PLAIN,8)); add(label3); label3.reshape(insets().left + 14,insets().top + 261,301,15); lbl=new Label("1"); lbl.setFont(new Font("Dialog",Font.BOLD,12)); add(lbl); lbl.reshape(insets().left + 310,insets().top + 182,25,15); label4=new Label("converted from Perl version by David Boldt "); label4.setFont(new Font("Dialog",Font.PLAIN,8)); add(label4); label4.reshape(insets().left + 14,insets().top + 274,301,15); label5=new Label("Ver 1.0"); label5.setFont(new Font("Dialog",Font.ITALIC,10)); add(label5); label5.reshape(insets().left + 278,insets().top + 238,55,19); //}} } public void start() { DrawPanel.start(); } public void stop() { DrawPanel.stop(); } public boolean handleEvent(Event event) { if ((event.target instanceof Scrollbar)) { if (button1.getLabel() == "Cycle") { int v = ((Scrollbar)event.target).getValue(); lbl.setText(String.valueOf(DrawPanel.nu)); DrawPanel.nu = v ; DrawPanel.repaint(); } } else if (event.id == Event.ACTION_EVENT && event.target == check2) { clickeddome(); return true; } else if (event.id == Event.ACTION_EVENT && event.target == check1) { clickedtri(); return true; } else if (event.id == Event.ACTION_EVENT && event.target == button1) { clickedButton1(); return true; } return super.handleEvent(event); } public void clickedButton1() { // to do: put event handler code here. if (button1.getLabel()=="Manual"){ button1.setLabel("Cycle"); DrawPanel.stop(); } else { button1.setLabel("Manual"); DrawPanel.start(); } } public void clickedtri() { // to do: put event handler code here. DrawPanel.draft=true; DrawPanel.repaint(); } public void clickeddome() { // to do: put event handler code here. DrawPanel.draft=false; DrawPanel.repaint(); } } class DomePanel extends Panel implements Runnable{ Thread runner; Image offscreenImg; Graphics offscreenG; Dimension offscreensize; dome thisobj; Color backcolor = Color.white ; double tau = (1.0 + Math.sqrt(5)) / 2.0; double pi = Math.PI; double ra = pi/180.0; double ro = 0.0; double de = 180.0/pi; int sf_vp = 200; int x_vp = 320; int y_vp = 375; int nu = 1; int maxfreq = 10; double x[] = new double[(maxfreq+1)*(maxfreq+1)] ; double y[] = new double[(maxfreq+1)*(maxfreq+1)] ; double z[] = new double[(maxfreq+1)*(maxfreq+1)] ; double x1[] = new double[(maxfreq+1)*(maxfreq+1)] ; double y1[] = new double[(maxfreq+1)*(maxfreq+1)] ; double z1[] = new double[(maxfreq+1)*(maxfreq+1)] ; double x2[] = new double[(maxfreq+1)*(maxfreq+1)] ; double y2[] = new double[(maxfreq+1)*(maxfreq+1)] ; double z2[] = new double[(maxfreq+1)*(maxfreq+1)] ; boolean draft = true; DomePanel (dome callingclass) { this.thisobj = callingclass ; } public void start () { if (runner == null) { runner = new Thread(this) ; runner.start(); } repaint(); } public void stop () { if (runner != null) { runner.stop() ; runner = null ; } } public void update (Graphics g) { Dimension d = size(); if ((offscreenImg == null) || (d.width != offscreensize.width) || (d.height != offscreensize.height)) { offscreenImg = createImage(d.width, d.height); offscreensize = d; offscreenG = offscreenImg.getGraphics(); } offscreenG.setColor(backcolor) ; offscreenG.fillRect(0,0, d.width, d.height); paint(offscreenG) ; g.drawImage(offscreenImg,0,0,this) ; } public void run () { while (runner != null) { for (int k = 1; k < maxfreq; k++) { this.nu = k ; repaint() ; try { Thread.sleep(400); } catch (InterruptedException e) { } } for (int k = maxfreq; k > 1; k--) { this.nu = k ; repaint() ; try { Thread.sleep(400); } catch (InterruptedException e) { } } } } public void paint (Graphics g) { // setchords(); setverts(); thisobj.scrollbar1.setValue(nu) ; thisobj.lbl.setText(String.valueOf(nu)); if(draft){ draft(g); } else { showdome(g); } } public void setverts() { // -- pre-allocate array space int i; int j; int index; double theta; double phi; for (i = 0; i <= nu; i++) { for (j = 0; j <= i; j++) { index = index2D(i,j); x[index] = j; z[index] = nu - i; y[index] = nu - x[index] - z[index]; z[index] = nu / 2.0 + z[index] / tau; y[index] = y[index] + x[index] * Math.cos(72.0 * ra); x[index] = x[index] * Math.sin(72.0 * ra); if ( y[index] == 0 ) { phi = 0; } else { phi = Math.atan2( x[index], y[index]); } if ( z[index] == 0 ) { theta = 0; } else { theta = Math.atan2(Math.sqrt( x[index]*x[index] + y[index]*y[index]), z[index] ); } x[index] = Math.cos(phi) * Math.sin(theta); y[index] = Math.sin(phi) * Math.sin(theta); z[index] = Math.cos(theta); } } } public int index2D(int i, int j) { return (nu+1) * i + j; } public void plot(Graphics g, Color color) { int index, index2, a, b, i, j; double x_start, y_start, x_stop, y_stop ; double cf, tempx, tempy, tempz; sf_vp = 200; x_vp = 320; y_vp = 375; // -- plot lattitude struts for (i = 1; i <= nu; i++) { for (j = 1; j <= i; j++) { index = index2D(i,j); index2 = index2D(i,j-1); if ( z1[index] >= -0.1 ) { x_start = x1[index2] * sf_vp + x_vp; y_start = y1[index2] * sf_vp + y_vp; x_stop = x1[index] * sf_vp + x_vp; y_stop = y1[index] * sf_vp + y_vp; mkline(g, color, x_start, y_start, x_stop, y_stop); } } } a = 1; for (j = 0; j <= nu-1; j++) { for (i = a; i <= nu; i++) { index = index2D(i,j); index2 = index2D(i-1,j); if ( z1[index] >= -0.1 ) { x_start = x1[index2] * sf_vp + x_vp; y_start = y1[index2] * sf_vp + y_vp; x_stop = x1[index] * sf_vp + x_vp; y_stop = y1[index] * sf_vp + y_vp; mkline(g, color, x_start, y_start, x_stop, y_stop); } } a++; } a = 1; b = 0; for (j = b; j <= nu-1; j++) { for (i = a; i <= nu; i++) { b++; index = index2D(i,b); index2 = index2D(i-1,b-1); if ( z1[index] >= -0.1 ) { x_start = x1[index2] * sf_vp + x_vp; y_start = y1[index2] * sf_vp + y_vp; x_stop = x1[index] * sf_vp + x_vp; y_stop = y1[index] * sf_vp + y_vp; mkline(g, color, x_start, y_start, x_stop, y_stop); } } b = 0; a++; } } // -----------------------------------< function t1 public void t1(Graphics g, Color color) { int i,j,index ; for (i = 0; i <= nu; i++) { for (j = 0; j <= i; j++) { index = index2D(i,j); x1[index] = x[index]; y1[index] = y[index]; z1[index] = z[index]; } } plot(g, color); } // -----------------------------------< function t2 public void t2 (Graphics g, Color color) { int i,j,index ; for (i = 0; i <= nu; i++) { for (j = 0; j <= i; j++) { index = index2D(i,j); x1[index] = x[index]*Math.cos(ro) - y[index]*Math.sin(ro); y1[index] = x[index]*Math.sin(ro) + y[index]*Math.cos(ro); z1[index] = z[index]; } } plot(g, color); } // -----------------------------------< function t3 public void t3 (Graphics g, Color color) { int i,j,index; for (i = 0; i <= nu; i++) { for (j = 0; j <= i; j++) { index = index2D(i,j); x2[index] = x1[index]; y2[index] = y1[index]; z2[index] = z1[index]; } } plot(g, color); } // -----------------------------------< function e1 public void e1 (Graphics g, Color color) { int i,j,index; for (i = 0; i <= nu; i++) { for (j = 0; j <= i; j++) { index = index2D(i,j); x1[index] = -x2[index]*Math.cos(ro) - z2[index]*Math.sin(ro); y1[index] = y2[index]; z1[index] = -x2[index]*Math.sin(ro) + z2[index]*Math.cos(ro); } } plot(g, color); } // -----------------------------------< function e2 public void e2 (Graphics g, Color color) { int i,j,index; for (i = 0; i <= nu; i++) { for (j = 0; j <= i; j++) { index = index2D(i,j); x1[index] = -x[index]; y1[index] = y[index]; z1[index] = -z[index]; } } plot(g, color); } // -----------------------------------< function e3 public void e3() { int i,j,index; for (i = 0; i <= nu; i++) { for (j = 0; j <= i; j++) { index = index2D(i,j); x[index] = x1[index]; y[index] = y1[index]; z[index] = z1[index]; } } } // -----------------------------------< function draft // draw super-triangle with chords labeled public void draft(Graphics g) { int index, index2, a, b, i, j; double x_start, y_start, x_stop, y_stop ; double cf, tempx, tempy, tempz; Color color = Color.black; ro = 3.2 * 72.0 * ra; sf_vp = 400; y_vp = 550; t2(g, Color.black); // -- plot lattitude struts for (i = 1; i <= nu; i++) { for (j = 1; j <= i; j++) { index = index2D(i,j); index2 = index2D(i,j-1); if ( z1[index] >= -0.1 ) { x_start = x1[index2] * sf_vp + x_vp; y_start = y1[index2] * sf_vp + y_vp; x_stop = x1[index] * sf_vp + x_vp; y_stop = y1[index] * sf_vp + y_vp; mkline(g, color, x_start, y_start, x_stop, y_stop); tempx = (x1[index2D(i,j) ] - x1[index2D(i,j-1) ]); tempy = (y1[index2D(i,j) ] - y1[index2D(i,j-1) ]); tempz = (z1[index2D(i,j) ] - z1[index2D(i,j-1) ]); cf = Math.sqrt(tempx*tempx + tempy*tempy + tempz*tempz); } } } // -- plot left edge struts a = 1; for (j = 0; j <= nu-1; j++) { for (i = a; i <= nu; i++) { index = index2D(i,j); index2 = index2D(i-1,j); if ( z1[index] >= -0.1 ) { x_start = x1[index2] * sf_vp + x_vp; y_start = y1[index2] * sf_vp + y_vp; x_stop = x1[index] * sf_vp + x_vp; y_stop = y1[index] * sf_vp + y_vp; mkline(g, color, x_start, y_start, x_stop, y_stop); tempx = (x1[index2D(i,j) ] - x1[index2D(i,j-1) ]); tempy = (y1[index2D(i,j) ] - y1[index2D(i,j-1) ]); tempz = (z1[index2D(i,j) ] - z1[index2D(i,j-1) ]); cf = Math.sqrt(tempx*tempx + tempy*tempy + tempz*tempz); } } a++; } // -- plot right edge struts a = 1; b = 0; for (j = b; j <= nu-1; j++) { for (i = a; i <= nu; i++) { b++; index = index2D(i,b); index2 = index2D(i-1,b-1); if ( z1[index] >= -0.1 ) { x_start = x1[index2] * sf_vp + x_vp; y_start = y1[index2] * sf_vp + y_vp; x_stop = x1[index] * sf_vp + x_vp; y_stop = y1[index] * sf_vp + y_vp; mkline(g, color, x_start, y_start, x_stop, y_stop); tempx = (x1[index2D(i,j) ] - x1[index2D(i,j-1) ]); tempy = (y1[index2D(i,j) ] - y1[index2D(i,j-1) ]); tempz = (z1[index2D(i,j) ] - z1[index2D(i,j-1) ]); cf = Math.sqrt(tempx*tempx + tempy*tempy + tempz*tempz); } } b = 0; a++; } } public void showdome(Graphics g){ int t; t1(g, Color.black); ro = 72.0 * ra; for (t = 1; t <= 4; t++) { ro = t * 72.0 * ra; t2(g, Color.black); if (t == 2 ) { t3(g, Color.black); } } // -- draw the second layer of the icosahedron (10 super-panels) ro = 52.622627 + 37.377373; e1(g, Color.blue); e3(); for (t = 1; t <= 4; t++) { ro = t * 72.0 * ra; t2(g, Color.blue); if (t == 2 ) { t3(g, Color.blue); } } e2(g, Color.green); e3(); for (t = 1; t <= 4; t++) { ro = t * 72.0 * ra; t2(g, Color.green); if (t == 2 ) { t3(g, Color.green); } } } public void mkline(Graphics g, Color color, double x_start, double y_start, double x_stop, double y_stop) { int x1,y1,x2,y2; if (draft) { x1 = (int)(x_start -180); y1 = (int)(y_start - 175); x2 = (int)(x_stop -180); y2 = (int)(y_stop - 175); } else { x1 = (int)(x_start/2 -30); y1 = (int)(y_start/2 - 75); x2 = (int)(x_stop/2 -30); y2 = (int)(y_stop/2 - 75); } g.setColor(color); g.drawLine(x1,y1,x2,y2); } }