/*****************************************************************************/
char titolo[]="v3d: sysmo graphic metafile viewer - ver Apr 03, 2025 - 13:58.";
/*****************************************************************************/
/* per compilare mac:                                                        */
/* /usr/bin/gcc -w -static-libgcc -o v3d v3d.c -lm -framework GLUT           */
/*                                  -framework OpenGL -framework Cocoa       */
/* per compilare linux:                                                      */
/* gcc -w -static-libgcc -o v3d v3d.c -lm -lglut -lGLU -lGL                  */
/*****************************************************************************/
#if defined(__APPLE__)  && defined(__MACH__)
#include <GLUT/glut.h>
#elif defined(__linux__)
#include <GL/glut.h>
#endif
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <string.h>
#include <sys/stat.h>
#include <time.h>

#define DIMWIN 800
#define PI 3.1415926535898
#define NPC 25
#define NUMCOL 54
#define drawOneLine(x1,y1,x2,y2) glBegin(GL_LINES); \
  glVertex2f((x1),(y1)); glVertex2f((x2),(y2)); glEnd();

/*********elementi del grafico*************/
/* distingue vari tipi di elementi        */
/* tipo=1 linee piene con contorno        */
/* tipo=2 tondi pieni con contorno        */
/* tipo=3 frecce piene con contorno       */
/* tipo=4 triangoli pieni                 */
/* tipo=5 numeri                          */
/* tipo=6 traiettorie animate             */
/* tipo=7 frecce movie                    */
/* tipo=8 quadrangoli pieni               */
/******************************************/
struct linea{  // 1
    float x[2],  y[2],  z[2];
    float xr[2], yr[2], zr[2];
    float sps;
    int clr;
} *linee;
int nolin;

struct tondo{  // 2
    float x,  y,  z;
    float xr, yr, zr;
    float rgg;
    int clr;
} *tondi;
int notnd;

struct freccia{  // 3
    float x[7],  y[7],  z[7];
    float xr[7], yr[7], zr[7];
    int clr;
} *frecce;
int nofrc;

struct triangolo{  // 4
    float x[3], y[3], z[3];
    float xr[3], yr[3], zr[3];
    int lt[3];
    int clr;
} *triangoli;
int notri;

struct numero{  // 5
	float x, y, z;
	float xr, yr, zr;
	float nmr;
	float shx;
	float shy;
	int tipo;
	int asino;
} *numeri;
int nonum;

struct quadrangolo{  // 8
    float x[4], y[4], z[4];
    float xr[4], yr[4], zr[4];
    int clr;
} *quadrangoli;
int noqua;

struct elemento{
  float dist;
  int tipo;
  int num;
} *elementi;
int noele;

/*************strutture per traiettorie animate*******/
int trjf=0; // flag animazione
struct traiettoria{  // 6
    int inizio;
    int fine;
    int diviso;
    int nopunti;
    int vedo;
    float dismp;
    float spazio;
    float velop;
} *traiettorie;
int notrj; // numero traiettorie
struct trjdato{
    float x,y,z;
    float xr,yr,zr;
    float j;   // modulo densita' di corrente
    float r;   // densita' di carica
    float v;   // modulo velocità
    float clr; // intensita' colore
} *trjdati;
int nopnttrj; // numero totale di punti somma tutte le traiettorie

/***********strutture per movie frecce*************/
int frmf=0;  // movie flag
struct frame{  // 7
    int inizio;
    int fine;
    int nopunti;
} *frames;
int nofrm; // numero di frames
struct frmdato{
    float x[7],  y[7],  z[7];
    float xr[7], yr[7], zr[7];
    int clr;
} *frmdati;
int nopntfrm; // numero totale di frecce somma tutti i frames
float dtmp; // delta tempo per frame

/**********coordinate punti cerchio di raggio unitario*****/
float xc[NPC],yc[NPC];

/***************Colori*****/
float red[NUMCOL],green[NUMCOL],blue[NUMCOL];

/**************ampiezza finestra*****/
float wmin,wmax;
int dimwin;

/*************coordinate centro figura***/
float coordzero[3];

/********************variabili di controllo*****/
int batch=0;
int stereo=0;
int centra=1;
int numbers=1;
int numsel=0;
float segno=1.0;
int colore=0;
float di=30.0;
float tx=0.0;
float ty=0.0;
float tz=0.0;
float fi=0.7;
float dark=0.0;
float a=0.0,b=0.0,g=0.0;   // angoli di eulero
float rot=3.0;
float sbc=2.0;
float ridlt=0.50,ridfr=0.80;
int asize=4;
float fog2=60.0;
int dirty_trick=1;
int encaps=0;
int encax1=130;
int encay1=260;
int encax2=455;
int encay2=585;
float spssinizio=5.0; // spessore tratto iniziale delle traiettorie
float romin=+1000.0,romax=-1000.0; // intervallo di colore: se ro<=romin bianco; se ro>=romax rosso

/********************file names*****/
char filemt[180];
char fileps[180];
char fileeps[180];
char filtrj[180];
char filmov[180];

/********************matrice di rotazione*****/
float t[3][3];

/********************deltas*****/
float deltad=0.1;
float DeltaD=1.0;
float deltaf=0.01;
float DeltaF=0.1;
float deltan=0.1;
float DeltaN=1.0;
float deltaa=1.0;
float DeltaA=10.0;
float deltab=1.0;
float DeltaB=10.0;
float deltag=1.0;
float DeltaG=10.0;
float deltarot=0.1;
float deltasbc=0.1;
float dridlt=0.01,dridfr=0.01;
float deltadark=0.01;
float deltaromax=0.1;
float deltaromin=0.001;
float deltaspssinizio=0.1;

/*********************posizione mouse*****/
int xglob=1;
int yglob=1;
int bglob=1;

/*********************controllo modifica input file*****/
unsigned int msecs=1000;
struct stat stbuf;
time_t tlm0;
time_t tlm1;

/********************controllo animazione traiettorie****/
double Tempo=0.0;
float  DeltaT=0.0;

/********************dichiarazioni functions****/
int leggeelefig(void);




/******************************************************************************/
/******************************************************************************/
/******************************************************************************/



/******************************************************************************/
void eulero(void)
/******************************************************************************/
{
// calcola la matrice di rotazione
// per i tre angoli di Eulero a,b,g
// secondo la convenzione ZXZ
  float c1,c2,c3,s1,s2,s3;
  c1=cos(a*0.01745329);
  c2=cos(b*0.01745329);
  c3=cos(g*0.01745329);
  s1=sin(a*0.01745329);
  s2=sin(b*0.01745329);
  s3=sin(g*0.01745329);
  t[0][0]=c1*c3-s1*c2*s3;
  t[1][1]=c1*c2*c3-s1*s3;
  t[2][2]=c2;
  t[1][0]=c1*c2*s3+s1*c3;
  t[2][0]=s2*s3;
  t[0][1]=-s1*c2*c3-c1*s3;
  t[2][1]=s2*c3;
  t[0][2]=s1*s2;
  t[1][2]=-c1*s2;
}


/******************************************************************************/
float tmt(float alfa,float beta,float gama)
/******************************************************************************/
{
// calcola la somma del quadrato
// degli scarti tra la matrice
// di rotazione corrente e quella per gli
// angoli di prova alfa, beta, gamma
// secondo la convenzione ZXZ  
  float c1,c2,c3,s1,s2,s3,sqs;
  c1=cos(alfa);
  c2=cos(beta);
  c3=cos(gama);
  s1=sin(alfa);
  s2=sin(beta);
  s3=sin(gama);
  sqs =pow(t[0][0]-(c1*c3-s1*c2*s3),2);
  sqs+=pow(t[1][1]-(c1*c2*c3-s1*s3),2);
  sqs+=pow(t[2][2]-(c2),2);
  sqs+=pow(t[1][0]-(c1*c2*s3+s1*c3),2);
  sqs+=pow(t[2][0]-(s2*s3),2);
  sqs+=pow(t[0][1]-(-s1*c2*c3-c1*s3),2);
  sqs+=pow(t[2][1]-(s2*c3),2);
  sqs+=pow(t[0][2]-(s1*s2),2);
  sqs+=pow(t[1][2]-(-c1*s2),2);
  return sqs;
}


/******************************************************************************/
void getang(void)
/******************************************************************************/
{
// determina gli angoli di Eulero dalla
// matrice di rotazione corrente
// secondo la convenzione ZXZ
  float beta,alfa1,gama1,alfa2,gama2,epsi=0.000001;
  beta=acos(t[2][2]);
  alfa1=atan2(t[0][2],-t[1][2]);
  gama1=atan2(t[2][0], t[2][1]);
  if(alfa1>=0.0)alfa2=alfa1-PI;
  else          alfa2=alfa1+PI;
  if(gama1>=0.0)gama2=gama1-PI;
  else          gama2=gama1+PI;
  if(tmt(alfa1,beta,gama1)<epsi){a=alfa1/0.01745329;b=beta/0.01745329;g=gama1/0.01745329;}
  else if(tmt(alfa1,beta,gama2)<epsi){a=alfa1/0.01745329;b=beta/0.01745329;g=gama2/0.01745329;}
       else if(tmt(alfa2,beta,gama1)<epsi){a=alfa2/0.01745329;b=beta/0.01745329;g=gama1/0.01745329;}
            else if(tmt(alfa2,beta,gama2)<epsi){a=alfa2/0.01745329;b=beta/0.01745329;g=gama2/0.01745329;}
                 else{printf("GULP!\n");}
}


/******************************************************************************/
void circle(float x,float y,float r,int pieno)
/******************************************************************************/
{
  int j;

  if(pieno) glBegin(GL_POLYGON);
  else      glBegin(GL_LINE_LOOP);
  for(j=0; j<NPC; j++)
    glVertex2f(xc[j]*r+x,yc[j]*r+y);
  glEnd();
}


/******************************************************************************/
void arrow(float *x,float *y,int pieno)
/******************************************************************************/
{
//                   2
//       5 + + + + + 4  + 
//       +           +    1
//       6 + + + + + 7  +
//                   3
  if(pieno) glBegin(GL_POLYGON);
  else      glBegin(GL_LINE_LOOP);
    glVertex2f(x[0],y[0]);
    glVertex2f(x[1],y[1]);
    glVertex2f(x[2],y[2]);
  glEnd();
  if(pieno) glBegin(GL_POLYGON);
  else      glBegin(GL_LINE_LOOP);
    glVertex2f(x[3],y[3]);
    glVertex2f(x[4],y[4]);
    glVertex2f(x[5],y[5]);
    glVertex2f(x[6],y[6]);
  glEnd();
}


/******************************************************************************/
void triangle(float *x,float *y)
/******************************************************************************/
{
//       2
//       +  + 
//       +    1
//       +  +
//       3
  glBegin(GL_POLYGON);
    glVertex2f(x[0],y[0]);
    glVertex2f(x[1],y[1]);
    glVertex2f(x[2],y[2]);
  glEnd();
}


/******************************************************************************/
void quadrangle(float *x,float *y)
/******************************************************************************/
{
//       2
//     +    + 
//   3        1
//     +    +
//       4
  glBegin(GL_POLYGON);
    glVertex2f(x[0],y[0]);
    glVertex2f(x[1],y[1]);
    glVertex2f(x[2],y[2]);
    glVertex2f(x[3],y[3]);
  glEnd();
}


