/*** 2D Waves ***/
/*** By Kim 0yhus 1998 (L)    ***/
#include <stdio.h>
#include <math.h>
#include <malloc.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>


Display *display;
Window window;
GC gc;
Colormap colors, colors2;

Visual       *visual;
XColor        xcolor;
XSizeHints    hints;

int OrigoX, OrigoY; 

void
  OpenX()
{
  int n,x,y;

  display = XOpenDisplay(0);
  x=DisplayWidth( display,0);
  y=DisplayHeight(display,0);
x=y=512;
  window=
    XCreateSimpleWindow(display,RootWindow(display,0),1,1,x,y,0,1,0);
  hints.flags=PPosition | USPosition;
  hints.x=100;
  hints.y=100;
  XSetStandardProperties(display, window, "kim's urkehulmate",
			 NULL,NULL,NULL,0, &hints);
  XMapWindow(display,window);
  XSync(display,True);
  sleep(1);

  visual=DefaultVisual(display, 0);
  colors =XCreateColormap(display,window,visual,AllocAll);
  colors2=XCreateColormap(display,window,visual,AllocAll);

  xcolor.flags= DoRed | DoGreen | DoBlue;
  for(n=0; n<256; n++) 
    {
      xcolor.pixel= n;
      xcolor.red  = n<<8;
      xcolor.green= n<<8;
      xcolor.blue = n<<8;
      XStoreColor(display, colors, &xcolor);
    }
  XInstallColormap(display,colors);
  XSetWindowColormap(display,window,colors);


  gc=XCreateGC(display,window,0,0);
  XSync(display,True);

  for(n=0; n<256; n++)
    {
      XSetForeground(display,gc,n);
      XFillRectangle(display,window,gc,n*4,0,4,256*2);
      XSync(display,True);
    }
}

void
  CloseX()
{
  /*
  XUninstallColormap(display,colors);
  XUninstallColormap(display,colors2);
  */
  XCloseDisplay(display);
}


double
X(double x, double y)
{
return(y/(x*x+y*y) +1.);
}

double
Y(double x, double y)
{
return(0-x/(x*x+y*y));
}

void
Curve(double x, double y, int N)
{
  int n;
  double x1,y1, x2,y2;

  x1=y1=0.;
  for(n=0; n<N; n++)
    {
      x2=X(x+x1,y+y1)*.001;
      y2=Y(x+x1,y+y1)*.001;
      x+=(x1+x2)/2.;
      y+=(y1+y2)/2.;
      XFillRectangle(display,window,gc, 
		     OrigoX+OrigoY/2*x,OrigoY-OrigoY/2*y,1,1);
      x1=x2;
      y1=y2;
    }
}

double F1[256][256], F2[256][256];

main()
{
  int n, c, x,y;
  char *Bilde;
  double f;
  XImage *XBilde;

  OpenX();
  OrigoX=DisplayWidth( display,0)/2;
  OrigoY=DisplayHeight(display,0)/2;
OrigoX=OrigoY=256;

  /*  XSetForeground(display,gc,0);
  XFillRectangle(display,window,gc,0,0,OrigoX*2,OrigoY*2);
  */
  Bilde=malloc(512*512);
  XBilde=XCreateImage(display, visual, 8, ZPixmap, 0, Bilde, 512, 512, 32, 0);

  for(y=0; y<256; y++)
    {
      for(x=0; x<256; x++)
	{
	  Bilde[x*2+0 +(y*2+0)*512]=x;
	  Bilde[x*2+0 +(y*2+1)*512]=x;
	  Bilde[x*2+1 +(y*2+0)*512]=x;
	  Bilde[x*2+1 +(y*2+1)*512]=x;
	}
    }
  XPutImage(display,window,gc, XBilde, 0,0, OrigoX-256,OrigoY-256, 512,512);

  for(y=0; y<256; y++)
      for(x=0; x<256; x++)
	F1[y][x]=F2[y][x]=10.*exp(-0.1*((x-128)*(x-128)+(y-128)*(y-128)) )
	  +1.*exp(-0.1*((y-100)*(y-100)) );
  /*    F1[128][128]=5.;
    for(x=0; x<256; x++)
      F1[100][x]=F2[100][x]=1.5;
      /*/
for(n=0; n<5000; n++)
  {
    for(y=0; y<256; y++)
      {
	for(x=0; x<256; x++)
	  {
	    c=F1[y][x]*127+128;
	    Bilde[x*2+0 +(y*2+0)*512]=c;
	    Bilde[x*2+0 +(y*2+1)*512]=c;
	    Bilde[x*2+1 +(y*2+0)*512]=c;
	    Bilde[x*2+1 +(y*2+1)*512]=c;
	  }
      }
  XPutImage(display,window,gc, XBilde, 0,0, OrigoX-256,OrigoY-256, 512,512);

  for(y=1; y<255; y++)
    for(x=1; x<255; x++)
      F2[y][x]= 2.*F1[y][x]-F2[y][x]
	+0.4*(F1[y][x+1]+F1[y][x-1]+F1[y+1][x]+F1[y-1][x]-4.*F1[y][x]);
 for(y=1; y<255; y++)
    for(x=1; x<255; x++)
      {
	f=F1[y][x];
	F1[y][x]=F2[y][x];
	F2[y][x]=f;
      }
  }

  XSync(display,True);  sleep(40);
  XDestroyImage(XBilde);
  CloseX();
}




