|
import java.applet.*;
import java.awt.*;
import java.awt.event.*;
public class Kettenlinie extends Applet
implements MouseListener,MouseMotionListener
{ double x1=-1,x2=0.9,y1=0,y2=0.3;
double k=1,b=0;
int W,H;
double L=2.5;
final int N=30;
Image I;
Graphics G;
public void init ()
{ W=getSize().width;
H=getSize().height;
compute_kette();
addMouseListener(this);
addMouseMotionListener(this);
I=createImage(W,H);
G=I.getGraphics();
}
boolean red;
public synchronized void paint (Graphics g)
{ G.clearRect(0,0,W,H);
G.drawRect(col(-1),row(1),col(1)-col(-1),row(-1)-row(1));
mark(G,x1,y1); mark(G,x2,y2);
if (red)
{ G.setColor(Color.red);
G.drawLine(col(x1),row(y1),col(x2),row(y2));
G.setColor(Color.black);
}
else
{ int c1,r1,c2,r2;
c1=c2=col(x1); r1=r2=row(y1);
double a=y1-chain(x1,0,b,k);
double dx=(x2-x1)/N;
for (int i=1; i<=N; i++)
{ double x=x1+i*dx;
double y=chain(x,a,b,k);
c2=col(x); r2=row(y);
G.drawLine(c1,r1,c2,r2);
c1=c2; r1=r2;
}
}
g.drawImage(I,0,0,this);
}
public void update (Graphics g)
{ paint(g);
}
int col (double x)
{ return (int)((x+1.2)/2.4*W);
}
int row (double y)
{ return (int)((1.2-y)/2.4*H);
}
void mark (Graphics g, double x, double y)
{ int i=col(x),j=row(y);
g.drawRect(i-5,j-5,10,10);
}
// *********************************
// Maus-Ereignisse
// *********************************
int point=0;
public void mousePressed (MouseEvent e)
{ int c=e.getX(),r=e.getY();
if (Math.abs(c-col(x1))<5 && Math.abs(r-row(y1))<5) point=1;
if (Math.abs(c-col(x2))<5 && Math.abs(r-row(y2))<5) point=2;
}
public void mouseClicked (MouseEvent e) {}
public void mouseReleased (MouseEvent e)
{ point=0;
}
public void mouseEntered (MouseEvent e) {}
public void mouseExited (MouseEvent e) {}
public void mouseMoved (MouseEvent e) {}
public void mouseDragged (MouseEvent e)
{ if (point==0) return;
int c=e.getX(),r=e.getY();
if (point==1)
{ x1=x(c); y1=y(r);
if (x1<-1) x1=-1;
if (x1>x2-0.1) x1=x2-0.1;
if (y1<-1) y1=-1;
if (y1>1) y1=1;
}
else
{ x2=x(c); y2=y(r);
if (x2>1) x2=1;
if (x21) y2=1;
}
compute_kette();
repaint();
}
double x (int c)
{ return -1.2+(double)c/W*2.4;
}
double y (int r)
{ return 1.2-(double)r/H*2.4;
}
// *********************************
// Berechnung der Kettenlinie
// *********************************
synchronized void compute_kette ()
{ if (Math.sqrt((x2-x1)*(x2-x1)+(y2-y1)*(y2-y1))>=L)
{ red=true; return;
}
red=false;
double f=(x2-x1)/2;
double y=(y2-y1)/f;
double bnew=0,knew=0;
int n=0;
while (n<20)
{ bnew=compute_b(k,b,y);
knew=compute_k(k,b,L/f);
if (Math.abs(b-bnew)<0.00001 && Math.abs(k-knew)<0.00001) break;
b=bnew;
k=knew;
n++;
}
b=(x1+x2)/2+bnew*f;
k=knew/f;
}
double sinh (double x)
{ return (Math.exp(x)-Math.exp(-x))/2;
}
double cosh (double x)
{ return (Math.exp(x)+Math.exp(-x))/2;
}
double fs (double k, double b, double L)
{ return (sinh(k*(1-b))-sinh(k*(-1-b)))/k-L;
}
double fc (double k, double b, double y)
{ return (cosh(k*(1-b))-cosh(k*(-1-b)))/k-y;
}
double compute_b (double k, double b, double y)
{ double b1=b+1;
double r=fc(k,b,y);
double r1=fc(k,b1,y);
int n=0;
while (Math.abs(b1-b)>0.00001 && n<20)
{ double bnew=b-r*(b1-b)/(r1-r);
if (bnew==b) System.out.println(); // Netscape bug !!
r1=r; b1=b; b=bnew;
r=fc(k,b,y);
n++;
}
return b;
}
double compute_k (double k, double b, double L)
{ double k1=k+1;
double r=fs(k,b,L);
double r1=fs(k1,b,L);
int n=0;
while (Math.abs(k1-k)>0.00001 && n<20)
{ double knew=k-r*(k1-k)/(r1-r);
if (knew<0) knew=-knew;
r1=r; k1=k; k=knew;
r=fs(k,b,L);
n++;
}
return k;
}
double chain (double x, double a, double b, double k)
{ return a+cosh(k*(x-b))/k;
}
}
zum Inhaltsverzeichnis Kettenlinie
|