/******************************************************************************/
void rdo(void)
/******************************************************************************/
{
  int i,j,imax;
  float x,y,z;
  float x0,y0,z0;
  float x1,y1,z1;
  float x2,y2,z2;
  float x3,y3,z3;
  float x4,y4,z4;
  float x5,y5,z5;
  float x6,y6,z6;
  float x7,y7,z7;
  float aux;
  float bf,ss,dlt,vux,vuy,vuz,vum,jx,jy,jz,cx,cy,cz;

/***calcola le coords dei punti degli elementi della figura rispetto al pdv****/ 
/***********calcola distanza tra centro-elementi e punto-di-vista**************/
/*******************ordina gli elementi della figura***************************/

  noele=0;
  for(i=0;i<nolin;i++){
    linee[i].xr[0]=(t[0][0]*linee[i].x[0]+t[0][1]*linee[i].y[0]+t[0][2]*linee[i].z[0])*fi+tx;
    linee[i].yr[0]=(t[1][0]*linee[i].x[0]+t[1][1]*linee[i].y[0]+t[1][2]*linee[i].z[0])*fi-di;
    linee[i].zr[0]=(t[2][0]*linee[i].x[0]+t[2][1]*linee[i].y[0]+t[2][2]*linee[i].z[0])*fi+ty;
    linee[i].xr[1]=(t[0][0]*linee[i].x[1]+t[0][1]*linee[i].y[1]+t[0][2]*linee[i].z[1])*fi+tx;
    linee[i].yr[1]=(t[1][0]*linee[i].x[1]+t[1][1]*linee[i].y[1]+t[1][2]*linee[i].z[1])*fi-di;
    linee[i].zr[1]=(t[2][0]*linee[i].x[1]+t[2][1]*linee[i].y[1]+t[2][2]*linee[i].z[1])*fi+ty;
    x=(linee[i].xr[0]+linee[i].xr[1])/2.0;
    y=(linee[i].yr[0]+linee[i].yr[1])/2.0;
    z=(linee[i].zr[0]+linee[i].zr[1])/2.0;
    elementi[noele].dist=sqrt(x*x+y*y+z*z);
    elementi[noele].tipo=1;
    elementi[noele].num=i;
    noele++;
  }    
  for(i=0;i<notnd;i++){
    tondi[i].xr=(t[0][0]*tondi[i].x+t[0][1]*tondi[i].y+t[0][2]*tondi[i].z)*fi+tx;
    tondi[i].yr=(t[1][0]*tondi[i].x+t[1][1]*tondi[i].y+t[1][2]*tondi[i].z)*fi-di;
    tondi[i].zr=(t[2][0]*tondi[i].x+t[2][1]*tondi[i].y+t[2][2]*tondi[i].z)*fi+ty;
    x=tondi[i].xr;
    y=tondi[i].yr;
    z=tondi[i].zr;
    elementi[noele].dist=sqrt(x*x+y*y+z*z);
    elementi[noele].tipo=2;
    elementi[noele].num=i;
    noele++;
  }
  for(i=0;i<nofrc;i++){ 
    for(j=0;j<7;j++){
      frecce[i].xr[j]=(t[0][0]*frecce[i].x[j]+t[0][1]*frecce[i].y[j]+t[0][2]*frecce[i].z[j])*fi+tx;
      frecce[i].yr[j]=(t[1][0]*frecce[i].x[j]+t[1][1]*frecce[i].y[j]+t[1][2]*frecce[i].z[j])*fi-di;
      frecce[i].zr[j]=(t[2][0]*frecce[i].x[j]+t[2][1]*frecce[i].y[j]+t[2][2]*frecce[i].z[j])*fi+ty;
    }    
/******************************************************************************/
/******************************************************************************/
// se dirty_trick=vero ruota la normale del piano della frecce verso il PdV 
    if(dirty_trick){ 
      x=(frecce[i].xr[2]-frecce[i].xr[1]);
      y=(frecce[i].yr[2]-frecce[i].yr[1]);
      z=(frecce[i].zr[2]-frecce[i].zr[1]);
      bf=sqrt(x*x+y*y+z*z)/2.0;
      x=(frecce[i].xr[5]-frecce[i].xr[4]);
      y=(frecce[i].yr[5]-frecce[i].yr[4]);
      z=(frecce[i].zr[5]-frecce[i].zr[4]);
      ss=sqrt(x*x+y*y+z*z)/2.0;
      x0=(frecce[i].xr[5]+frecce[i].xr[4])/2.0;
      y0=(frecce[i].yr[5]+frecce[i].yr[4])/2.0;
      z0=(frecce[i].zr[5]+frecce[i].zr[4])/2.0;
      x1=frecce[i].xr[0];
      y1=frecce[i].yr[0];
      z1=frecce[i].zr[0];

      x=(frecce[i].xr[2]+frecce[i].xr[1])/2.0;
      y=(frecce[i].yr[2]+frecce[i].yr[1])/2.0;
      z=(frecce[i].zr[2]+frecce[i].zr[1])/2.0;

      aux=sqrt(x*x+y*y+z*z);
      cx=x/aux;
      cy=y/aux;
      cz=z/aux;
      jx=(x1-x0);
      jy=(y1-y0);
      jz=(z1-z0);
      aux=sqrt(jx*jx+jy*jy+jz*jz);
      jx=jx/aux;
      jy=jy/aux;
      jz=jz/aux;
      vux=cy*jz-cz*jy;
      vuy=cz*jx-cx*jz;
      vuz=cx*jy-cy*jx;
      vum=sqrt(vux*vux+vuy*vuy+vuz*vuz);
      if(vum<1.0E-6){vux=0.0; vuy=1.0; vuz=0.0;}
      else{vux=vux/vum; vuy=vuy/vum; vuz=vuz/vum;}
// ricalcola le coordinate dei punti 2,3
      dlt=bf*vux;
      x2=x-dlt;
      x3=x+dlt;
      dlt=bf*vuy;
      y2=y-dlt;
      y3=y+dlt;
      dlt=bf*vuz;
      z2=z-dlt;
      z3=z+dlt;
// ricalcola le coordinate dei punti 4,5,6,7
      dlt=ss*vux;
      x4=x -dlt;
      x5=x0-dlt;
      x6=x0+dlt;
      x7=x +dlt;
      dlt=ss*vuy;
      y4=y -dlt;
      y5=y0-dlt;
      y6=y0+dlt;
      y7=y +dlt;
      dlt=ss*vuz;
      z4=z -dlt;
      z5=z0-dlt;
      z6=z0+dlt;
      z7=z +dlt;
      frecce[i].xr[0]=x1;
      frecce[i].yr[0]=y1;
      frecce[i].zr[0]=z1;
      frecce[i].xr[1]=x2;
      frecce[i].yr[1]=y2;
      frecce[i].zr[1]=z2;
      frecce[i].xr[2]=x3;
      frecce[i].yr[2]=y3;
      frecce[i].zr[2]=z3;
      frecce[i].xr[3]=x4;
      frecce[i].yr[3]=y4;
      frecce[i].zr[3]=z4;
      frecce[i].xr[4]=x5;
      frecce[i].yr[4]=y5;
      frecce[i].zr[4]=z5;
      frecce[i].xr[5]=x6;
      frecce[i].yr[5]=y6;
      frecce[i].zr[5]=z6;
      frecce[i].xr[6]=x7;
      frecce[i].yr[6]=y7;
      frecce[i].zr[6]=z7;
    }
// fine dirty_trick 
/******************************************************************************/
/******************************************************************************/
    x=(frecce[i].xr[4]+frecce[i].xr[5])/2.0;
    y=(frecce[i].yr[4]+frecce[i].yr[5])/2.0;
    z=(frecce[i].zr[4]+frecce[i].zr[5])/2.0;
    x=(frecce[i].xr[0]+x)/2.0;
    y=(frecce[i].yr[0]+y)/2.0;
    z=(frecce[i].zr[0]+z)/2.0;
    elementi[noele].dist=sqrt(x*x+y*y+z*z);
    elementi[noele].tipo=3;
    elementi[noele].num=i;
    noele++;
  }
  for(i=0;i<notri;i++){ 
    x=y=z=0.0;
    for(j=0;j<3;j++){
      triangoli[i].xr[j]=(t[0][0]*triangoli[i].x[j]+t[0][1]*triangoli[i].y[j]+t[0][2]*triangoli[i].z[j])*fi+tx;
      triangoli[i].yr[j]=(t[1][0]*triangoli[i].x[j]+t[1][1]*triangoli[i].y[j]+t[1][2]*triangoli[i].z[j])*fi-di;
      triangoli[i].zr[j]=(t[2][0]*triangoli[i].x[j]+t[2][1]*triangoli[i].y[j]+t[2][2]*triangoli[i].z[j])*fi+ty;
      x+=triangoli[i].xr[j]/3.0;
      y+=triangoli[i].yr[j]/3.0;
      z+=triangoli[i].zr[j]/3.0;
    }    
    elementi[noele].dist=sqrt(x*x+y*y+z*z);
    elementi[noele].tipo=4;
    elementi[noele].num=i;
    noele++;
  }
  for(i=0;i<nonum;i++){
    numeri[i].xr=(t[0][0]*numeri[i].x+t[0][1]*numeri[i].y+t[0][2]*numeri[i].z)*fi+tx;
    numeri[i].yr=(t[1][0]*numeri[i].x+t[1][1]*numeri[i].y+t[1][2]*numeri[i].z)*fi-di;
    numeri[i].zr=(t[2][0]*numeri[i].x+t[2][1]*numeri[i].y+t[2][2]*numeri[i].z)*fi+ty;
    x=numeri[i].xr;
    y=numeri[i].yr;
    z=numeri[i].zr;
    elementi[noele].dist=sqrt(x*x+y*y+z*z);
    elementi[noele].tipo=5;
    elementi[noele].num=i;
    noele++;
  }
  for(i=0;i<nopnttrj;i++){
    trjdati[i].xr=(t[0][0]*trjdati[i].x+t[0][1]*trjdati[i].y+t[0][2]*trjdati[i].z)*fi+tx;
    trjdati[i].yr=(t[1][0]*trjdati[i].x+t[1][1]*trjdati[i].y+t[1][2]*trjdati[i].z)*fi-di;
    trjdati[i].zr=(t[2][0]*trjdati[i].x+t[2][1]*trjdati[i].y+t[2][2]*trjdati[i].z)*fi+ty;
    x=trjdati[i].xr;
    y=trjdati[i].yr;
    z=trjdati[i].zr;
    elementi[noele].dist=sqrt(x*x+y*y+z*z);
    elementi[noele].tipo=6;
    elementi[noele].num=i;
    noele++;
  }
  for(i=0;i<noqua;i++){ 
    x=y=z=0.0;
    for(j=0;j<4;j++){
      quadrangoli[i].xr[j]=(t[0][0]*quadrangoli[i].x[j]+t[0][1]*quadrangoli[i].y[j]+t[0][2]*quadrangoli[i].z[j])*fi+tx;
      quadrangoli[i].yr[j]=(t[1][0]*quadrangoli[i].x[j]+t[1][1]*quadrangoli[i].y[j]+t[1][2]*quadrangoli[i].z[j])*fi-di;
      quadrangoli[i].zr[j]=(t[2][0]*quadrangoli[i].x[j]+t[2][1]*quadrangoli[i].y[j]+t[2][2]*quadrangoli[i].z[j])*fi+ty;
      x+=quadrangoli[i].xr[j]/4.0;
      y+=quadrangoli[i].yr[j]/4.0;
      z+=quadrangoli[i].zr[j]/4.0;
    }    
    elementi[noele].dist=sqrt(x*x+y*y+z*z);
    elementi[noele].tipo=8;
    elementi[noele].num=i;
    noele++;
  }
          
/************************ordina gli elementi per distanza decrescente*****/
  for(i=0;i<noele-1;i++){
      imax=i;
      for(j=i+1;j<noele;j++) if(elementi[j].dist>elementi[imax].dist)imax=j;
      if(i!=imax){
          aux=elementi[i].dist;
          elementi[i].dist=elementi[imax].dist;
          elementi[imax].dist=aux;
          j=elementi[i].num;
          elementi[i].num=elementi[imax].num;
          elementi[imax].num=j;
          j=elementi[i].tipo;
          elementi[i].tipo=elementi[imax].tipo;
          elementi[imax].tipo=j;
      }
  }                
}


/******************************************************************************/
int init(int w, int h)
/******************************************************************************/
{
  int i;
  float xmin=0.0;
  float ymin=0.0;
  float zmin=0.0;
  float xmax=0.0;
  float ymax=0.0;
  float zmax=0.0;

/*********inizializza le coordinate dei punti del cerchio di raggio 1***/
  for(i=0; i<NPC; i++){
    xc[i]=cos(2*PI*i/NPC);
    yc[i]=sin(2*PI*i/NPC);
  }

/**********inizializza i colori*****/
  red[0] =1.0; green[0] =0.0; blue[0] =0.0;  //rosso
  red[1] =0.0; green[1] =1.0; blue[1] =0.0;  //verde
  red[2] =0.0; green[2] =0.0; blue[2] =1.0;  //blu
  red[3] =0.0; green[3] =1.0; blue[3] =1.0;  //ciano
  red[4] =1.0; green[4] =0.0; blue[4] =1.0;  //magenta
  red[5] =1.0; green[5] =1.0; blue[5] =0.0;  //giallo
  red[6] =0.0; green[6] =0.0; blue[6] =0.0;  //nero
//CPK
  red[7] =200.0/255.0; green[7] =200.0/255.0; blue[7] =200.0/255.0;  // hydrogen
  red[8] =100.0/255.0; green[8] =100.0/255.0; blue[8] =100.0/255.0;  // carbon
  red[9] = 48.0/255.0; green[9] = 80.0/255.0; blue[9] =248.0/255.0;  // nitrogen
  red[10]=255.0/255.0; green[10]= 13.0/255.0; blue[10]= 13.0/255.0;  // oxygen
  red[11]= 31.0/255.0; green[11]=240.0/255.0; blue[11]= 31.0/255.0;  // fluorine,chlorine
  red[12]=166.0/255.0; green[12]= 41.0/255.0; blue[12]= 41.0/255.0;  // bromine
  red[13]=148.0/255.0; green[13]=  0.0/255.0; blue[13]=148.0/255.0;  // iodine
  red[14]=  0.0/255.0; green[14]=  1.0/255.0; blue[14]=  1.0/255.0;  // noble gases
  red[15]=255.0/255.0; green[15]=128.0/255.0; blue[15]=  0.0/255.0;  // phosphorus
  red[16]=255.0/255.0; green[16]=255.0/255.0; blue[16]= 48.0/255.0;  // sulfur
  red[17]=255.0/255.0; green[17]=181.0/255.0; blue[17]=181.0/255.0;  // boron
  red[18]=143.0/255.0; green[18]= 64.0/255.0; blue[18]=212.0/255.0;  // alkali metals
  red[19]= 61.0/255.0; green[19]=255.0/255.0; blue[19]=  0.0/255.0;  // alkaline earth
  red[20]=255.0/255.0; green[20]= 20.0/255.0; blue[20]=147.0/255.0;  // other elements
//Continuous diverging color map well suited to scientific visualization
//Cool to warm color map RGB values; 33 values from 0 to 1, step=1/32=0.03125
  red[21]= 59.0/255.0; green[21]= 76.0/255.0; blue[21]=192.0/255.0;
  red[22]= 68.0/255.0; green[22]= 90.0/255.0; blue[22]=204.0/255.0;
  red[23]= 77.0/255.0; green[23]=104.0/255.0; blue[23]=215.0/255.0;
  red[24]= 87.0/255.0; green[24]=117.0/255.0; blue[24]=225.0/255.0;
  red[25]= 98.0/255.0; green[25]=130.0/255.0; blue[25]=234.0/255.0;
  red[26]=108.0/255.0; green[26]=142.0/255.0; blue[26]=241.0/255.0;
  red[27]=119.0/255.0; green[27]=154.0/255.0; blue[27]=247.0/255.0;
  red[28]=130.0/255.0; green[28]=165.0/255.0; blue[28]=251.0/255.0;
  red[29]=141.0/255.0; green[29]=176.0/255.0; blue[29]=254.0/255.0;
  red[30]=152.0/255.0; green[30]=185.0/255.0; blue[30]=255.0/255.0;
  red[31]=163.0/255.0; green[31]=194.0/255.0; blue[31]=255.0/255.0;
  red[32]=174.0/255.0; green[32]=201.0/255.0; blue[32]=253.0/255.0;
  red[33]=184.0/255.0; green[33]=208.0/255.0; blue[33]=249.0/255.0;
  red[34]=194.0/255.0; green[34]=213.0/255.0; blue[34]=244.0/255.0;
  red[35]=204.0/255.0; green[35]=217.0/255.0; blue[35]=238.0/255.0;
  red[36]=213.0/255.0; green[36]=219.0/255.0; blue[36]=230.0/255.0;
  red[37]=221.0/255.0; green[37]=221.0/255.0; blue[37]=221.0/255.0;
  red[38]=229.0/255.0; green[38]=216.0/255.0; blue[38]=209.0/255.0;
  red[39]=236.0/255.0; green[39]=211.0/255.0; blue[39]=197.0/255.0;
  red[40]=241.0/255.0; green[40]=204.0/255.0; blue[40]=185.0/255.0;
  red[41]=245.0/255.0; green[41]=196.0/255.0; blue[41]=173.0/255.0;
  red[42]=247.0/255.0; green[42]=187.0/255.0; blue[42]=160.0/255.0;
  red[43]=247.0/255.0; green[43]=177.0/255.0; blue[43]=148.0/255.0;
  red[44]=247.0/255.0; green[44]=166.0/255.0; blue[44]=135.0/255.0;
  red[45]=244.0/255.0; green[45]=154.0/255.0; blue[45]=123.0/255.0;
  red[46]=241.0/255.0; green[46]=141.0/255.0; blue[46]=111.0/255.0;
  red[47]=236.0/255.0; green[47]=127.0/255.0; blue[47]= 99.0/255.0;
  red[48]=229.0/255.0; green[48]=112.0/255.0; blue[48]= 88.0/255.0;
  red[49]=222.0/255.0; green[49]= 96.0/255.0; blue[49]= 77.0/255.0;
  red[50]=213.0/255.0; green[50]= 80.0/255.0; blue[50]= 66.0/255.0;
  red[51]=203.0/255.0; green[51]= 62.0/255.0; blue[51]= 56.0/255.0;
  red[52]=192.0/255.0; green[52]= 40.0/255.0; blue[52]= 47.0/255.0;
  red[53]=180.0/255.0; green[53]=  4.0/255.0; blue[53]= 38.0/255.0;

/**********legge gli elementi della figura*****/
leggeelefig();

/********************determina l'ampiezza della finestra*****/
  xmin-=coordzero[0];
  xmax-=coordzero[0];
  ymin-=coordzero[1];
  ymax-=coordzero[1];
  zmin-=coordzero[2];
  zmax-=coordzero[2];
  if(xmax-xmin>ymax-ymin)
    if(xmax-xmin>zmax-zmin){
      wmax=xmax;
      wmin=xmin;
    }
    else{
      wmax=zmax;
      wmin=zmin;
    }
  else
    if(ymax-ymin>zmax-zmin){
      wmax=ymax;
      wmin=ymin;
    }
    else{
      wmax=zmax;
      wmin=zmin;
    }
    wmin=-6.65;
    wmax=+6.65;
  printf("wmin=%f wmax=%f\n",wmin,wmax);
  printf("On-line help is available pressing the keyboard key <h>.\n");
  printf("Please remember that focus has to be on the graphic window.\n");

/********************imposta a bianco il colore dello sfondo*****/
/********************imposta l'ampiezza della finestra*****/
  glEnable(GL_LINE_SMOOTH);
  glEnable(GL_BLEND);
  glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  glHint(GL_LINE_SMOOTH_HINT, GL_DONT_CARE);
  glClearColor(1.0, 1.0, 1.0, 0.0);
  glShadeModel(GL_FLAT);
  glViewport(0, 0, (GLsizei) w, (GLsizei) h);
  glMatrixMode(GL_PROJECTION);
  glLoadIdentity();
  gluOrtho2D(wmin,wmax,wmin,wmax);
  return 0;
}


