Ok, deciframi questo
#include"math.h"
#include"graph.h"
#include"stdio.h"
#include"stdlib.h"
#include"string.h"
#include"bios.h"
#define PI 3.1415927
struct dati {
double x;
double y;
double vx;
double vy;
double m;
struct dati *pt;
}; /* <- punto e virgola */
struct punt { /* contiene gli indirizzi dei due anelli generati */
struct dati *pt1; /* e il numero delle masse introdotte n */
struct dati *pt2;
struct dati *pt3;
short n;
}
main()
{
double G,x,y,vx,vy,xc,yc,mc,r,ax,ay,step,step0;
struct punt indir,puntdati();
struct dati *pa,*pb,*pn,*pcoda;
short n,p,q,j,dm,cont;
short cl[7]= {2,4,3,14,5,7,1}; /* <- Vettore colori */
double stepdm(),val_step();
char ch[10];
_setvideomode(_VRES16COLOR);
pa=NULL;j=0;
G=1000.0; /* <- Costante gravitazionale */
inizio1: /* <- Label inizio 1 */
_clearscreen(_GCLEARSCREEN);
croce(); /* <- Disegna croce */
_outtext("Scrivere 's' per interrompere inserzione 'c' per correggere\n");
if(pa!=NULL) /* Cancellazione struct generate
rima di inserire_ */
cancella(pa,pb,pcoda,n); /* nuovi dati cancella quelli vecchi */
step0=val_step(); /* Acquisizione valore step e richiesta step dinamico */
if(step0<0)
dm=1;
else dm=0;
step0=fabs(step0);
indir=puntdati(); /* <- Acqusizione dati e costruzione struct dinamiche */
n=indir.n;
inizio2: /* <- Label inizio 2 */
pa=indir.pt1;
pb=indir.pt2;
pcoda=indir.pt3;
step=step0;
if(j=='r') /* Se il tasto premuto Š R,copia i dati originali_ */
{ /* contenuti nella "coda" in "anello 1" */
do
{
pa->x=320.0+(pcoda->x)*cos((pcoda->y)*PI/180.0);
pa->y=240.0-(pcoda->x)*sin((pcoda->y)*PI/180.0);
pa->vx=(pcoda->vx)*cos((pcoda->vy)*PI/180.0);
pa->vy=-(pcoda->vx)*sin((pcoda->vy)*PI/180.0);
pa->m=pcoda->m;
pcoda=pcoda->pt;
pa=pa->pt;
} while (pcoda !=NULL);
pcoda=indir.pt3;
}
_clearscreen(_GCLEARSCREEN);
_outtext("Premere I:inserzione nuovi dati R:risimulazione C:correzione Q:uscita\n");
sprintf(ch,"%lg",step0);
_outtext("0 Step=");_outtext(ch);
if(dm==1)
_outtext(" Step dinamico attivato");
stampa(pcoda,cl,0); /* <- Stampa dati con 0:stampa dati semplificati */
croce(); /* <-Disegna croce */
punt_start(pcoda); /* <- Disegna i punti di partenza dei grafici */
cont=0; /* <- variabile switch per routine step dinamico */
ax=0.0;ay=0.0;
do /* <- Inizio ciclo calcolo e tracciamento grafico */
{
for(q=1;q<=n;q++)
{
ax=0.0;ay=0.0; /* <- accelerazioni poste a 0 ad ogni inizio ciclo */
pn=pa;
x=pa->x;
y=pa->y;
vx=pa->vx;
vy=pa->vy;
for(p=1;p<n;p++)
{
pn=pn->pt; /* Elementi successivi dell'elemento puntato da pa */
xc=pn->x;
yc=pn->y;
mc=pn->m;
r=sqrt((x-xc)*(x-xc)+(y-yc)*(y-yc)); /* Calcolo contributi accelerazione */
ax=ax+mc*(G*(xc-x)/(r*r*r)); /* delle N masse */
ay=ay+mc*(G*(yc-y)/(r*r*r));
}
if(dm)
step=stepdm(ax,ay,step,n,q,cont); /* <- Routine step dinamico */
x=x+vx*step+1.0/2*ax*step*step; /* Spostamenti e velocita' aggiornate */
y=y+vy*step+1.0/2*ay*step*step;
vx=vx+ax*step;
vy=vy+ay*step;
pb->x=x; /* Inserimento dati aggiornati in anello 2 */
pb->y=y; /* Le masse sono gia' presenti */
pb->vx=vx;
pb->vy=vy;
pa=pa->pt; /* <-Calcolo accelerazioni sulla massa successiva */
pb=pb->pt; /* <-Indirizzamento sul successivo elemento dell'anello 2 */
_setcolor(cl[((q-1) % 7)]);
_setpixel_w(x,y);
} /* <- fine for(q) */
cont=1; /* <- Variabile switch per routine step dinamico: stepdm() */
pn=pb; /* Scambio indirizzi anelli:anello 1 diventa anello 2 e viceversa */
pb=pa;
pa=pn;
j=_bios_keybrd(_KEYBRD_READY) & 255;
inizio4:;
} while(j==0);
getch();
if(j=='i') /* <- Inserimento nuovi dati */
goto inizio1;
else if(j=='r') /* <- Risimulazione */
goto inizio2;
else if(j=='c') /* <- Correzione */
{
stampa(pcoda,cl,1); /* <- stampa dati con 1:stampa dati completo */
do
{
j=(short)correzione(indir.pt1,pcoda,n);
if(j==0) /* <-Se il valore di ritorno Š j=0 allora correggi lo step */
{
step0=val_step();
if(step0<0)
dm=1;
else dm=0;
step0=fabs(step0);
}
do /* <- Verifica se esistono elementi con stesse coordinate */
{
j=verifica(pcoda);
if(j!=0)
correzione(indir.pt1,pcoda,n);
} while (j!=0);
_settextcolor(14);
_outtext("Altro?(s\\n) ");
_settextcolor(15);
} while (getch() =='s');
j='r';
goto inizio2;
}
else if(j=='q')
{
_setvideomode(_DEFAULTMODE);
exit(0);
}
else
{
j=0;
goto inizio4;
}
} /* Fine main */
double val_step() /* Routine di richiesta step */
{
double step;
char ch[10];
_outtext("Step(tempo<=0.02) ");
scanf("%s",ch);
_outtext(ch);
step=atof(ch);
_outtext(" Step dinamico?(s\\n) ");
if(getche()=='s')
step=-step; /* Se si richiede uno step dinamico:restituisci_ */
_outtext("\n"); /* uno step negativo come parametro di controllo */
return(step);
}
double stepdm(ax,ay,step,n,q,cont) /* <- Routine step dinamico */
double ax,ay,step;
short n,q;
{
double ar;
static double amax,vstp;
ar=ax*ax+ay*ay;
if(q==1)
amax=0.0;
amax=max(amax,ar);
if((q!=n) || (amax==0.0))
return(step);
if(cont==0)
{
vstp=sqrt(amax)*step;
return(step);
}
step=vstp/sqrt(amax);
return(step);
}
struct punt puntdati() /* Ritorna una struct contenente 3 puntatori_ */
{ /* al 1øelemento degli anelli e della coda */
double x,y,vx,vy,m;
short n,c;
struct dati a,input();
struct dati *pt1b,*pt1a,*pt2b,*pt2a; /* <-Puntatori anelli */
struct dati *ptc,*pptc,*p_iniz; /* <-Puntatori coda */
struct punt b;
pt1a=NULL;pt2a=NULL;pptc=NULL;p_iniz=NULL;pt1b=NULL;
n=0; /* <- n=contatore elementi_masse inseriti */
inizio3: /* <- Label inizio3:rientro routine Correzione */
a=input(n);
/* Inserimento dati */
while (a.m>=0.0)
{ /* Importante:devo specificare (struct dati*) in malloc */
pt1b=(struct dati*)malloc(sizeof(struct dati));
pt1b->x=320.0+a.x*cos(a.y*PI/180.0); /* in a.x =r */
pt1b->y=240.0-a.x*sin(a.y*PI/180.0); /* in a.y= teta */
pt1b->vx=a.vx*cos(a.vy*PI/180.0); /* in a.vx= v */
pt1b->vy=-a.vx*sin(a.vy*PI/180.0); /* in a.vy= tetav */
pt1b->m=a.m;
if(pt1a==NULL) /* <- Costruzione anello 1 */
{
pt1a=pt1b;
pt1a->pt=pt1b;
}
pt1b->pt=pt1a->pt; /* Metti in pt della struct appena generata,il valore */
pt1a->pt=pt1b; /* di pt della struct precedente
t dell'ultimo ele_ */
pt1a=pt1b; /* mento puntera' sempre al 1ødell'anello. Infine */
/* pt della struct precedente punta alla struct appe_ */
/* na generata */
/* <- Costruzione anello 2 */
pt2b=(struct dati*)malloc(sizeof(struct dati));
pt2b->m=a.m; /* <-inserimento massa */
if(pt2a==NULL)
{
pt2a=pt2b;
pt2a->pt=pt2b;
}
pt2b->pt=pt2a->pt;
pt2a->pt=pt2b;
pt2a=pt2b;
/* Costruzione coda per conservare dati iniziali */
ptc=(struct dati*)malloc(sizeof(struct dati));
if(pptc==NULL)
{
pptc=ptc;
p_iniz=ptc;
}
pptc->pt=ptc;
ptc->pt=NULL;
pptc=ptc;
ptc->x=a.x; /* Inserimento dati */
ptc->y=a.y;
ptc->vx=a.vx;
ptc->vy=a.vy;
ptc->m=a.m;
n++;
if(p_iniz !=NULL) /* <- Verifica se due elementi hanno uguali coordinate */
do
{
c=verifica(p_iniz);
if(c!=0)
correzione(pt1b,p_iniz,n);
} while(c!=0);
a=input(n);
} /* <- fine while */
if((n==0) && (a.m==-1))
goto inizio3;
if(a.m==-2.0)
{
correzione(pt1b,p_iniz,n); /* <- Corregge dati inseriti */
goto inizio3;
}
b.pt1=pt1b->pt; /* Restituisce indirizzo 1øelemento anello 1 */
b.pt2=pt2b->pt; /* Restituisce indirizzo 1øelemento anello 2 */
b.pt3=p_iniz; /* Restituisce indirizzo 1øelemento coda */
b.n=n; /* Restituisce numero elementi introdotti */
return(b);
}
correzione(anello,coda,n) /* In anello riceve l'ultimo indirizzo */
struct dati *anello,*coda; /* generato:quindi deve aggiornarsi al */
short n; /* valore contenuto in pt per puntare */
{ /* al 1ø elmento dell'anello */
struct dati a,input();
short p,q;
char ch[10];
_settextcolor(14);
_outtext("Correzione elemento: N=");
_settextcolor(15);
scanf("%s",ch);
_outtext(ch);
_outtext("\n");
p=(short)atoi(ch);
if(p<=0)
return(0);
if((n==0) || (p>n)) /* <- Se il dato da correggere non Š gia' stato_ */
return(1); /* memorizzato in una struct:ritorna alla label_ */
anello=anello->pt; /* inzio3. Ritorna il valore 1 perchŠ 0 serve in */
if(n>1) /* caso di richiesta di correzione dello step */
for(q=1;q<p;q++)
{
anello=anello->pt;
coda=coda->pt;
}
/* Memorizzazione dati nella "coda" */
a=input(p-1); /* Alla routine input() viene passato il numero_ */
coda->x=a.x; /* di linea da correggere-1 */
coda->y=a.y;
coda->vx=a.vx;
coda->vy=a.vy;
coda->m=a.m;
anello->x= 320.0+a.x*cos(a.y*PI/180.0); /* Memorizzazione dati in anello */
anello->y= 240.0-a.x*sin(a.y*PI/180.0);
anello->vx=a.vx*cos(a.vy*PI/180.0);
anello->vy=-a.vx*sin(a.vy*PI/180.0);
anello->m=a.m;
return(1); /* Ritorna il valore 1 perchŠ 0 serve in caso di_ */
} /* richiesta correzione step */
struct dati input(n)
short n;
{
double r,teta,m,v,tetav;
struct dati a;
int p='s',q='c';
char ch[20];
sprintf(ch,"%d ",n+1); /* <- Numerazione linee */
_outtext(ch);
_outtext("r(pixel)=");
scanf("%s",ch);
if(strchr(ch,p)!=NULL || strchr(ch,q)!=NULL)
goto fine;
_outtext(ch);
r=atof(ch);
_outtext(" angolo=");
scanf("%s",ch);
if(strchr(ch,p)!=NULL || strchr(ch,q)!=NULL)
goto fine;
_outtext(ch);
teta=atof(ch);
_outtext(" massa(10-..)=");
scanf("%s",ch);
if(strchr(ch,p)!=NULL || strchr(ch,q)!=NULL)
goto fine;
_outtext(ch);
m=atof(ch);
_outtext(" velocita'(1-..)=");
scanf("%s",ch);
if(strchr(ch,p)!=NULL || strchr(ch,q)!=NULL)
goto fine;
_outtext(ch);
v=atof(ch);
_outtext(" angolo=");
scanf("%s",ch);
if(strchr(ch,p)!=NULL || strchr(ch,q)!=NULL)
goto fine;
_outtext(ch);
_outtext("\n");
tetav=atof(ch);
a.x=r; /* x= r */
a.y=teta; /* y= teta */
a.vx=v; /* vx= v */
a.vy=tetav; /* vy= tetav */
a.m=m;
return(a);
fine:
if(strchr(ch,p)!=NULL)
a.m=-1.0;
else if(strchr(ch,q)!=NULL)
a.m=-2.0;
_outtext("\n");
return(a);
}
stampa(punt,cl,c) /* Routine stampa dati */
struct dati *punt; /* c:variabile per stampa completa o semplificata */
short c,cl[];
{
double r,m,v,angl1,angl2;
char ch[80];
short p=4,n=3;
if(c==0)
{
_settextposition(3,1);
_outtext("n R V M");
do
{
r=punt->x;
v=punt->vx;
m=punt->m;
punt=punt->pt;
_settextcolor(cl[((p-4) % 7)]);
_settextposition(p,1);
sprintf(ch,"%d ",p-3);
_outtext(ch);
_settextcolor(15);
_settextposition(p,n);
sprintf(ch,"%lg",r);
_outtext(ch);
_settextposition(p,n+4);
sprintf(ch,"%lg",v);
_outtext(ch);
_settextposition(p,n+8);
sprintf(ch,"%lg",m);
_outtext(ch);
p++;
} while(punt !=NULL);
return;
} /* <-Fine if(c) */
else if(c==1)
{
do
{
r=punt->x;
angl1=punt->y;
v=punt->vx;
angl2=punt->vy;
m=punt->m;
punt=punt->pt;
_settextposition(p-1,1);
_settextcolor(cl[((p-4) % 7)]);
sprintf(ch,"%d ",p-3);
_outtext(ch);
_settextcolor(15);
sprintf(ch,"r=%lg angolo=%lg m=%lg v=%lg angolo=%lg\n",r,angl1,m,v,angl2);
_outtext(ch);
p++;
} while (punt!=NULL);
} /* <-Fine else if(c) */
}
cancella(pa,pb,pcoda,n) /* Cancella struct generate:anelli,code */
struct dati *pa,*pb,*pcoda;
short n;
{
struct dati *pn;
short p;
for(p=1;p<=n;p++)
{
pn=pa->pt;
free(pa);
pa=pn;
pn=pb->pt;
free(pb);
pb=pn;
pn=pcoda->pt;
free(pcoda);
pcoda=pn;
}
return;
}
verifica(pc)
struct dati *pc;
{
double r1,r2,teta1,teta2;
struct dati *pn;
if(pc->pt ==NULL) /* <- Se solo un elemento Š stato introdotto */
return(0); /* allora -> nessuna verifica */
while (pc->pt !=NULL)
{
pn=pc;
r1=pc->x;
teta1=pc->y;
while (pn->pt !=NULL)
{
pn=pn->pt;
r2=pn->x;
teta2=pn->y;
if((r1==r2) && (teta1==teta2))
{
printf("\a");
_settextcolor(14);
_outtext("Attenzione:due elementi hanno coordinate uguali\n");
_settextcolor(15);
return(1);
}
} /* Fine while 2 */
pc=pc->pt;
} /* Fine while 1 */
return(0);
}
croce() /* Disegna croce al centro schermo */
{
_setcolor(15);
_moveto(312,240);
_lineto(328,240);
_moveto(320,235);
_lineto(320,245);
return;
}
punt_start(pcoda) /* Disegna punti di partenaza grafici */
struct dati *pcoda;
{
double x,y;
do
{
x=320.0+(pcoda->x)*cos((pcoda->y)*PI/180.0);
y=240.0-(pcoda->x)*sin((pcoda->y)*PI/180.0);
_ellipse_w(_GBORDER,x-1,y-1,x+1,y+1);
pcoda=pcoda->pt;
} while (pcoda !=NULL);
return;
}