/* * h1c.java - revised 18 Apr 05 - width 461, height 285 * @author jackord@kw.igs.net * companion program to cat.java showing the parameter variation sequence * (a) used in cat.java (thread sleeps 10 ms per trial) * (b) in the simplex algorithm (thread sleeps 100 ms per trial) * the catenary constants are also refined using the simplex algorithm */ import java.applet.Applet; import java.awt.*; import java.awt.event.ActionListener; import java.awt.event.ActionEvent; public class h1c extends Applet implements ActionListener, Runnable { int n, phi, nvr, nvx; int kk=0; int r=3; int del=0; // Declarations double s, tns, dtns, d; double[][] q=new double[9][6]; String b1s="Vary"; Button b1=new Button(b1s); String b2s="Simp"; Button b2=new Button(b2s); String b3s="Catc"; Button b3=new Button(b3s); TextField tx1=new TextField(10); TextField tx2=new TextField(10); TextField tx3=new TextField(10); Thread tmr; public void init() { add(b1); add(b2); add(b3); add(tx1); add(tx2); add(tx3); b1.addActionListener(this); b2.addActionListener(this); b3.addActionListener(this); setBackground(new Color(211, 211, 211)); tx1.setBackground(getBackground()); tx2.setBackground(getBackground()); tx3.setBackground(getBackground()); } public void start() { // Graphics thread if (tmr==null) { tmr=new Thread(this); tmr.setPriority(Thread.MIN_PRIORITY); tmr.start(); } } public void stop() { tmr=null; kk=0; } public void run() { repaint(); } public void hit(int ii, Graphics g) { // Trace out string double x, y, p, t, tn, tc; if (kk==3) { x=q[ii][2]+q[ii][3]*cosh((10-q[ii][1])/q[ii][3])-230; y=q[ii][2]+q[ii][3]*cosh((250-q[ii][1])/q[ii][3])-110; p=q[ii][3]*(sinh((250-q[ii][1])/q[ii][3])-sinh((10-q[ii][1])/q[ii][3]))-400; s=Math.sqrt((x*x+y*y+p*p)/3); } else { x=10; y=10; t=tns; p=phi*Math.PI/18000; // First angle & tension if (kk==2) { p=q[ii][1]*Math.PI/18000; t=q[ii][2]; } tn=Math.tan(p); tc=t*Math.cos(p); x=x+d*Math.cos(p); y=y-d*Math.sin(p); g.fillArc(xs(-p*180/Math.PI)-r, ys(t)-r, 2*r, 2*r, 0, 360); for (int i=1; i<=n; i=i+1) { // Loop tn=tn+1/tc; p=Math.atan(tn); t=tc/Math.cos(p); // Next angle & tension x=x+d*Math.cos(p); y=y-d*Math.sin(p); } s=Math.sqrt((x-250)*(x-250)+(y-130)*(y-130)); try { // Graphics time delay Thread.sleep(del); } catch (InterruptedException e) { stop(); } } } public void ang(Graphics g) { // Find optimum angle double so; int dph=-256; do { phi=phi+dph; so=s; hit(1, g); if (s>so) { dph=-dph/2; } } while (Math.abs(dph)>1); phi=phi+2*dph; hit(1, g); } double cosh(double x) { // Cosh(x) return (Math.exp(x)+Math.exp(-x))/2; } double sinh(double x) { // Sinh(x) return (Math.exp(x)-Math.exp(-x))/2; } int xs(double x) { return 48+(int)((x-58)*400./22); } int ys(double y) { return 242-(int)((y-40)*230./12); } public void pin(Graphics g) { // Initialize screen if (kk==0) { b1.setBounds(53, 167, 40, 20); b2.setBounds(53, 192, 40, 20); b3.setBounds(53, 217, 40, 20); tx1.setBounds(98, 167, 80, 20); tx2.setBounds(98, 192, 80, 20); tx3.setBounds(98, 217, 80, 20); } g.setColor(Color.black); g.drawRect(48, 12, 400, 230); g.drawString("40", 28, 248); g.drawString("52", 28, 18); g.drawString("tension", 4, 133); g.drawString("angle", 224, 278); g.drawString("58", 40, 262); g.drawString("80", 440, 262); } public void paint(Graphics g) { // Paint double so; pin(g); n=64; d=400./(n+1); phi=-6000; tns=48; dtns=2; g.setColor(Color.red); hit(1, g); tx1.setText("phi = "+(-phi/100.)); tx2.setText("tns = "+(int)(100*tns)/100.); tx3.setText("dev = "+(int)(100*s)/100.); if (kk==1) { g.setColor(Color.blue); ang(g); tx3.setText("Dev = "+(int)(100*s)/100.); do { // Vary initial tension tns=tns+dtns; so=s; ang(g); // ... and angle tx1.setText("phi = "+(-phi/100.)); tx2.setText("tns = "+(int)(100*tns)/100.); tx3.setText("dev = "+(int)(100*s)/100.); if (s>so) { dtns=-dtns/2; } } while ((s>.1)&&(kk>0)); // ... to reach support g.setColor(Color.red); hit(1, g); } if (kk==2) { g.setColor(Color.red); sim(g); } if (kk==3) { sim(g); } stop(); } public void sim(Graphics g) { // Simplex algorithm int ii=0; int iv=0; int jlof=0; int xflag; double ave, nexp, lim; if (kk==2) { nvr=2; nvx=nvr+1; lim=0.1; q[1][1]=phi; q[1][2]=tns; q[2][1]=phi-256; q[2][2]=tns; q[3][1]=phi; q[3][2]=tns+dtns; } else { nvr=3; nvx=nvr+1; lim=0.00001; q[1][1]=152; q[1][2]=-42; q[1][3]=69; q[2][1]=153; q[2][2]=-42; q[2][3]=69; q[3][1]=152; q[3][2]=-41; q[3][3]=69; q[4][1]=152; q[4][2]=-42; q[4][3]=70; } for (int i=1; i<=nvx; i=i+1) { hit(i, g); q[i][0]=s; } sort(g); while ((q[1][0]>lim)&&(kk>0)) { xflag=0; for (int i=1; i<=nvr; i=i+1) { ave=0; for (int j=1; j<=nvr; j=j+1) { ave=ave+q[j][i]; } q[nvx+1][i]=ave/nvr; } if ((jlof==1)&&(q[nvx+2][0]==q[nvx][0])) { jlof=0; cns(g); } else { jlof=0; iv=nvx+2; for (int i=1; i<=nvr; i=i+1) { q[iv][i]=2*q[nvx+1][i]-q[nvx][i]; } hit(iv, g); q[iv][0]=s; if (q[iv][0]>q[nvx][0]) { cns(g); } else { if (q[iv][0]