/*********************************************************************/
void writepsfile(char *fileout)
/*********************************************************************/
{
  FILE *fp;
  int i,j,k,tipo,num,perbene;
  float capp;
  float offsetx[2],offsety[2];
  float orip[7],verp[7];
  float x,y,z,d,cx,cy,cz,dp,xp,yp,rf;
  float ppp=72.0/2.54;
  float dimdisa4=12.5;
  float dimstra4=6.25;
  float pagsixa4=21.0;
  float pagsiya4=29.7;
  float powsqr2=1.0;
  float dimdis,dimstr,pgx,pgy;
  float fog1,fogd,umfog,fog,rosso,verde,bluuu,spsln;
  char buf[9];

/******inizializza le dimensioni della pag PS per i casi stereo e non stereo***/ 
  for(k=4;k>asize;k--)powsqr2=powsqr2*sqrt(2.0);
  dimdis=dimdisa4*powsqr2;
  dimstr=dimstra4*powsqr2;
  pgx   =pagsixa4*powsqr2;
  pgy   =pagsiya4*powsqr2;
  if(!stereo){
    capp=dimdis*ppp;
    capp=capp/(wmax-wmin);
    offsetx[0]=(dimdis/2.0*ppp)+(pgx-dimdis)/2.0*ppp;
    offsety[0]=(dimdis/2.0*ppp)+(pgy-dimdis)/2.0*ppp;
  }
  else{
    capp=dimstr*ppp;
    capp=capp/(wmax-wmin);
    offsetx[0]=(dimstr*0.69/2.0*ppp)+(pgx-2.0*dimstr*0.69)/2.0*ppp;
    offsetx[1]=offsetx[0]+dimstr*0.69*ppp;
    offsety[0]=(dimstr/2.0*ppp)+(pgy-dimstr)/2.0*ppp;
    offsety[1]=offsety[0]+dimstr*ppp;
  }

/**************************************apre il file PostScript*****/
  if((fp=fopen(fileout,"w"))==NULL){
    printf("open failed for file %s\n",fileout);
    return;
  }
  printf("Start writing file %s ",fileout);
  i=pgx*ppp;
  j=pgy*ppp;
  if(encaps){
	  fprintf(fp,"%%!PS-Adobe-3.0 EPSF-3.0\n");
	  fprintf(fp,"%%%%BoundingBox: %i %i %i %i\n",encax1,encay1,encax2,encay2);
  }
  else{
	  fprintf(fp,"%%!PS-Adobe-3.0 PSF-3.0\n");
	  fprintf(fp,"%%%%BoundingBox: 1 1 %i %i\n",i,j);
  }  
  fprintf(fp,"%%%%BeginProlog\n");                     
  fprintf(fp,"/arrowhead{\n");
  fprintf(fp,"  gsave\n");
  fprintf(fp,"    currentpoint\n");
  fprintf(fp,"    4 2 roll exch\n");
  fprintf(fp,"    4 -1 roll exch\n");
  fprintf(fp,"    sub 3 1 roll\n");
  fprintf(fp,"    sub exch\n");
  fprintf(fp,"    atan rotate\n");
  fprintf(fp,"    dup scale\n");
  fprintf(fp,"    -7 2 rlineto 1 -2 rlineto -1 -2 rlineto\n");
  fprintf(fp,"    closepath fill \n");
  fprintf(fp,"  grestore newpath\n");
  fprintf(fp,"} def\n");
  fprintf(fp,"%%%%EndProlog\n");                       
  fprintf(fp," %%! PostScript\n");

/**********************************il prossimo for gestisce due iterazioni*****/
/******************setero=0 una iterazione, figura come appare sul monitor*****/
/******************stereo=1 due iterazioni, calcola due rotazioni +-rot********/
  for(k=0;k<=stereo;k++){
    if(stereo&&(k==0)){
      a=a+rot;
      eulero();
      rdo();
    } 
    else if(stereo&&(k==1)){ 
      a=a-rot;
      eulero();
      rdo();
    }

  fog1=elementi[noele-1].dist-0.00002;
  if( fog2 <= fog1 )fog2=fog1+0.00001;
  fogd=fog2-fog1;
  
/***********************************disegna la figura************/
    for(i=0;i<noele;i++){
      tipo=elementi[i].tipo;
      num=elementi[i].num; 

    if( ( fog=(elementi[i].dist-fog1)/fogd ) > 1.0 ) fog=1.0;
    umfog=1.0-fog;

      if(tipo==1){    //linea
        for(j=0;j<2;j++){
          x=linee[num].xr[j];
          y=linee[num].yr[j];
          z=linee[num].zr[j];
          d=sqrt(x*x+y*y+z*z);
          cx=x/d;
          cy=y/d;
          cz=z/d;
          dp=-di/cy;
          xp=-dp*cx;
          yp= dp*cz;
          if(!stereo){
            orip[j]=xp*capp+offsetx[k];
            verp[j]=yp*capp+offsety[k];
	    spsln=0.22*linee[num].sps;
          }
          else{
            orip[j]=        (xp*capp+offsetx[k]);
            verp[j]=pgy*ppp-(-yp*capp+offsety[0]);
	    spsln=0.11*linee[num].sps;
          }
        }    
        fprintf(fp," newpath\n");
        fprintf(fp," 1 1 1 setrgbcolor\n");
        fprintf(fp," %8.2f %8.2f moveto\n",orip[0],verp[0]);
        fprintf(fp," %8.2f %8.2f lineto\n",orip[1],verp[1]);
        fprintf(fp," %8.2f setlinewidth stroke\n",spsln+sbc*ridlt);
        fprintf(fp," newpath\n");
        rosso=  red[linee[num].clr]*umfog+fog;
        verde=green[linee[num].clr]*umfog+fog;
        bluuu= blue[linee[num].clr]*umfog+fog;
        fprintf(fp," %8.2f %8.2f %8.2f setrgbcolor\n",rosso,verde,bluuu);
        fprintf(fp," %8.2f %8.2f moveto\n",orip[0],verp[0]);
        fprintf(fp," %8.2f %8.2f lineto\n",orip[1],verp[1]);
        fprintf(fp," %8.2f setlinewidth stroke\n",spsln);
      }    
      if(tipo==2){    //tondo
        x=tondi[num].xr;
        y=tondi[num].yr;
        z=tondi[num].zr;
        d=sqrt(x*x+y*y+z*z);
        cx=x/d;
        cy=y/d;
        cz=z/d;
        dp=-di/cy;
        xp=-dp*cx;
        yp= dp*cz;
        if(!stereo){
          orip[0]=xp*capp+offsetx[k];
          verp[0]=yp*capp+offsety[k];
        }
        else{
          orip[0]=        (xp*capp+offsetx[k]);
          verp[0]=pgy*ppp-(-yp*capp+offsety[0]);
        }
        rf=tondi[num].rgg*capp*fi;
        fprintf(fp," newpath\n");
        fprintf(fp," 1 1 1 setrgbcolor\n");
        fprintf(fp," %8.2f %8.2f %8.2f 0 360 arc\n",orip[0],verp[0],rf+sbc*ridlt);
        fprintf(fp," fill\n");
        fprintf(fp," newpath\n");
        rosso=  red[tondi[num].clr]*umfog+fog;
        verde=green[tondi[num].clr]*umfog+fog;
        bluuu= blue[tondi[num].clr]*umfog+fog;
        fprintf(fp," %8.2f %8.2f %8.2f setrgbcolor\n",rosso,verde,bluuu);
        fprintf(fp," %8.2f %8.2f %8.2f 0 360 arc\n",orip[0],verp[0],rf);
        fprintf(fp," fill\n");
      }
      if(tipo==3){    //freccia
        for(j=0;j<7;j++){
          x=frecce[num].xr[j];
          y=frecce[num].yr[j];
          z=frecce[num].zr[j];
          d=sqrt(x*x+y*y+z*z);
          cx=x/d;
          cy=y/d;
          cz=z/d;
          dp=-di/cy;
          xp=-dp*cx;
          yp= dp*cz;
          if(!stereo){
            orip[j]=xp*capp+offsetx[k];
            verp[j]=yp*capp+offsety[k];
          }
          else{
            orip[j]=        (xp*capp+offsetx[k]);
            verp[j]=pgy*ppp-(-yp*capp+offsety[0]);
          }
        }    
        fprintf(fp," newpath\n");
        fprintf(fp," 1 1 1 setrgbcolor\n");
        fprintf(fp," %8.2f %8.2f moveto\n",orip[0],verp[0]);
        fprintf(fp," %8.2f %8.2f lineto\n",orip[1],verp[1]);
        fprintf(fp," %8.2f %8.2f lineto\n",orip[2],verp[2]);
        fprintf(fp," closepath \n");
        fprintf(fp," %8.2f setlinewidth stroke\n",(0.000001+sbc)*ridfr);
        fprintf(fp," newpath\n");
        fprintf(fp," 1 1 1 setrgbcolor\n");
        fprintf(fp," %8.2f %8.2f moveto\n",orip[3],verp[3]);
        fprintf(fp," %8.2f %8.2f lineto\n",orip[4],verp[4]);
        fprintf(fp," %8.2f %8.2f lineto\n",orip[5],verp[5]);
        fprintf(fp," %8.2f %8.2f lineto\n",orip[6],verp[6]);
        fprintf(fp," closepath \n");
        fprintf(fp," %8.2f setlinewidth stroke\n",(0.000001+sbc)*ridfr);
        fprintf(fp," newpath\n");
        rosso=  red[frecce[num].clr]*umfog+fog;
        verde=green[frecce[num].clr]*umfog+fog;
        bluuu= blue[frecce[num].clr]*umfog+fog;
        fprintf(fp," %8.2f %8.2f %8.2f setrgbcolor\n",rosso,verde,bluuu);
        fprintf(fp," %8.2f %8.2f moveto\n",orip[0],verp[0]);
        fprintf(fp," %8.2f %8.2f lineto\n",orip[1],verp[1]);
        fprintf(fp," %8.2f %8.2f lineto\n",orip[2],verp[2]);
        fprintf(fp," closepath fill\n");
        fprintf(fp," newpath\n");
        rosso=  red[frecce[num].clr]*umfog+fog;
        verde=green[frecce[num].clr]*umfog+fog;
        bluuu= blue[frecce[num].clr]*umfog+fog;
        fprintf(fp," %8.2f %8.2f %8.2f setrgbcolor\n",rosso,verde,bluuu);
        fprintf(fp," %8.2f %8.2f moveto\n",orip[3],verp[3]);
        fprintf(fp," %8.2f %8.2f lineto\n",orip[4],verp[4]);
        fprintf(fp," %8.2f %8.2f lineto\n",orip[5],verp[5]);
        fprintf(fp," %8.2f %8.2f lineto\n",orip[6],verp[6]);
        fprintf(fp," closepath fill\n");
      }    
      if(tipo==4){    //triangolo
        for(j=0;j<3;j++){
          x=triangoli[num].xr[j];
          y=triangoli[num].yr[j];
          z=triangoli[num].zr[j];
          d=sqrt(x*x+y*y+z*z);
          cx=x/d;
          cy=y/d;
          cz=z/d;
          dp=-di/cy;
          xp=-dp*cx;
          yp= dp*cz;
          if(!stereo){
            orip[j]=xp*capp+offsetx[k];
            verp[j]=yp*capp+offsety[k];
          }
          else{
            orip[j]=        (xp*capp+offsetx[k]);
            verp[j]=pgy*ppp-(-yp*capp+offsety[0]);
          }
        }    
        fprintf(fp," newpath\n");
        fprintf(fp," 1 1 1 setrgbcolor\n");
        fprintf(fp," %8.2f %8.2f moveto\n",orip[0],verp[0]);
        fprintf(fp," %8.2f %8.2f lineto\n",orip[1],verp[1]);
        fprintf(fp," %8.2f %8.2f lineto\n",orip[2],verp[2]);
        fprintf(fp," closepath \n");
        fprintf(fp," %8.2f setlinewidth stroke\n",(0.000001+sbc)*ridfr);
        fprintf(fp," newpath\n");
        rosso=  red[triangoli[num].clr]*umfog+fog;
        verde=green[triangoli[num].clr]*umfog+fog;
        bluuu= blue[triangoli[num].clr]*umfog+fog;
        fprintf(fp," %8.2f %8.2f %8.2f setrgbcolor\n",rosso,verde,bluuu);
        fprintf(fp," %8.2f %8.2f moveto\n",orip[0],verp[0]);
        fprintf(fp," %8.2f %8.2f lineto\n",orip[1],verp[1]);
        fprintf(fp," %8.2f %8.2f lineto\n",orip[2],verp[2]);
        fprintf(fp," closepath fill\n");
      }    

// la visualizzazione dei numeri est spostata dopo come ultimi elementi
//      if(tipo==5 && numbers && numeri[num].asino){    //numero
//        x=numeri[num].xr;
//        y=numeri[num].yr;
//        z=numeri[num].zr;
//        perbene=numeri[num].nmr*100.0+0.5;
//        if(numeri[num].tipo==43) sprintf(buf,"%d",perbene);
//        if(numeri[num].tipo==77) sprintf(buf,"%8.3f",numeri[num].nmr);
//        d=sqrt(x*x+y*y+z*z);
//        cx=x/d;
//        cy=y/d;
//        cz=z/d;
//        dp=-di/cy;
//        xp=-dp*cx+numeri[num].shx;
//        yp= dp*cz+numeri[num].shy;
//        if(!stereo){
//          orip[0]=xp*capp+offsetx[k];
//          verp[0]=yp*capp+offsety[k];
//        }
//        else{
//          orip[0]=        (xp*capp+offsetx[k]);
//          verp[0]=pgy*ppp-(-yp*capp+offsety[0]);
//        }
//        rosso=  red[2]*umfog+fog;
//        verde=green[2]*umfog+fog;
//        bluuu= blue[2]*umfog+fog;
//        fprintf(fp," newpath\n");
//        fprintf(fp," %8.2f %8.2f %8.2f setrgbcolor\n",rosso,verde,bluuu);
//        fprintf(fp," /FSD {findfont exch scalefont def} bind def\n");
//        fprintf(fp," /SMS {setfont moveto show} bind def\n");
//        fprintf(fp," /Fb 9 /Helvetica FSD\n");
//        fprintf(fp," /Fm 7 /Helvetica FSD\n");
//        fprintf(fp," /Fs 5 /Helvetica FSD\n");
//        fprintf(fp," (%s) %8.2f %8.2f Fb SMS\n",buf,orip[0],verp[0]);
//        if(perbene>100)    fprintf(fp," (%s) %8.2f %8.2f Fm SMS\n",buf,orip[0],verp[0]);
//        else if(perbene>50)fprintf(fp," (%s) %8.2f %8.2f Fs SMS\n",buf,orip[0],verp[0]); 
//        else if(perbene>1) fprintf(fp," (%s) %8.2f %8.2f Fs SMS\n",buf,orip[0],verp[0]);
//        fprintf(fp," 1.00 setlinewidth stroke\n");
//      }
  
      if(tipo==8){    //quadrangolo
        for(j=0;j<4;j++){
          x=quadrangoli[num].xr[j];
          y=quadrangoli[num].yr[j];
          z=quadrangoli[num].zr[j];
          d=sqrt(x*x+y*y+z*z);
          cx=x/d;
          cy=y/d;
          cz=z/d;
          dp=-di/cy;
          xp=-dp*cx;
          yp= dp*cz;
          if(!stereo){
            orip[j]=xp*capp+offsetx[k];
            verp[j]=yp*capp+offsety[k];
          }
          else{
            orip[j]=        (xp*capp+offsetx[k]);
            verp[j]=pgy*ppp-(-yp*capp+offsety[0]);
          }
        }    
//        fprintf(fp," newpath\n");
//        fprintf(fp," 1 1 1 setrgbcolor\n");
//        fprintf(fp," %8.2f %8.2f moveto\n",orip[0],verp[0]);
//        fprintf(fp," %8.2f %8.2f lineto\n",orip[1],verp[1]);
//        fprintf(fp," %8.2f %8.2f lineto\n",orip[2],verp[2]);
//        fprintf(fp," %8.2f %8.2f lineto\n",orip[3],verp[3]);
//        fprintf(fp," closepath \n");
//        fprintf(fp," %8.2f setlinewidth stroke\n",(0.000001+sbc)*ridfr);
        fprintf(fp," newpath\n");
        rosso=  red[quadrangoli[num].clr]*umfog+fog;
        verde=green[quadrangoli[num].clr]*umfog+fog;
        bluuu= blue[quadrangoli[num].clr]*umfog+fog;
        fprintf(fp," %8.2f %8.2f %8.2f setrgbcolor\n",rosso,verde,bluuu);
        fprintf(fp," %8.2f %8.2f moveto\n",orip[0],verp[0]);
        fprintf(fp," %8.2f %8.2f lineto\n",orip[1],verp[1]);
        fprintf(fp," %8.2f %8.2f lineto\n",orip[2],verp[2]);
        fprintf(fp," %8.2f %8.2f lineto\n",orip[3],verp[3]);
        fprintf(fp," closepath fill\n");
      } 
    }

// visulaizzazione dei numeri
    for(i=0;i<noele;i++){
      tipo=elementi[i].tipo;
      num=elementi[i].num; 
      if(tipo==5 && numbers && numeri[num].asino){    //numero
        x=numeri[num].xr;
        y=numeri[num].yr;
        z=numeri[num].zr;
        perbene=numeri[num].nmr*100.0+0.5;
	if(numeri[num].tipo==43) sprintf(buf,"%d",perbene);
        if(numeri[num].tipo==77) sprintf(buf,"%8.3f",numeri[num].nmr);
        d=sqrt(x*x+y*y+z*z);
        cx=x/d;
        cy=y/d;
        cz=z/d;
        dp=-di/cy;
        xp=-dp*cx+numeri[num].shx;
        yp= dp*cz+numeri[num].shy;
        if(!stereo){
          orip[0]=xp*capp+offsetx[k];
          verp[0]=yp*capp+offsety[k];
        }
        else{
          orip[0]=        (xp*capp+offsetx[k]);
          verp[0]=pgy*ppp-(-yp*capp+offsety[0]);
        }
        rosso=  red[2]*umfog+fog;
        verde=green[2]*umfog+fog;
        bluuu= blue[2]*umfog+fog;
        fprintf(fp," newpath\n");
        fprintf(fp," %8.2f %8.2f %8.2f setrgbcolor\n",rosso,verde,bluuu);
	fprintf(fp," /FSD {findfont exch scalefont def} bind def\n");
	fprintf(fp," /SMS {setfont moveto show} bind def\n");
	fprintf(fp," /Fb 9 /Helvetica FSD\n");
        fprintf(fp," /Fm 7 /Helvetica FSD\n");
        fprintf(fp," /Fs 5 /Helvetica FSD\n");
//      fprintf(fp," (%s) %8.2f %8.2f Fb SMS\n",buf,orip[0],verp[0]);
        if(perbene>100)    fprintf(fp," (%s) %8.2f %8.2f Fm SMS\n",buf,orip[0],verp[0]);
        else if(perbene>50)fprintf(fp," (%s) %8.2f %8.2f Fs SMS\n",buf,orip[0],verp[0]); 
//      else if(perbene>1) fprintf(fp," (%s) %8.2f %8.2f Fs SMS\n",buf,orip[0],verp[0]);
        else  fprintf(fp," (%s) %8.2f %8.2f Fs SMS\n",buf,orip[0],verp[0]);
        fprintf(fp," 1.00 setlinewidth stroke\n");
      }
    }

  }
/*  fprintf(fp,"%% newpath\n");                                   */
/*  fprintf(fp,"%% %8.2f %8.2f %8.2f setrgbcolor\n",0.0,0.0,0.0); */
/*  fprintf(fp,"%% %8.2f %8.2f moveto\n",0.0,0.0);                */
/*  fprintf(fp,"%% 1 %6.2f %8.2f arrowhead\n",0.0,0.0);           */
  fprintf(fp," showpage\n");
  fprintf(fp,"%%%%EOF\n");
  fclose(fp);
  printf(" done!\n");

/************************se stereo rimette la rotazione a posto*****/
  if(stereo&&(k==0)){
    eulero();
    rdo();
  }    
}    


