/* Archi di parabola per l' SVG http://www.elegio.it/svg/svg2014/
/*

2^^^^ La curva ad archi di cerchio o parabola la chiamo ondulata 6^^^^

*/
//
function faparabola(M,C){
    var cc=[":",(C[1]+M[1])/2,(C[2]+M[2])/2];
    return ["Q",M[1],M[2],cc[1],cc[2] ];
    }
//
function faparabolaf(M,C){
    var cc=[":",C[1],C[2]];
    return ["Q",M[1],M[2],cc[1],cc[2] ];
    }
//
//  Questa e' la funzione di esecuzione della curva 
//  basata sugli ARCHI DI PARABOLA. 
//
function fadisegnop(ondulata,qualdisegno){
    var j,n,nonfa,dopo,ild;
    var ilpath=document.getElementById(qualdisegno);
    n=ondulata.length;
    ild=" M "+ondulata[1][1]+" "+ondulata[1][2]+" ";
    dopo=false;
    for(j=3;n>j;j+=1){
        nonfa=(!Array.isArray(ondulata[j])) ||
            (!Array.isArray(ondulata[j-1])) ;
        if(!nonfa){
           if(dopo){ild+=" M "+ondulata[j][1]+
                    " "+ondulata[j][2]+" ";
                    dopo=false;}
           else if(j==n-1)ild+=prosvg(faparabolaf(
                  ondulata[j-1],ondulata[j]));
           else if(!Array.isArray(ondulata[j+1])
                  )ild+=prosvg(faparabolaf(
                  ondulata[j-1],ondulata[j]));
           else ild+=prosvg(faparabola(
               ondulata[j-1],ondulata[j]));
           }
        else dopo=true;
        }
    if(ilpath.getAttribute("d")==null){
       ilpath.innerHTML=ild;}
    else ilpath.setAttribute("d",ild);
    return ild;
    }
/*

3^^^^ Archi di cerchio ( una curva con lievi discontinuità ) 1^^^^

*/
//
// Questa e' la funzione fondamentale per gli ARCHI DI CERCHIO. 
// Dati tre punti crea un vettore di lunghezza 8 che puo' essere
// o un segmento segnalato da L o un arco di cerchio
// segnalato da una A.
//
function facerchio(B,M,C){
   var bx,by,brq,cx,cy,crq,dn,ox,oy,pr=0;
   bx=B[1]-M[1];
   by=B[2]-M[2];
   brq=bx*bx+by*by;
   cx=C[1]-M[1];
   cy=C[2]-M[2];
   crq=cx*cx+cy*cy;
   dn=2*(by*cx-bx*cy);
   if(dn>=0)dn=1/(dn+1e-9);
   else dn=1/(dn-1e-9);
   ox=(by*crq-cy*brq)*dn;
   oy=(cx*brq-bx*crq)*dn;
   rr=Math.ceil(64*Math.sqrt(ox*ox+oy*oy))/64;
   if(rr>1000000)return [" L ",C[1],C[2] ];
   if(ox*by>oy*bx)pr=1;
   return [" A ",rr,rr,0,0,pr,C[1],C[2]] }
//
// Traduce in stringa usabile dal path un vettore di 8 elementi 
//
function prosvg(vet){
    var j,n,ss=" ";
    if(Array.isArray(vet)){ n=vet.length;
        for(j=0;n>j;j++)ss+=vet[j]+" ";}
    return ss;
    }
//
//  Questa e' la funzione di esecuzione della curva 
//  basata sugli ARCHI DI CERCHIO. 
//
function fadisegno(ondulata,qualdisegno){
    var j,n,nonfa,dopo,ild;
    var ilpath=document.getElementById(qualdisegno);
    n=ondulata.length;
    ild=" M "+ondulata[1][1]+" "+ondulata[1][2]+" ";
    dopo=false;
    for(j=3;n>j;j+=2){
        nonfa=(!Array.isArray(ondulata[j])) ||
            (!Array.isArray(ondulata[j-1])) ||
            (!Array.isArray(ondulata[j-2])) ;
        if(!nonfa){
           if(dopo){ild+=" M "+ondulata[j][1]+
                    " "+ondulata[j][2]+" ";
                    dopo=false;}
           else ild+=prosvg(facerchio(ondulata[j-2],
                ondulata[j-1],ondulata[j]));
           }
        else dopo=true;
        }
    // ild+=" Z";
    ilpath.setAttribute("d",ild);
    return ild;
    }
/*

4^^^^ Per coprire di palline le curve ad archi di parabola o di cerchio 2^^^^

*/
//
// Funzione analoga alla fadisegnop e alla fadisegno.
// 
// Ma non disegna una curva ma disegna palline piu' o meno
// grandi attorno ai punti da usare per fare la curva.
//
function fapalline(ondulata,qualdisegno){
    var j,n,nonfa,rr,ild;
    var ilpath=document.getElementById(qualdisegno);
    n=ondulata.length;
    rr=3;
    ild=" M "+(ondulata[1][1]-rr)+" "+ondulata[1][2]+
             " a "+rr+" "+rr+" 0 0 0 "+(2*rr)+ " 0"+
             " a "+rr+" "+rr+" 0 0 0 "+(-2*rr)+" 0 ";
    rr+=0.75;
    for(j=3;n>j;j+=2){
        nonfa=(!Array.isArray(ondulata[j])) ||
            (!Array.isArray(ondulata[j-1])) ||
            (!Array.isArray(ondulata[j-2])) ;
        if(nonfa)rr=3;
        else{ild+=" M "+(ondulata[j][1]-rr)+" "+ondulata[j][2]+
             " a "+rr+" "+rr+" 0 0 0 "+(2*rr)+ " 0"+
             " a "+rr+" "+rr+" 0 0 0 "+(-2*rr)+" 0 ";rr+=0.5;
            rr=Math.min(rr,12);
            }
       }
    ilpath.setAttribute("d",ild);
    return ild;
    }
