#include <stdio.h>
#include <stdlib.h>
#include <float.h>
#include <math.h>

#define FILEIN "segmenti.bin"
#define M_MIN  10.0
#define NPUNTI 1000000
#define XMIN   -100.0
#define XMAX   +100.0

typedef struct _seg {float x1,y1,x2,y2;} seg;
typedef seg*                             pseg;
typedef struct _ret {float m,q;}         ret;
typedef ret*                             pret;

typedef FILE*   pfile;

void printf_retta(pret pr) {printf("y=%.2fx+%.2f",pr->m,pr->q);}

int main(void)
 {unsigned nseg,i,nr,j;
  pseg     ps,ps1;
  pret     pr,pr1,prmin;
  float    m,q,dy,dymin=FLT_MAX,d,x,y,yr1,xmin,ymin;
  pfile    pf;

  if ((pf=fopen(FILEIN,"rb"))==NULL) goto file_err;
  if (fread(&nseg,sizeof(unsigned),1,pf)!=1) goto file_err;
  if ((ps=(pseg)malloc(sizeof(seg)*nseg))==NULL) goto mem_err;
  fread(ps,sizeof(seg),nseg,pf);
  fclose(pf);

  for(nr=i=0,ps1=ps;i<nseg;i++,ps1++)
   {d=((ps1->x2)-(ps1->x1));
    if (d)
    {m=((ps1->y2)-(ps1->y1))/d;
     if (fabs(m)<M_MIN) 
      {q=(ps1->y1)-m*(ps1->x1);
       ps[nr].x1=m;
       ps[nr++].y1=q;
      }
    }
   }

  printf("%d rette soddisfano i requisiti richiesti\n",nr);
  if (nr<=1) free(ps);
  else
   {if ((pr=(pret)malloc(sizeof(ret)*nr))==NULL) {free(ps); goto mem_err;}
    for(i=0,ps1=ps,pr1=pr;i<nr;i++,ps1++,pr1++) {pr1->m=ps1->x1; pr1->q=ps1->y1;};
    free(ps);
    printf("Cerco punto più vicino alla retta "); 
    printf_retta(pr);
    for(d=(XMAX-XMIN)/(NPUNTI-1),j=0;j<NPUNTI;j++)
     {x=XMIN+j*d;
      yr1=(pr->m)*x+(pr->q);
      for(i=1,pr1=pr+1;i<nr;i++,pr1++)
       {y=(pr1->m)*x+(pr1->q);
        if ((dy=fabs(y-yr1))<dymin) {dymin=dy; prmin=pr1; xmin=x;ymin=y;}
       }
     }
     free(pr);
     printf("\nLa retta ");
     printf_retta(prmin);
     printf(" e' la piu' vicina!\nPunto d'intersezione (x=%.2f,y=%.2f)\n",xmin,ymin);
   }

  return EXIT_SUCCESS;

  file_err: printf("Problema col file!!\n");       return EXIT_FAILURE;
  mem_err:  printf("Problema con la memoria!!\n"); return EXIT_FAILURE;

 }