/******************************************************************************/
void display(void)
/******************************************************************************/
{
  int i,j,k,tipo,num,perbene;
  float x,y,z,d,cx,cy,cz,dp,xp0,yp0,xp1,yp1,xpc,ypc;
  float xpvf[7],ypvf[7];
  int lttr[3];
  float rf;
  float fog1,fogd,umfog,fog,rosso,verde,bluuu;
  char buf[9];
  char c;
    
/********************chiarisce la finestra*****/
  glClear(GL_COLOR_BUFFER_BIT);

/****se richiesto sostituisce le frecce con quelle nel frame corrispondente al tempo trascorso***/
  if(frmf){
    perbene=Tempo/dtmp;
    j=perbene%nofrm;
    for(i=0, k=frames[j].inizio; i<nofrc; i++, k++)
      for(j=0;j<7;j++){
        frecce[i].x[j] =frmdati[k].x[j];
        frecce[i].y[j] =frmdati[k].y[j];
        frecce[i].z[j] =frmdati[k].z[j];
        frecce[i].xr[j]=frmdati[k].xr[j];
        frecce[i].yr[j]=frmdati[k].yr[j];
        frecce[i].zr[j]=frmdati[k].zr[j];
        frecce[i].clr  =frmdati[k].clr;
    }
  }

/***ricalcola tutto***/
  rdo();

/********************disegna la figura*****/

  fog1=elementi[noele-1].dist-0.00002;
  if( fog2 <= fog1 )fog2=fog1+0.00001;
  fogd=fog2-fog1;
  
  for(i=0;i<noele;i++){
    tipo=elementi[i].tipo;
    num=elementi[i].num;  

    if( ( fog=(elementi[i].dist-fog1)/fogd ) > 1.0 ) fog=1.0;
    umfog=1.0-fog;

    if(tipo==1){    //linea
      x=linee[num].xr[0];
      y=linee[num].yr[0];
      z=linee[num].zr[0];
      d=sqrt(x*x+y*y+z*z);
      cx=x/d;
      cy=y/d;
      cz=z/d;
      dp=-di/cy;
      xp0=-dp*cx;
      yp0= dp*cz;
      x=linee[num].xr[1];
      y=linee[num].yr[1];
      z=linee[num].zr[1];
      d=sqrt(x*x+y*y+z*z);
      cx=x/d;
      cy=y/d;
      cz=z/d;
      dp=-di/cy;
      xp1=-dp*cx;
      yp1= dp*cz;
      glLineWidth(linee[num].sps+sbc);
      glColor3f(1.0, 1.0, 1.0);
      drawOneLine(xp0,yp0,xp1,yp1);
      glLineWidth(linee[num].sps);
      rosso=  red[linee[num].clr]*umfog+fog;
      verde=green[linee[num].clr]*umfog+fog;
      bluuu= blue[linee[num].clr]*umfog+fog;
      glColor3f(rosso,verde,bluuu);
      drawOneLine(xp0,yp0,xp1,yp1);
    }    
    if(tipo==2){    //tondo
      x=tondi[num].xr;
      y=tondi[num].yr;
      z=tondi[num].zr;
      d=sqrt(x*x+y*y+z*z);
      cx=x/d;
      cy=y/d;
      cz=z/d;
      dp=-di/cy;
      xpc=-dp*cx;
      ypc= dp*cz;
      rf=tondi[num].rgg*fi;
      glLineWidth(0.000001+sbc);
      glColor3f(1.0, 1.0, 1.0);
      circle(xpc,ypc,rf,0);
      glLineWidth(0.000001);
      rosso=  red[tondi[num].clr]*umfog+fog;
      verde=green[tondi[num].clr]*umfog+fog;
      bluuu= blue[tondi[num].clr]*umfog+fog;
      glColor3f(rosso,verde,bluuu);
      circle(xpc,ypc,rf,1);
    }    
    if(tipo==3){    //freccia
      for(j=0;j<7;j++){
        x=frecce[num].xr[j];
        y=frecce[num].yr[j];
        z=frecce[num].zr[j];
        d=sqrt(x*x+y*y+z*z);
        cx=x/d;
        cy=y/d;
        cz=z/d;
        dp=-di/cy;
        xpvf[j]=-dp*cx;
        ypvf[j]= dp*cz;
      }    
      glLineWidth(0.000001+sbc);
      glColor3f(1.0, 1.0, 1.0);
      arrow(xpvf,ypvf,0);
      glLineWidth(0.000001);
      rosso=  red[frecce[num].clr]*umfog+fog;
      verde=green[frecce[num].clr]*umfog+fog;
      bluuu= blue[frecce[num].clr]*umfog+fog;
      glColor3f(rosso,verde,bluuu);
      arrow(xpvf,ypvf,1);
    }    
    if(tipo==4){    //triangolo
      for(j=0;j<3;j++){
        x=triangoli[num].xr[j];
        y=triangoli[num].yr[j];
        z=triangoli[num].zr[j];
        lttr[j]=triangoli[num].lt[j];
        d=sqrt(x*x+y*y+z*z);
        cx=x/d;
        cy=y/d;
        cz=z/d;
        dp=-di/cy;
        xpvf[j]=-dp*cx;
        ypvf[j]= dp*cz;
      }    
      glLineWidth(0.000001);
      rosso=(  red[triangoli[num].clr]-dark)*umfog+fog;
      verde=(green[triangoli[num].clr]-dark)*umfog+fog;
      bluuu=( blue[triangoli[num].clr]-dark)*umfog+fog;
      glColor3f(rosso,verde,bluuu);
      triangle(xpvf,ypvf);
      glLineWidth(0.5);
      glColor3f(0.0,0.0,0.0);
      if(lttr[0])drawOneLine(xpvf[0],ypvf[0],xpvf[1],ypvf[1]);
      if(lttr[1])drawOneLine(xpvf[1],ypvf[1],xpvf[2],ypvf[2]);
      if(lttr[2])drawOneLine(xpvf[2],ypvf[2],xpvf[0],ypvf[0]);
    }    

// la visualizzazione dei numeri est spostata dopo come ultimi elementi
//  if(tipo==5 && numbers){    //numero
//    x=numeri[num].xr;
//    y=numeri[num].yr;
//    z=numeri[num].zr;
//    perbene=numeri[num].nmr*100.0+0.5;
//    if(numeri[num].tipo==43) sprintf(buf,"%d",perbene);
//    if(numeri[num].tipo==77) sprintf(buf,"%8.3f",numeri[num].nmr);
//    d=sqrt(x*x+y*y+z*z);
//    cx=x/d;
//    cy=y/d;
//    cz=z/d;
//    dp=-di/cy;
//    xpc=-dp*cx+numeri[num].shx;
//    ypc= dp*cz+numeri[num].shy;
//    if(num==numsel-1){
//            rosso=  red[4]*umfog+fog; //          0 1 2 3 4 5 6
//            verde=green[4]*umfog+fog; // magenta  r g b c m g n 
//            bluuu= blue[4]*umfog+fog;
//    }
//    else{
//            rosso=  red[2]*umfog+fog; //      0 1 2 3 4 5 6
//            verde=green[2]*umfog+fog; // blu  r g b c m g n
//            bluuu= blue[2]*umfog+fog; //
//    }
//    if( numeri[num].asino==0 && num==numsel-1){
//            rosso=  red[1]*umfog+fog; //        0 1 2 3 4 5 6
//            verde=green[1]*umfog+fog; // verde  r g b c m g n
//            bluuu= blue[1]*umfog+fog; //
//    }
//    if(numeri[num].asino || num==numsel-1){
//      glColor3f(rosso,verde,bluuu);
//      glRasterPos2f(xpc,ypc);
//      for(j=0;(c=buf[j])!='\0';j++)
//            glutBitmapCharacter(GLUT_BITMAP_HELVETICA_18,c);
//	      if(perbene>100)    glutBitmapCharacter(GLUT_BITMAP_HELVETICA_12,c);
//	      else if(perbene>50)glutBitmapCharacter(GLUT_BITMAP_HELVETICA_10,c); 
//	      else if(perbene>1) glutBitmapCharacter(GLUT_BITMAP_HELVETICA_10,c);
//    }
//  }    

    if(tipo==8){    //quadrangolo
      for(j=0;j<4;j++){
        x=quadrangoli[num].xr[j];
        y=quadrangoli[num].yr[j];
        z=quadrangoli[num].zr[j];
        d=sqrt(x*x+y*y+z*z);
        cx=x/d;
        cy=y/d;
        cz=z/d;
        dp=-di/cy;
        xpvf[j]=-dp*cx;
        ypvf[j]= dp*cz;
      }    
      glLineWidth(0.000001);
      rosso=(  red[quadrangoli[num].clr]-dark)*umfog+fog;
      verde=(green[quadrangoli[num].clr]-dark)*umfog+fog;
      bluuu=( blue[quadrangoli[num].clr]-dark)*umfog+fog;
      glColor3f(rosso,verde,bluuu);
      quadrangle(xpvf,ypvf);
    } 
  }      

// visualizzazione dei numeri
  for(i=0;i<noele;i++){
    tipo=elementi[i].tipo;
    num=elementi[i].num;  
    if(tipo==5 && numbers){    //numero
      x=numeri[num].xr;
      y=numeri[num].yr;
      z=numeri[num].zr;
      perbene=numeri[num].nmr*100.0+0.5;
      if(numeri[num].tipo==43) sprintf(buf,"%d",perbene);
      if(numeri[num].tipo==77) sprintf(buf,"%8.3f",numeri[num].nmr);
      d=sqrt(x*x+y*y+z*z);
      cx=x/d;
      cy=y/d;
      cz=z/d;
      dp=-di/cy;
      xpc=-dp*cx+numeri[num].shx;
      ypc= dp*cz+numeri[num].shy;
      if(num==numsel-1){
              rosso=  red[4]*umfog+fog; //          0 1 2 3 4 5 6
              verde=green[4]*umfog+fog; // magenta  r g b c m g n 
              bluuu= blue[4]*umfog+fog;
              glLineWidth(1.0);
              circle(xpc,ypc,0.4,0);
      }
      else{
              rosso=  red[2]*umfog+fog; //      0 1 2 3 4 5 6
              verde=green[2]*umfog+fog; // blu  r g b c m g n
              bluuu= blue[2]*umfog+fog; //
      }
      if( numeri[num].asino==0 && num==numsel-1){
              rosso=  red[1]*umfog+fog; //        0 1 2 3 4 5 6
              verde=green[1]*umfog+fog; // verde  r g b c m g n
              bluuu= blue[1]*umfog+fog; //
      }
      if(numeri[num].asino || num==numsel-1){
        glColor3f(rosso,verde,bluuu);
        glRasterPos2f(xpc,ypc);
        for(j=0;(c=buf[j])!='\0';j++)
//            glutBitmapCharacter(GLUT_BITMAP_HELVETICA_18,c);
  	      if(perbene>100)    glutBitmapCharacter(GLUT_BITMAP_HELVETICA_12,c);
  	      else if(perbene>50)glutBitmapCharacter(GLUT_BITMAP_HELVETICA_10,c); 
//  	      else if(perbene>1) glutBitmapCharacter(GLUT_BITMAP_HELVETICA_10,c);
  	      else glutBitmapCharacter(GLUT_BITMAP_HELVETICA_10,c);
      }
    }
  }

/****se richiesto disegna traiettorie come da tempo trascorso****/
  if(trjf)
    for(i=0;i<notrj;i++){
      if(traiettorie[i].vedo<0)break;
      traiettorie[i].spazio += traiettorie[i].velop * DeltaT;
      perbene=traiettorie[i].spazio/traiettorie[i].dismp;
      j=traiettorie[i].inizio + perbene%traiettorie[i].nopunti;
      traiettorie[i].velop=trjdati[j].v;
      for(k=0;k<traiettorie[i].nopunti/traiettorie[i].diviso;k++){
        x=trjdati[j].xr;
        y=trjdati[j].yr;
        z=trjdati[j].zr;
        d=sqrt(x*x+y*y+z*z);
        cx=x/d;
        cy=y/d;
        cz=z/d;
        dp=-di/cy;
        xp0=-dp*cx;
        yp0= dp*cz;
        j--;
        if(j<traiettorie[i].inizio && traiettorie[i].vedo!=0)break;
        if(j<traiettorie[i].inizio)j=traiettorie[i].fine;
        x=trjdati[j].xr;
        y=trjdati[j].yr;
        z=trjdati[j].zr;
        d=sqrt(x*x+y*y+z*z);
        cx=x/d;
        cy=y/d;
        cz=z/d;
        dp=-di/cy;
        xp1=-dp*cx;
        yp1= dp*cz;
        glColor3f(1.0, 1.0-trjdati[j].clr, 1.0-trjdati[j].clr);
        glLineWidth(spssinizio-spssinizio*k*traiettorie[i].diviso/traiettorie[i].nopunti);
        drawOneLine(xp0,yp0,xp1,yp1);
      }
    }

  glFlush();
  glutSwapBuffers();

/****se batch scrive ps/eps come da Specialvalue****/
  if(batch){
	  getang();
	  if(encaps)writepsfile(fileeps);
	  else writepsfile(fileps);
	  exit(1);
  }

}