/*

5^^^^ Convenzione Multidimensionale per specificare punti. 3^^^^

*/
//
// Segue questa regola: ogni punto e' un vettore e, se usa 
// gli archi di cerchio, usa i punti dispari come estremi 
// dell'arco e i punti pari come punto interno di controllo. 
// Come regola generale non usa mai l'elemento zero di 
// un vettore e l'elemento 1 e' l'ascissa e il 2
// e' l'ordinata. 
// Questa convenzione la uso per potere lavorare
// facilmente anche in tre o quattro dimensioni e potere
// disegnare sempre solo le prime due coordinate
//
// FUNZIONI DI SERVIZIO PER APPLICARE QUESTA CONVENZIONE
//
// Funzione per convertire il vettore di punti 
// multidimensionali con eventuli interruzione di punti 
// in un vettore di coordinate bidimensionali 
// senza interruzione di punti.
//
function invettorezz(multidim){
    var j,k=0,n,vet=[];
    n=multidim.length;
    for(j=0;n>j;j++){
        if(Array.isArray(multidim[j])){
            vet[k]=multidim[j][1];k++;
            vet[k]=multidim[j][2];k++;
            }
        }
    return vet;
    }
//
// Funzione per convertire un vettore di coordinate solo
// bidimensionali in un vettore di punti multidimensionali 
// che in questo caso sono anche loro bidimensionali. 
//
function davettorezz(vet,scala){
    var j,k=1,multidim=["Puntimultidim"];
    n=vet.length;
    for(j=1;n>j;j+=2){
        multidim[k]=[" ("+(k-1)+") ",
              scala*vet[j-1],scala*vet[j]];
        k++;}
    return multidim; 
    }
//
//  Cambia la scala del disegno :
//  vxmax e vymaz sono le dimensioni della immagine SVG
//
function scala(ond,xsca,ysca,vxmax,vymax){
    var j,sx,sy,dsx,dsy,frid=0.95,xmin=1.e9,ymin=1.e9;
    var xmax=-1.e9,ymax=-1.e9,n=ond.length,sond=[];
    for(j=0;n>j;j++){
         if(Array.isArray(ond[j])){ 
            x=ond[j][1]*xsca;
            y=ond[j][2]*ysca;
            xmin=Math.min(x,xmin);
            xmax=Math.max(x,xmax);
            ymin=Math.min(y,ymin);
            ymax=Math.max(y,ymax);
            sond[j]=
            [ond[j][0],ond[j][1]*xsca,ond[j][2]*ysca];
            }
         else sond[j]=ond[j];
         }
    sx=frid*(1+Math.floor(16*(vxmax/(xmax-xmin+0.00001)-1))/16);
    sy=frid*(1+Math.floor(16*(vymax/(ymax-ymin+0.00001)-1))/16);
    dsx=vxmax/2-sx*(xmax+xmin)/2;
    dsy=vymax/2-sy*(ymax+ymin)/2;
    //
    for(j=0;n>j;j++){
         if(Array.isArray(sond[j])){ 
            sond[j]=
            [sond[j][0],Math.round(16*(sond[j][1]*sx+dsx))/16,
                        Math.round(16*(sond[j][2]*sy+dsy))/16];
            }
         }
    //
    return sond;
    }
//
/*

6^^^^ PER LA MESSA A PUNTO DI QUESTA LIBRERIA 4^^^^

*/
//
// Qui definisco una funzione che genera una sinusoide
// amplificata da una funzione esponenziale e leggermente
// perturbata da un rumore cositituito da una aggiunta random...
//
// In questo modo ogni volta che la funzione viene chiamata
// si ottiene una curla leggermente diversa...
//
// Esempio di vettore per punti multidimensionali.
//
var ond=["Ondulata",[" 1) ",400,75],
    [" 2) ",775,450],[" 3) ",400,825],
    [" 4) ",665,715],[" 5) ",775,450]];
//
// Per mettere a punto le funzioni di disegno dell'arco 
// definisco questa funzione piuttosto balorda ma utile 
// per mettere alla prova le varie opzioni.
//
function provaondulatoria(xnpassi){
   var j,tt,xx,yy,npassi,incre,ond=["Ondula"];
   npassi=2*Math.round(xnpassi);
   // alert("Fa "+npassi+" passi");
   incre=1200/(npassi/3.7);
   for(j=1;npassi>j;j++){
      tt=(j-1)*(Math.PI/12);
      xx=20+incre*tt;
      xx=Math.round(32*xx)/32;
      yy=450+50*Math.exp(tt*0.07)*Math.sin(tt)+10*Math.random();
      yy=Math.round(32*yy)/32;
      if(j%20==0) ond[j]=" (salto) ";
      else ond[j]=[" ("+(j-1)+") ",xx,yy];}
   return ond;
   }
//
var d_esempio="M 100 100 "+
              "a 60 60 0 0 0 120 0 a 60 60 0 0 0 -120 0" ;
//
var questaversione=["20140914","Archi di parabola e di cerchio" ];
/*

1^^^^ AMEN ( Libreria essenziale delle curve ad archi di parabola e di cerchio ) 5^^^^

-
*/