// ................................................................. cartoon.cc
// ................................................................... #include
#include <curses.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <grdriver.h>
#include "corso.h"

extern "C" {int kbhit();}
VideoData vd;
GrTextOption to;

void func(double *t,double *y,double *dydt);

main()
{
  int DeltaSave,i,iy,iy0,iyf,iyf0;
  double dt,step,tMax,tMin,yScale,yScale2;
  double *tt,*y;
  char answ[122],buff[40];
  FILE *hnd;

  tt=new double [8];
  y=new double [2];
  // .............................................................. costanti
  tt[1]=0.3; //        massa
  tt[2]=50.0; //       costante di Hooke
  tt[3]=0.4; //        smorzamento
  tt[4]=15.0; //       frequenza di guida
  tt[5]=5.0; //        ampiezza di guida
  // ................................................... condizioni iniziali
  y[0]=0.0; //         posizione iniziale
  y[1]=0.0; //         velocita' iniziale
  // ................................................... intervallo di tempo
  step=0.003;
  // ......................................................... campionamento
  DeltaSave=4;
  // .......................................................... graphic mode
  GrInstall();
  GrClearScreen(vd.brightwhite);
  yScale=2000.0;
  yScale2=20.0;
  GrHLine(81,799,300,vd.black);
  GrVLine(80,0,599,vd.black);
  // .................................................................. scala
  GrPrintf(2*vd.dx,500-vd.hy,"-2.0");
  GrHLine(70,80,500,vd.black);
  GrPrintf(2*vd.dx,400-vd.hy,"-1.0");
  GrHLine(70,80,400,vd.black);
  GrPrintf(3*vd.dx,300-vd.hy,"0.0");
  GrHLine(70,80,300,vd.black);
  GrPrintf(3*vd.dx,200-vd.hy,"1.0");
  GrHLine(70,80,200,vd.black);
  GrPrintf(3*vd.dx,100-vd.hy,"2.0");
  GrHLine(70,80,100,vd.black);
  // ......................................................... punti iniziali
  iy0=300-(int)(y[0]*yScale);
  iyf0=300;
  // ................................................. first Runge-Kutta step
  tt[0]=0;
  RungeStep(tt,y,2,step,0,func);
  iy=300-(int)(0.5+(y[0]*yScale));
  iyf=300-(int)(0.5+tt[5]*sin(tt[4]*tt[0])*yScale2);
  GrLine(798,iy0,799,iy,vd.midred);
  GrLine(798,iyf0,799,iyf,vd.midblue);
  iy0=iy;
  iyf0=iyf;
  // ...................................................... Runge Kutta Loop
  for (i=1;;i++)
    { RungeStep(tt,y,2,step,1,func);
      if (i%DeltaSave) continue;
      iy=300-(int)(0.5+(y[0]*yScale));
      iyf=300-(int)(0.5+tt[5]*sin(tt[4]*tt[0])*yScale2);
      GrBitBlt(NULL,81,0,NULL,82,0,799,599,0);
      GrVLine(799,0,599,vd.brightwhite);
      GrHLine(798,799,300,vd.black);
      GrLine(798,iy0,799,iy,vd.midred);
      GrLine(798,iyf0,799,iyf,vd.midblue);
      iy0=iy;
      iyf0=iyf;
      if (kbhit()) break;
    }
  // .................................................. last Runge-Kutta step
  RungeStep(tt,y,2,step,2,func);
  // ........................................................................
  delete [] y;
  delete [] tt;
}

// ---------------------------------------------------------------------------

void func(double *t,double *y,double *dydt)
{ 
  double a,k,m,omega,relax;

  m=t[1];
  k=t[2];
  relax=t[3];
  omega=t[4];
  a=t[5];

  // ................................................................. velocita'
  dydt[0]=y[1];
  // ............................................................. accelerazione
  dydt[1]=-(k/m)*y[0]-(relax/m)*y[1]+a*sin(omega*t[0]);
}