/******************************************************************************/
void animate(void)
/******************************************************************************/
{
  float acor,bcor,gcor;
  char fileanima[180];
  char testo[80];
  char frame[4];
  char *token,*tasto;
  int i,vint1,vint2,vintstep;
  getang();
  acor=a;
  bcor=b;
  gcor=g;
  printf("Animate: a|b|g|x v_int_1 v_int_2 v_int_step \n");
  fgets(testo,80,stdin);
  token=strtok(testo," "); 
  i=1;
  while( token != NULL ){
      if(i==1)tasto=token;
      if(i==2)vint1=atoi(token);
      if(i==3)vint2=atoi(token);
      if(i==4)vintstep=atoi(token);
      token = strtok(NULL," ");
      i++;
  } 
  for(i=vint1;i<=vint2;i=i+vintstep){
      if(strcmp(tasto,"a")==0)a=i;
      if(strcmp(tasto,"b")==0)b=i;
      if(strcmp(tasto,"g")==0)g=i;
      if(strcmp(tasto,"x")==0){
	      a=i;
	      b=i;
	      g=i;
      }
      eulero();
      rdo();
      if(i<10) sprintf(frame,"00%1i",i);
      if(i>9 && i<100) sprintf(frame,"0%2i",i);
      if(i>99) sprintf(frame,"%3i",i);
      strcpy(fileanima,"a");
      strcat(fileanima,frame);
      if(encaps)strcat(fileanima,".eps");
      else      strcat(fileanima,".ps");
      printf("%f %f %f ",a,b,g);
      writepsfile(fileanima);
  }
  a=acor;
  b=bcor;
  g=gcor;
  eulero();
  rdo();
}


/******************************************************************************/
void castrato(int pippo)
/******************************************************************************/
{
/******se l'input file e' stato modificato rilegge tutto*************/	
  if( (stat(filemt,&stbuf))!=-1 )tlm1=stbuf.st_mtime;
  if(tlm1!=tlm0 || pippo<0) leggeelefig();
  tlm0=tlm1;
  msecs=abs(pippo);
  glutPostRedisplay();
}


/******************************************************************************/
int leggeelefig()
/******************************************************************************/
{
  int i,j,k,l,ll,npf,cq;
  char c;
  FILE *fp;
  char buf[100],aux[17];
  float x,y,z,r,xp,yp,zp,xmin,ymin,zmin,xmax,ymax,zmax;
  float dismp;
/********************apre il file di input conta gli elementi della fig*****/
/********************distingue linee, tondi, frecce, tringoli***************/
  if((fp=fopen(filemt,"r"))==NULL){
    printf("open failed for File %s\n",filemt);
    return 1;
  }
  for(nolin=notnd=nofrc=notri=nonum=noqua=0; ; ){
    if(fgets(buf,80,fp)==NULL) break;
    for(i=0;i<13;i++) aux[i]=buf[i+1];  aux[13]=' '; x=atof(aux);
    for(i=0;i<13;i++) aux[i]=buf[i+14]; aux[13]=' '; y=atof(aux);
    for(i=0;i<13;i++) aux[i]=buf[i+27]; aux[13]=' '; z=atof(aux);
    c=buf[41];
    if(c=='Q'){
      for(i=0;i<2;i++)  aux[i]=buf[i+42]; aux[2]=' ' ; cq=21+atoi(aux);
      for(i=0;i<13;i++) aux[i]=buf[i+45]; aux[13]=' '; r=atof(aux);
    }
    else{    
      for(i=0;i<13;i++) aux[i]=buf[i+43]; aux[13]=' '; r=atof(aux);
    }
         if(c=='a')nolin++; //linea Rossa
    else if(c=='b')nolin++; //linea Verde
    else if(c=='c')nolin++; //linea Blu
    else if(c=='d')nolin++; //linea Ciano
    else if(c=='e')nolin++; //linea Magenta
    else if(c=='f')nolin++; //linea Gialla
    else if(c=='g')nolin++; //linea Nera

    else if(c=='h')notnd++; //tondo Rosso
    else if(c=='i')notnd++; //tondo Verde
    else if(c=='l')notnd++; //tondo Blu
    else if(c=='m')notnd++; //tondo Ciano
    else if(c=='n')notnd++; //tondo Magenta
    else if(c=='o')notnd++; //tondo Giallo
    else if(c=='p')notnd++; //tondo Nero
//CPK
    else if(c=='H')notnd++; //tondo grigio chiaro
    else if(c=='C')notnd++; //tondo grigio scuro
    else if(c=='N')notnd++; //tondo blu    scuro  
    else if(c=='O')notnd++; //tondo rosso         
    else if(c=='F')notnd++; //tondo verde         
    else if(c=='R')notnd++; //tondo rosso scuro   
    else if(c=='I')notnd++; //tondo viola scuro   
    else if(c=='G')notnd++; //tondo ciano         
    else if(c=='P')notnd++; //tondo arancio       
    else if(c=='S')notnd++; //tondo giallo        
    else if(c=='B')notnd++; //tondo rosa          
    else if(c=='A')notnd++; //tondo viola         
    else if(c=='T')notnd++; //tondo verde scuro   
    else if(c=='E')notnd++; //tondo rosa          
//CPK
    else if(c=='w')nonum++; //numero intero
    else if(c=='W')nonum++; //numero reale

    else if(c=='q')nofrc++; //freccia Rossa
    else if(c=='r')nofrc++; //freccia Verde
    else if(c=='s')nofrc++; //freccia Blu
    else if(c=='t')nofrc++; //freccia Ciano
    else if(c=='u')nofrc++; //freccia Magenta
    else if(c=='v')nofrc++; //freccia Gialla
    else if(c=='z')nofrc++; //freccia Nera

    else if(c=='1')notri++; //triangolo Rosso
    else if(c=='2')notri++; //triangolo Verde
    else if(c=='3')notri++; //triangolo Blu
    else if(c=='4')notri++; //triangolo Ciano
    else if(c=='5')notri++; //triangolo Magenta
    else if(c=='6')notri++; //triangolo Giallo
    else if(c=='7')notri++; //triangolo Bianco

    else if(c=='Q')noqua++; //quadrangolo 
  }
  fclose(fp);

  if(nofrc%7){
      printf("contatore frecce (%d) non divisibile per 7\n",nofrc);
      return 7;
  }
  nofrc=nofrc/7;

  if(notri%3){
      printf("contatore triangoli (%d) non divisibile per 3\n",notri);
      return 3;
  }
  notri=notri/3;  

  if(noqua%4){
      printf("contatore quadrangoli (%d) non divisibile per 4\n",notri);
      return 4;
  }
  noqua=noqua/4;  

  printf("The figure is composed by:\n");
  printf("%10d lines\n",nolin);
  printf("%10d circles\n",notnd);
  printf("%10d arrows\n",nofrc);
  printf("%10d triangles\n",notri);
  printf("%10d numbers\n",nonum);
    
/***************** se richiesto, apre il file delle traiettorie**********/
/***************** e determina il loro numero e dimensione***************/
  notrj=nopnttrj=0;
  if(trjf){
    if((fp=fopen(filtrj,"r"))==NULL){
      printf("open failed for File %s\n",filtrj);
      return 1;
    }
   for( ; ; ){
      if(fgets(buf,90,fp)==NULL) break;
      if(buf[0]=='c')notrj++;
      else           nopnttrj++;
      if(buf[12]=='i')notrj--; // in eccesso
      if(buf[12]=='c')notrj--; // connessa o chiusa
      if(buf[12]=='a')notrj--; // aperta
    }
    fclose(fp);
    printf("%10d trajectories\n",notrj);
    printf("%10d trajectory points\n",nopnttrj);
  }

/***************** se richiesto, apre il file dei movie-frames **********/
/***************** e determina il loro numero e dimensione***************/
  nofrm=nopntfrm=0;
  if(frmf){
    if((fp=fopen(filmov,"r"))==NULL){
      printf("open failed for File %s\n",filmov);
      return 1;
    }
    fgets(buf,90,fp);
    if(buf[0]!='F'){
	   printf("missing initial data in file %s\n",filmov);
	   return 1;
    }
    for(i=0;i<5 ;i++) aux[i]=buf[i+10]; aux[5] =' '; nofrm=atof(aux);
    for(i=0;i<5 ;i++) aux[i]=buf[i+15]; aux[5] =' '; nopntfrm=nofrm*atof(aux);
    for(i=0;i<10;i++) aux[i]=buf[i+20]; aux[10]=' '; dtmp=atof(aux);
    fclose(fp);
    printf("%10d frames\n",nofrm);
    printf("%10d total frame points\n",nopntfrm);
  }
 
  printf("%10d quadrangles\n",noqua);

/********************alloca la memoria per la fig*****/
  printf("Requested memory for (1) lines..............is %d bytes,",nolin*sizeof(struct linea));
  linee = (struct linea   *) malloc(nolin*sizeof(struct linea));
  if(linee==NULL){printf(" malloc returned NULL\n");return 1;}
  else            printf(" malloc OK\n");
  
  printf("Requested memory for (2) filled circles.....is %d bytes,",notnd*sizeof(struct tondo));
  tondi = (struct tondo   *) malloc(notnd*sizeof(struct tondo));
  if(tondi==NULL){printf(" malloc returned NULL\n");return 1;}
  else            printf(" malloc OK\n");
  
  printf("Requested memory for (3) filled arrows......is %d bytes,",nofrc*sizeof(struct freccia));
  frecce = (struct freccia *) malloc(nofrc*sizeof(struct freccia));
  if(frecce==NULL){printf(" malloc returned NULL\n");return 1;}
  else             printf(" malloc OK\n");
  
  printf("Requested memory for (4) filled triangles...is %d bytes,",notri*sizeof(struct triangolo));
	  triangoli = (struct triangolo *) malloc(notri*sizeof(struct triangolo));
  if(triangoli==NULL){printf(" malloc returned NULL\n");return 1;}
  else                printf(" malloc OK\n");

  printf("Requested memory for (5) numbers............is %d bytes,",nonum*sizeof(struct numero));
  numeri = (struct numero   *) malloc(nonum*sizeof(struct numero));
  if(numeri==NULL){printf(" malloc returned NULL\n");return 1;}
  else             printf(" malloc OK\n");
    
  if(trjf!=0){
    printf("Requested memory for (6) trajectories.......is %d bytes,",notrj*sizeof(struct traiettoria));
    traiettorie = (struct traiettoria *) malloc(notrj*sizeof(struct traiettoria));
    if(traiettorie==NULL){printf(" malloc returned NULL\n");return 1;}
    else                  printf(" malloc OK\n");
    printf("Requested memory for (6) trajectory points..is %d bytes,",nopnttrj*sizeof(struct trjdato));
    trjdati = (struct trjdato *) malloc(nopnttrj*sizeof(struct trjdato));
    if(trjdati==NULL){printf(" malloc returned NULL\n");return 1;}
    else              printf(" malloc OK\n");
  }

  if(frmf!=0){
    printf("Requested memory for (7) frames.............is %d bytes,",nofrm*sizeof(struct frame));
    frames = (struct frame *) malloc(nofrm*sizeof(struct frame));
    if(frames==NULL){printf(" malloc returned NULL\n");return 1;}
    else             printf(" malloc OK\n");
    printf("Requested memory for (7) frame points.......is %d bytes,",nopntfrm*sizeof(struct frmdato));
    frmdati = (struct frmdato *) malloc(nopntfrm*sizeof(struct frmdato));
    if(frmdati==NULL){printf(" malloc returned NULL\n");return 1;}
    else              printf(" malloc OK\n");
  }
  
  printf("Requested memory for (8) filled quadrangles...is %d bytes,",noqua*sizeof(struct quadrangolo));
	  quadrangoli = (struct quadrangolo *) malloc(noqua*sizeof(struct quadrangolo));
  if(quadrangoli==NULL){printf(" malloc returned NULL\n");return 1;}
  else                printf(" malloc OK\n");

/*********1*****2*****3*****4*****5*****6********7********8***/
  noele=nolin+notnd+nofrc+notri+nonum+nopnttrj+nopntfrm+noqua;  
  elementi = (struct elemento *) malloc(noele*sizeof(struct elemento));
  printf("Requested auxiliary memory..................is %d bytes",noele*sizeof(struct elemento));
  if(elementi==NULL){printf(" malloc returned a NULL character\n");return 1;}
  else               printf(" malloc OK\n");

/********************riapre il file di input e legge la fig*****/
  xmin=1000000.0;
  ymin=1000000.0;
  zmin=1000000.0;
  xmax=-1000000.0;
  ymax=-1000000.0;
  zmax=-1000000.0;
  fp=fopen(filemt,"r");
  for(nolin=notnd=nofrc=notri=nonum=noqua=0; ; ){
    if(fgets(buf,80,fp)==NULL) break;
    for(i=0;i<13;i++) aux[i]=buf[i+1];  aux[13]=' '; x=atof(aux);
    for(i=0;i<13;i++) aux[i]=buf[i+14]; aux[13]=' '; y=atof(aux);
    for(i=0;i<13;i++) aux[i]=buf[i+27]; aux[13]=' '; z=atof(aux);
    c=buf[41];
    if(c=='Q'){
      for(i=0;i<2;i++)  aux[i]=buf[i+42]; aux[2]=' ' ; cq=21+atoi(aux);
      for(i=0;i<13;i++) aux[i]=buf[i+45]; aux[13]=' '; r=atof(aux);
    }
    else{    
      for(i=0;i<13;i++) aux[i]=buf[i+43]; aux[13]=' '; r=atof(aux);
    }
    if(x<xmin)xmin=x;
    if(y<ymin)ymin=y;
    if(z<zmin)zmin=z;
    if(x>xmax)xmax=x;
    if(y>ymax)ymax=y;
    if(z>zmax)zmax=z;
    if(c=='x'){xp=x;yp=y;zp=z;}
    else if(c=='a'||c=='b'||c=='c'||c=='d'||c=='e'||c=='f'||c=='g'){ //linee
        linee[nolin].x[0]=xp; xp=linee[nolin].x[1]=x;
        linee[nolin].y[0]=yp; yp=linee[nolin].y[1]=y;
        linee[nolin].z[0]=zp; zp=linee[nolin].z[1]=z;
        linee[nolin].sps=r;
        if(c=='a')linee[nolin].clr=0;
        if(c=='b')linee[nolin].clr=1;
        if(c=='c')linee[nolin].clr=2;
        if(c=='d')linee[nolin].clr=3;
        if(c=='e')linee[nolin].clr=4;
        if(c=='f')linee[nolin].clr=5;
        if(c=='g')linee[nolin].clr=6;
        nolin++;}
    else if(c=='h'||c=='i'||c=='l'||c=='m'||c=='n'||c=='o'||c=='p'||c=='H'||c=='C'||c=='N'||c=='O'||c=='F'||c=='R'||c=='I'||c=='G'||c=='P'||c=='S'||c=='B'||c=='A'||c=='T'||c=='E'){ //tondi
        xp=tondi[notnd].x=x;
        yp=tondi[notnd].y=y;
        zp=tondi[notnd].z=z;
        tondi[notnd].rgg=r;
        if(c=='h')tondi[notnd].clr=0;
        if(c=='i')tondi[notnd].clr=1;
        if(c=='l')tondi[notnd].clr=2;
        if(c=='m')tondi[notnd].clr=3;
        if(c=='n')tondi[notnd].clr=4;
        if(c=='o')tondi[notnd].clr=5;
        if(c=='p')tondi[notnd].clr=6;
//CPK
        if(c=='H')tondi[notnd].clr=7;
        if(c=='C')tondi[notnd].clr=8;
        if(c=='N')tondi[notnd].clr=9;
        if(c=='O')tondi[notnd].clr=10;
        if(c=='F')tondi[notnd].clr=11;
        if(c=='R')tondi[notnd].clr=12;
        if(c=='I')tondi[notnd].clr=13;
        if(c=='G')tondi[notnd].clr=14;
        if(c=='P')tondi[notnd].clr=15;
        if(c=='S')tondi[notnd].clr=16;
        if(c=='B')tondi[notnd].clr=17;
        if(c=='A')tondi[notnd].clr=18;
        if(c=='T')tondi[notnd].clr=19;
        if(c=='E')tondi[notnd].clr=20;
        notnd++;}
    else if(c=='w'){ //numeri interi
        xp=numeri[nonum].x=x;
        yp=numeri[nonum].y=y;
        zp=numeri[nonum].z=z;
        numeri[nonum].nmr=r;
	numeri[nonum].shx=0.0;
	numeri[nonum].shy=0.0;
	numeri[nonum].tipo=43;
	numeri[nonum].asino=1;
	nonum++;}
    else if(c=='W'){ //numeri reali
        xp=numeri[nonum].x=x;
        yp=numeri[nonum].y=y;
        zp=numeri[nonum].z=z;
        numeri[nonum].nmr=r;
	numeri[nonum].shx=0.0;
	numeri[nonum].shy=0.0;
	numeri[nonum].tipo=77;
	numeri[nonum].asino=1;
	nonum++;}
    else if(c=='q'||c=='r'||c=='s'||c=='t'||c=='u'||c=='v'||c=='z'){ //frecce
        i=r-0.9;                    //                   2
        if(i<=6&&i>=0){             //       5 + + + + + 4  +
          frecce[nofrc].x[i]=x;     //       +           +    1
          frecce[nofrc].y[i]=y;     //       6 + + + + + 7  +
          frecce[nofrc].z[i]=z;     //                   3
          if(i==0){xp=x;yp=y;zp=z;
                   if(c=='q')frecce[nofrc].clr=0;
                   if(c=='r')frecce[nofrc].clr=1;
                   if(c=='s')frecce[nofrc].clr=2;
                   if(c=='t')frecce[nofrc].clr=3;
                   if(c=='u')frecce[nofrc].clr=4;
                   if(c=='v')frecce[nofrc].clr=5;
                   if(c=='z')frecce[nofrc].clr=6;
                   nofrc++;}}}    
    else if(c=='1'||c=='2'||c=='3'||c=='4'||c=='5'||c=='6'||c=='7'){ //triangoli
        i=fabs(r)-0.9;                 //   2
        if(i<=2&&i>=0){                //   +  +
          triangoli[notri].x[i]=x;     //   +    1
          triangoli[notri].y[i]=y;     //   +  +
          triangoli[notri].z[i]=z;     //   3
          if(r>0.0)triangoli[notri].lt[i]=1;
          else     triangoli[notri].lt[i]=0;
          if(i==0){xp=x;yp=y;zp=z;
                   if(c=='1')triangoli[notri].clr=0;
                   if(c=='2')triangoli[notri].clr=1;
                   if(c=='3')triangoli[notri].clr=2;
                   if(c=='4')triangoli[notri].clr=3;
                   if(c=='5')triangoli[notri].clr=4;
                   if(c=='6')triangoli[notri].clr=5;
                   if(c=='7')triangoli[notri].clr=6;
                   notri++;}}}    
    else if(c=='Q'){ //quadrandoli
	i=r-0.9;                      //       2
        if(i<=3&&i>=0){               //     +   +
          quadrangoli[noqua].x[i]=x;  //   3       1
          quadrangoli[noqua].y[i]=y;  //     +   +
          quadrangoli[noqua].z[i]=z;  //       4
	  if(i==0){xp=x;yp=y;zp=z; 
		  quadrangoli[noqua].clr=cq;
		  noqua++;}}}
  }
  fclose(fp);
    
/*****se richiesto, riapre il file delle traiettorie e le legge**********/
  notrj=nopnttrj=0;
  if(trjf){
    fp=fopen(filtrj,"r");
    for( ; ; ){
      if(fgets(buf,90,fp)==NULL) break;
      if( buf[0]=='c' && buf[12]!='i' && buf[12]!='c' && buf[12]!='a' ){
          for(i=0;i<16;i++) aux[i]=buf[i+32]; aux[16]=' '; traiettorie[notrj].diviso=atoi(aux);
          if(traiettorie[notrj].diviso==0)traiettorie[notrj].diviso=1;
          traiettorie[notrj].inizio=nopnttrj;
	      notrj++;
      }
      else if(buf[0]=='c' && buf[12]=='a'){traiettorie[notrj-1].vedo=2;} // aperta
      else if(buf[0]=='c' && buf[12]=='i'){traiettorie[notrj-1].vedo=3;}  // in eccesso
      else if(buf[0]=='c' && buf[12]=='c' && buf[13]=='h'){traiettorie[notrj-1].vedo=0;}  // chiusa
      else if(buf[0]=='c' && buf[12]=='c' && buf[13]=='o'){traiettorie[notrj-1].vedo=1;}  // connessa
      else if(buf[0]!='c'){
        for(i=0;i<16;i++) aux[i]=buf[i];    aux[16]=' '; trjdati[nopnttrj].x=atof(aux);
	for(i=0;i<16;i++) aux[i]=buf[i+16]; aux[16]=' '; trjdati[nopnttrj].y=atof(aux);
	for(i=0;i<16;i++) aux[i]=buf[i+32]; aux[16]=' '; trjdati[nopnttrj].z=atof(aux);
    	for(i=0;i<16;i++) aux[i]=buf[i+48]; aux[16]=' '; trjdati[nopnttrj].j=atof(aux);
    	for(i=0;i<16;i++) aux[i]=buf[i+64]; aux[16]=' '; trjdati[nopnttrj].r=atof(aux);
                                                         trjdati[nopnttrj].v=trjdati[nopnttrj].j/trjdati[nopnttrj].r;
	                                                 if(trjdati[nopnttrj].r<romin)romin=trjdati[nopnttrj].r;
	                                                 if(trjdati[nopnttrj].r>romax)romax=trjdati[nopnttrj].r;
        traiettorie[notrj-1].fine=nopnttrj;
        nopnttrj++;
      }
    }
    fclose(fp);
    deltaromin=deltaromax=(romax-romin)/100.0;
//    for(i=0;i<nopnttrj;i++) trjdati[i].clr=(trjdati[i].r-romin)/(romax-romin);
    for(i=0;i<nopnttrj;i++) trjdati[i].clr=1.0;
    for(i=0;i<notrj;i++){
      traiettorie[i].nopunti=traiettorie[i].fine-traiettorie[i].inizio+1;
      if(traiettorie[i].nopunti==1)traiettorie[i].vedo=-1;
      dismp=0.0;
      for(j=traiettorie[i].inizio;j<traiettorie[i].fine;j++){
        x=trjdati[j+1].x-trjdati[j].x;
        y=trjdati[j+1].y-trjdati[j].y;
        z=trjdati[j+1].z-trjdati[j].z;
        dismp=dismp+sqrt(x*x+y*y+z*z);
      }
      traiettorie[i].dismp=dismp/traiettorie[i].nopunti;
      traiettorie[i].spazio=0.0;
      traiettorie[i].velop=trjdati[traiettorie[i].inizio].v;
    }
  }

/*****se richiesto, riapre il file dei movie-frames e li legge**********/
  npf=0;
  if(frmf){
    fp=fopen(filmov,"r");
    for(k=0;k<nofrm;k++){
      fgets(buf,80,fp); 
      frames[k].inizio=npf;
      frames[k].nopunti=nopntfrm/nofrm;
      for(j=0;j<nopntfrm/nofrm;j++){
        for(l=0;l<7;l++){
          fgets(buf,80,fp);
          for(i=0;i<13;i++) aux[i]=buf[i+1];  aux[13]=' '; x=atof(aux);
          for(i=0;i<13;i++) aux[i]=buf[i+14]; aux[13]=' '; y=atof(aux);
          for(i=0;i<13;i++) aux[i]=buf[i+27]; aux[13]=' '; z=atof(aux);
          c=buf[41];
          for(i=0;i<13;i++) aux[i]=buf[i+43]; aux[13]=' '; r=atof(aux);
          ll=r-0.9;  
          frmdati[npf].x[ll]=x;
          frmdati[npf].y[ll]=y;
          frmdati[npf].z[ll]=z;
          if(c=='q')frmdati[npf].clr=0;
          if(c=='r')frmdati[npf].clr=1;
          if(c=='s')frmdati[npf].clr=2;
          if(c=='t')frmdati[npf].clr=3;
          if(c=='u')frmdati[npf].clr=4;
          if(c=='v')frmdati[npf].clr=5;
          if(c=='z')frmdati[npf].clr=6;
        }
	npf++;
      }
      frames[k].fine=npf-1;
    }
    fclose(fp);
  }

/****************************centra la fig*******************************/
  printf("xmin=%f xmax=%f\n",xmin,xmax);
  printf("ymin=%f ymax=%f\n",ymin,ymax);
  printf("zmin=%f zmax=%f\n",zmin,zmax);

  if(centra){x=(xmax+xmin)/2.0; y=(ymax+ymin)/2.0; z=(zmax+zmin)/2.0;}
  else      {x=0.0;             y=0.0;             z=0.0;            }
  printf("X_0=%f, Y_0=%f, Z_0=%f\n",x,y,z);
  coordzero[0]=x; coordzero[1]=y; coordzero[2]=z;
  for(i=0;i<nolin;i++){
    linee[i].x[0]-=x; linee[i].x[1]-=x;
    linee[i].y[0]-=y; linee[i].y[1]-=y;
    linee[i].z[0]-=z; linee[i].z[1]-=z;
  }
  for(i=0;i<notnd;i++){
    tondi[i].x-=x;
    tondi[i].y-=y;
    tondi[i].z-=z;
  }
  for(i=0;i<nofrc;i++)
    for(j=0;j<7;j++){
      frecce[i].x[j]-=x;
      frecce[i].y[j]-=y;
      frecce[i].z[j]-=z;
  }
  for(i=0;i<notri;i++)
    for(j=0;j<3;j++){
      triangoli[i].x[j]-=x;
      triangoli[i].y[j]-=y;
      triangoli[i].z[j]-=z;
  }
  for(i=0;i<nonum;i++){
    numeri[i].x-=x;
    numeri[i].y-=y;
    numeri[i].z-=z;
  }
  for(i=0;i<nopnttrj;i++){
    trjdati[i].x-=x;
    trjdati[i].y-=y;
    trjdati[i].z-=z;
  }
  for(i=0;i<nopntfrm;i++)
    for(j=0;j<7;j++){
    frmdati[i].x[j]-=x;
    frmdati[i].y[j]-=y;
    frmdati[i].z[j]-=z;
  }
  for(i=0;i<noqua;i++)
    for(j=0;j<4;j++){
      quadrangoli[i].x[j]-=x;
      quadrangoli[i].y[j]-=y;
      quadrangoli[i].z[j]-=z;
  }
  return 0;
}


/******************************************************************************/
void vaitempo(void)
/******************************************************************************/
{
  Tempo+=DeltaT;
  if(Tempo<0.0)Tempo=0.0;
  glutPostRedisplay();
}


/******************************************************************************/
void tastiera(unsigned char c,int x, int y)
/******************************************************************************/
{
  int pippo,i;
  FILE *fp;
  
  castrato(msecs);
  if(c==27) exit(0);
  if(c=='Q') exit(0);
  if(c=='h'){
    printf("----------------------------------------------------------------\n");
    printf("On-line help.\n");
    printf("Keyborad options:\n");
    printf("h     display this help\n");
    printf("<Esc> quit the program\n");
    printf("Q     quit the program\n");
    printf("p     make a PostScript file matching the current display see also e-option\n");
    printf("s     on|off stereo-view, act only on PostScript file\n");
    printf("c     change the versus (sign) of some of the following commands\n");
    printf("C     on|off center the plot in the window\n");
    printf("d(D)  increment the point-of-view distance by %5.1f(%5.1f) units\n",segno*deltad,segno*DeltaD);
    printf("i     put the point-of-view very far away\n");
    printf("f(F)  increment the zoom factor by %5.2f(%5.2f)\n",segno*deltaf,segno*DeltaF);
    printf("O     increment the stereo angle by %5.2f\n",segno*deltarot);
    printf("y     increment the white contour by %5.2f\n",segno*deltasbc);
    printf("u     increment darkness of triangles/quadrangles by %5.2f\n",segno*deltadark);
    printf("w     increment PS line/circle white contour by %5.2f %5.2f\n",ridlt,segno*dridlt);
    printf("k     increment PS arrow/rect white contour by %5.2f %5.2f\n",ridfr,segno*dridfr);
    printf("n(N)  increment the fog limit by %5.2f(%5.2f)\n",segno*deltan,segno*DeltaN);
    printf("0,1,2,3,4 change paper size from A0 to A4 [current A%1i]\n",asize);
    printf("The figure can be rotated also changing the Euler angles alpha, beta, gamma\n");
    printf("a(A) increment alpha by %5.0f(%5.0f) degree\n",segno*deltaa,segno*DeltaA);
    printf("b(B) increment beta  by %5.0f(%5.0f) degree\n",segno*deltab,segno*DeltaB);
    printf("g(G) increment gamma by %5.0f(%5.0f) degree\n",segno*deltag,segno*DeltaG);
    printf("x    update Euler angles and zoom factor\n");
    printf("z    make encapsuled PostScript frames for animations\n");
    printf("t    a dirty trick\n");
    printf("e    produce encapsuled PostScript instead of PostScript\n");
    printf("S    write the SpecialValues.txt file with the current values of variables\n");
    printf("W    on|off numbers\n");
    printf("+    select number forward\n");
    printf("-    (minus) select number backward\n");
    printf("_    (underscore) on|off select number\n");
    printf("T    start trajectory animation, time step is %6.3f unit\n",DeltaT);
    printf("X    stop  trajectory animation\n");
    printf("r    ro<%8.5f bianco\n",romin);
    printf("R    ro>%8.5f rosso \n",romax);
    printf("I    spessore iniziale traiettorie %4.1f\n",spssinizio);
    printf("----------------------------------------------------------------\n");
  }
  if(c=='T'){DeltaT+=segno*1E-3; if(DeltaT<0.0)DeltaT=0.0; glutIdleFunc(vaitempo);}
  if(c=='r'){
	  if( (romin+segno*deltaromin) < romax)romin+=segno*deltaromin;
          for(i=0;i<nopnttrj;i++) trjdati[i].clr=(trjdati[i].r-romin)/(romax-romin);
  }
  if(c=='R'){
	  if( (romax-segno*deltaromax) > romin)romax+=segno*deltaromax;
          for(i=0;i<nopnttrj;i++) trjdati[i].clr=(trjdati[i].r-romin)/(romax-romin);
  }
  if(c=='I')spssinizio+=segno*deltaspssinizio;
  if(c=='X')glutIdleFunc(NULL);
  if(c=='+')numsel++;
  if(numsel>nonum)numsel=0;
  if(c=='-')numsel--;
  if(numsel<0)numsel=nonum;
  if(c=='_' && numsel!=0)numeri[numsel-1].asino=numeri[numsel-1].asino?0:1;  
  if(c=='W')numbers=numbers?0:1;
  if(c=='S'){
    if((fp=fopen("SpecialValues.txt","w"))==NULL){
      printf("open failed for file SpecialValues.txt\n");
      exit(1);
    }
    getang();
    printf("Start writing file SpecialValues.txt ");
    fprintf(fp,"%d   encax1\n",encax1);
    fprintf(fp,"%d   encay1\n",encay1);
    fprintf(fp,"%d   encax2\n",encax2);
    fprintf(fp,"%d   encay2\n",encay2);
    fprintf(fp,"%d   stereo\n",stereo);
    fprintf(fp,"%f   segno\n",segno);
    fprintf(fp,"%d   centra\n",centra);
    fprintf(fp,"%f   di\n",di);
    fprintf(fp,"%f   fi\n",fi);
    fprintf(fp,"%f   fog2\n",fog2);
    fprintf(fp,"%f   a\n",a);
    fprintf(fp,"%f   b\n",b);
    fprintf(fp,"%f   g\n",g);
    fprintf(fp,"%f   rot\n",rot);
    fprintf(fp,"%f   sbc\n",sbc);
    fprintf(fp,"%f   dark\n",dark);
    fprintf(fp,"%f   ridlt\n",ridlt);
    fprintf(fp,"%f   ridfr\n",ridfr);
    fprintf(fp,"%d   asize\n",asize);
    fprintf(fp,"%d   dirty_trick\n",dirty_trick);
    fprintf(fp,"%d   encaps\n",encaps);
     printf(" done!\n");
    fclose(fp);
  }
  if(c=='p'){
	  getang();
	  if(encaps)writepsfile(fileeps);
	  else writepsfile(fileps);
  }
  if(c=='s')stereo=stereo?0:1;
  if(c=='c')segno=-segno;
  if(c=='C'){
	  centra=centra?0:1;
	  pippo=-msecs;
	  castrato(pippo);
  }
  if(c=='d')di+=segno*deltad;
  if(c=='D')di+=segno*DeltaD;
  if(di<deltad)di=deltad;
  if(c=='f'){getang();fi+=segno*deltaf;}
  if(c=='F'){getang();fi+=segno*DeltaF;}
  if(fi<deltaf)fi=deltaf;
  if(c=='n')fog2+=segno*deltan;
  if(c=='N')fog2+=segno*DeltaN;
/***aggiorna angoli Eulero***/  
/** a nel range [-180,180] **/   
  if(c=='a'){getang();a+=segno*deltaa;}
  if(c=='A'){getang();a+=segno*DeltaA;}
  if(a> 180.0)a= 180.0;
  if(a<-180.0)a=-180.0;
/** b nel range [0,180] **/   
  if(c=='b'){getang();b+=segno*deltab;}
  if(c=='B'){getang();b+=segno*DeltaB;}
  if(b>180.0)b=180.0;
  if(b<  0.0)b=  0.0;
/** g nel range [-180,180] **/   
  if(c=='g'){getang();g+=segno*deltag;}
  if(c=='G'){getang();g+=segno*DeltaG;}
  if(g> 180.0)g= 180.0;
  if(g<-180.0)g=-180.0;
/****************************/  
  if(c=='O')rot+=segno*deltarot;
  if(c=='y')sbc+=segno*deltasbc;
  if(sbc<0.0)sbc=0.0;
  if(c=='u')dark+=segno*deltadark;
  if(dark>1.0)dark=1.0;
  if(dark<0.0)dark=0.0;
  if(c=='w')ridlt+=segno*dridlt;
  if(ridlt<0.0)ridlt=0.0;
  if(c=='k')ridfr+=segno*dridfr;
  if(ridfr<0.0)ridfr=0.0;
  if(c=='i')di=1000;
  if(c=='0')asize=0;
  if(c=='1')asize=1;
  if(c=='2')asize=2;
  if(c=='3')asize=3;
  if(c=='4')asize=4;
  if(c=='x')getang();
  if(c=='z')animate();
  if(c=='t')dirty_trick=dirty_trick?0:1;
  if(c=='e')encaps=encaps?0:1;
  if(c=='a'||c=='A'||c=='b'||c=='B'||c=='g'||c=='G')eulero();
  printf("s%2d,  c%2.0f, d%5.1f, f%5.2f, a%5.0f, b%5.0f, g%5.0f, t%2d, e%2d\n",
          stereo,segno,  di,     fi,     a,      b,      g, dirty_trick, encaps);
  if(c=='h'||c=='s'||c=='c') return;
  glutPostRedisplay();
}


/******************************************************************************/
void bottone(int button, int state, int x, int y)
/******************************************************************************/
{
	int i, tipo, num;
        float xe, ye, ze, d, cx, cy, cz;
	float dp, xp, yp;
	float dist;
	int xpw, ypw;
        FILE *fp;
        int trovato;

  	castrato(msecs);
	xglob=x;
	yglob=y;
	bglob=button;
	if( button==2 && state==0){ 
                trovato=0;
                for(i =0;i<noele;i++){
                  tipo=elementi[i].tipo;
                  num=elementi[i].num;  
                  if(tipo==1){    //linea 
                    xe=(linee[num].xr[0]+linee[num].xr[1])/2;
                    ye=(linee[num].yr[0]+linee[num].yr[1])/2;
                    ze=(linee[num].zr[0]+linee[num].zr[1])/2;
//                    dist=sqrt((linee[num].xr[0]-linee[num].xr[1])*(linee[num].xr[0]-linee[num].xr[1])+
//			      (linee[num].yr[0]-linee[num].yr[1])*(linee[num].yr[0]-linee[num].yr[1])+
//			      (linee[num].zr[0]-linee[num].zr[1])*(linee[num].zr[0]-linee[num].zr[1]))/fi;
//		    if(dist>0.1 && dist<0.4){
                      d=sqrt(xe*xe+ye*ye+ze*ze);
                      cx=xe/d;
                      cy=ye/d;
                      cz=ze/d;
                      dp=-di/cy;
                      xp=-dp*cx;
                      yp= dp*cz;
		      xpw=(xp-wmin)*dimwin/(wmax-wmin);
		      ypw=(-yp-wmin)*dimwin/(wmax-wmin);
		      if(abs(x-xpw)<=8 && abs(y-ypw)<=8 ){ 
			    printf("Elemento n. =%5d, linea, num =%5d, x =%9.4f, y =%9.4f, z =%9.4f\n",i,num,
					                  (linee[num].x[0]+linee[num].x[1])/2,
					                  (linee[num].y[0]+linee[num].y[1])/2,
					                  (linee[num].z[0]+linee[num].z[1])/2); 
                            if((fp=fopen("buzzly","a"))!=NULL){
	                      fprintf(fp,"Elemento n. =%5d, linea, num =%5d\n",i,num);
                              fclose(fp);
                            }
                            trovato=1;
                      }
//		    }
		  } 
                  if(tipo==2){    //tondo
                    xe=tondi[num].xr;
                    ye=tondi[num].yr;
                    ze=tondi[num].zr;
                    d=sqrt(xe*xe+ye*ye+ze*ze);
                    cx=xe/d;
                    cy=ye/d;
                    cz=ze/d;
                    dp=-di/cy;
                    xp=-dp*cx;
                    yp= dp*cz;
		    xpw=(xp-wmin)*dimwin/(wmax-wmin);
		    ypw=(-yp-wmin)*dimwin/(wmax-wmin);
		    if(abs(x-xpw)<=8 && abs(y-ypw)<=8 ){ 
			    printf("Elemento n. =%5d, tondo, num =%5d, x =%9.4f, y =%9.4f, z =%9.4f\n",i,num,
					                                                               tondi[num].x,
					                                                               tondi[num].y,
												       tondi[num].z); 
                            if((fp=fopen("buzzly","a"))!=NULL){
	                      fprintf(fp,"Elemento n. =%5d, tondo, num =%5d\n",i,num);
                              fclose(fp);
                            }
                            trovato=1;
                    }
		  }
		} 
                if(trovato==0) if((fp=fopen("buzzly","a"))!=NULL){
	                         fprintf(fp,"999\n");
                                 fclose(fp);
                               }
	}
}


/******************************************************************************/
void topomoto(int x, int y)
/******************************************************************************/
{
  float gama,cg,sg,beta,cb,sb;
  float t0,t1,t2;

  if(bglob==0){
    gama=(x-xglob)*0.1; 
    xglob=x;
    cg=cos(gama*0.01745329);
    sg=sin(gama*0.01745329);
    t0=+cg*t[0][0]-sg*t[1][0]; 
    t1=+sg*t[0][0]+cg*t[1][0]; 
    t[0][0]=t0;
    t[1][0]=t1;
    t0=+cg*t[0][1]-sg*t[1][1]; 
    t1=+sg*t[0][1]+cg*t[1][1]; 
    t[0][1]=t0;
    t[1][1]=t1;
    t0=+cg*t[0][2]-sg*t[1][2]; 
    t1=+sg*t[0][2]+cg*t[1][2]; 
    t[0][2]=t0;
    t[1][2]=t1;
    glutPostRedisplay();

    beta=(y-yglob)*0.1;
    yglob=y;
    cb=cos(beta*0.01745329);
    sb=sin(beta*0.01745329);
    t1=+cb*t[1][0]+sb*t[2][0]; 
    t2=-sb*t[1][0]+cb*t[2][0]; 
    t[1][0]=t1;
    t[2][0]=t2;
    t1=+cb*t[1][1]+sb*t[2][1]; 
    t2=-sb*t[1][1]+cb*t[2][1]; 
    t[1][1]=t1;
    t[2][1]=t2;
    t1=+cb*t[1][2]+sb*t[2][2]; 
    t2=-sb*t[1][2]+cb*t[2][2]; 
    t[1][2]=t1;
    t[2][2]=t2;
    glutPostRedisplay();
  }

  if(bglob==1){
          fi=fi+(x-xglob)*0.005;
          xglob=x;
          if(fi<deltaf)fi=deltaf;
          glutPostRedisplay();
   	      fi=fi+(y-yglob)*0.005;
          if(fi<deltaf)fi=deltaf;
          yglob=y;
          glutPostRedisplay();
  }

  if(bglob==2){
          tx=tx-(x-xglob)*0.01;
          xglob=x;
          glutPostRedisplay();
	      ty=ty-(y-yglob)*0.01;
          yglob=y;
          glutPostRedisplay();
  }

}


/******************************************************************************/
void SpecialInput(int key, int x, int y)
/******************************************************************************/
{
  float factor;

  if(numsel>0){
          switch(key)
          {
            case GLUT_KEY_UP:
	      factor=0.01;
	      if( glutGetModifiers() == GLUT_ACTIVE_SHIFT )factor=0.1;
              numeri[numsel-1].shy+=factor; break;
            case GLUT_KEY_DOWN:
	      factor=0.01;
	      if( glutGetModifiers() == GLUT_ACTIVE_SHIFT )factor=0.1;
              numeri[numsel-1].shy-=factor; break;
            case GLUT_KEY_LEFT:
	      factor=0.01;
	      if( glutGetModifiers() == GLUT_ACTIVE_SHIFT )factor=0.1;
              numeri[numsel-1].shx-=factor; break;
            case GLUT_KEY_RIGHT:
	      factor=0.01;
	      if( glutGetModifiers() == GLUT_ACTIVE_SHIFT )factor=0.1;
              numeri[numsel-1].shx+=factor; break;
          }
  }
glutPostRedisplay();
}


/******************************************************************************/
int main(int argc, char *argv[])
/******************************************************************************/
{
  int err,i;
  char label[180];
  FILE *fp;
  char buf[80];
 
  printf("%s\n", titolo);

  if(argc<2){
    printf("Usage: %s file.3d [-npix window_size] [-batch] [-trjf trajectory_file] [-frmf movie_file]\n",argv[0]);
    return 1;
  }
    
  dimwin=DIMWIN;
  for(i=2;i<argc;i++){
      if(strcmp(argv[i],"-npix")==0)dimwin=atoi(argv[i+1]);
      if(strcmp(argv[i],"-trjf")==0){strcpy(filtrj,argv[i+1]);trjf=1;}
      if(strcmp(argv[i],"-frmf")==0){strcpy(filmov,argv[i+1]);frmf=1;}
      if(strcmp(argv[i],"-batch")==0)batch=1;
  }

  strcpy(filemt,argv[1]);

  strcpy(fileps,argv[1]);
  for(i=0; fileps[i]!='.' && fileps[i]!='\0' ;i++) ;
  if(fileps[i]=='.')fileps[i]='\0';
  strcat(fileps,".ps");

  strcpy(fileeps,argv[1]);
  for(i=0; fileeps[i]!='.' && fileeps[i]!='\0' ;i++) ;
  if(fileeps[i]=='.')fileeps[i]='\0';
  strcat(fileeps,".eps");

  strcpy(label,argv[0]);
  strcat(label," ");
  strcat(label,argv[1]);

  if((fp=fopen("SpecialValues.txt","r"))!=NULL){
       printf("Set initial values from SpecialValues.txt file");
       fgets(buf,80,fp); encax1=atoi(buf);
       fgets(buf,80,fp); encay1=atoi(buf);
       fgets(buf,80,fp); encax2=atoi(buf);
       fgets(buf,80,fp); encay2=atoi(buf);
       fgets(buf,80,fp); stereo=atoi(buf);
       fgets(buf,80,fp); segno=atof(buf);
       fgets(buf,80,fp); centra=atoi(buf);
       fgets(buf,80,fp); di=atof(buf);
       fgets(buf,80,fp); fi=atof(buf);
       fgets(buf,80,fp); fog2=atof(buf);
       fgets(buf,80,fp); a=atof(buf);
       fgets(buf,80,fp); b=atof(buf);
       fgets(buf,80,fp); g=atof(buf);
       fgets(buf,80,fp); rot=atof(buf);
       fgets(buf,80,fp); sbc=atof(buf);
       fgets(buf,80,fp); dark=atof(buf);
       fgets(buf,80,fp); ridlt=atof(buf);
       fgets(buf,80,fp); ridfr=atof(buf);
       fgets(buf,80,fp); asize=atoi(buf);
       fgets(buf,80,fp); dirty_trick=atoi(buf);
       fgets(buf,80,fp); encaps=atoi(buf);
       printf(" done!\n");
       fclose(fp);
  }
  else a=b=g=0.01; // conviene che angoli di eulero non siano proprio 0.0
  eulero();   // inizializza matrice di rotazione

  glutInit(&argc, argv);
  glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
  glutInitWindowSize(dimwin,dimwin);
  glutInitWindowPosition(40,40);
  glutCreateWindow(label);
  if( (err=init(dimwin,dimwin))==0 ){
    glutDisplayFunc(display);
    if( (stat(filemt,&stbuf))!=-1 )tlm0=stbuf.st_mtime;
//    glutTimerFunc(msecs,castrato,msecs);
    glutKeyboardFunc(tastiera);
    glutMouseFunc(bottone);
    glutMotionFunc(topomoto);
    glutSpecialFunc(SpecialInput);
    printf("s%2d,  c%2.0f, d%5.1f, f%5.2f, a%5.0f, b%5.0f, g%5.0f, t%2d, e%2d\n",
            stereo,segno,  di,     fi,     a,      b,      g, dirty_trick, encaps);
    glutMainLoop();
  }
  return err;
}
