//Javascript zur Seite über kubische Splines
// (c) Arndt Brünner, alle Rechte vorbehalten!
// Version: 3.4.2006

var aa=new Array(),bb=new Array(),cc=new Array(),dd=new Array(),xx=new Array(),yy=new Array(),nxx=0;
var N=0,v=new Array("","");

function berechnekubspline()
{
	document.f.s.value="";
	var t=document.f.w.value.replace(/,/g,".");
	t=t.replace(/[\n\r\t\(\);|]/g," ").replace(/ +/g," ");
	if((t.charAt(0)==" ")&&(t!=""))t=t.substr(1,t.length-1);
	if((t.charAt(t.length-1)==" ")&&(t!=""))t=t.substr(0,t.length-1);
	var T=t.split(" "),l=T.length,i,j=0,k=0;
	if(((l%2)==1)||(l==0))return;
	var r=parseInt("10000000000000000000".substr(0,document.f.r.selectedIndex+3));
	var rat=(document.f.r.selectedIndex==11);//||(t.indexOf("/")>-1));
	var p0=document.f.p0.value;//.split("=");if(p0.length==1){p0[1]=p0[0];p0[0]="k";}
	var p1=document.f.pn.value;//.split("=");if(p1.length==1){p1[1]=p1[0];p1[0]="k";}
	if(!lhr)return;
	p0=(String(p0).replace(/,/,"."));
	p1=(String(p1).replace(/,/,"."));
	var n=l/2-1;
	var x=new Array(n+1),y=new Array(n+1);
	xx=new Array();
	if(rat)
	{
		p0=toBruch(p0);p1=toBruch(p1);
		if(isNaN(p0[0]/p0[1])||isNaN(p1[0]/p1[1])){alert("Fehler bei der Eingabe der Krümmung");return;}
		for(i=0;i<=n;i++)
		{
			x[i]=toBruch(XX=T[j++]);
			if(x[i][1]>100000000){if(XX.indexOf("/")>-1)XX=eval(XX);var B=kettenbruchapprox(XX,1000000000,1e-14);if(B[1]!=1){x[i][0]=B[0];x[i][1]=B[1];}else break;}
			y[i]=toBruch(YY=T[j++]);
			if(y[i][1]>100000000){if(YY.indexOf("/")>-1)YY=eval(YY);var B=kettenbruchapprox(YY,1000000000,1e-14);if(B[1]!=1){y[i][0]=B[0];y[i][1]=B[1];}else break;}
			xx[i]=x[i][0]/x[i][1];
			yy[i]=y[i][0]/y[i][1];
			if(isNaN(xx[i])||isNaN(yy[i])){alert("Eingabefehler");return;}
		}
		if(i<=n){document.f.r.selectedIndex=10;berechnekubspline();return;}
		//alert(x);
		quicksort3(xx,x,y);
		var mn=new Array(j=(n+2)*(n+1)),mz=new Array(j);
		for(i=0;i<j;i++){mz[i]=0;mn[i]=1;}
		for(i=1;i<n;i++)
		{
			if(xx[i]==xx[i+1]){alert("Fehler:\nZwei identische x-Werte: "+bstr(x[i][0],x[i][1]));return;}
			var I=i*(n+2)+i
			mz[I-1]=x[i][0]*x[i-1][1]-x[i-1][0]*x[i][1];
			mn[I-1]=x[i][1]*x[i-1][1];
			mz[I]=2*(x[i+1][0]*x[i-1][1]-x[i-1][0]*x[i+1][1]);
			mn[I]=x[i+1][1]*x[i-1][1];
			mz[I+1]=(x[i+1][0]*x[i][1]-x[i][0]*x[i+1][1]);
			mn[I+1]=x[i+1][1]*x[i][1];
		}
		var az=new Array(n+1),an=new Array(n+1),bz=new Array(n+1),bn=new Array(n+1),
		    cz=new Array(n+1),cn=new Array(n+1),dz=new Array(n+1),dn=new Array(n+1);
		mz[0]=2;bz[0]=mz[n+1]=p0[0];bn[0]=mn[n+1]=p0[1];
		mz[j-2]=2;bz[n]=mz[j-1]=p1[0];bn[n]=mn[j-1]=p1[1];
		for(i=1;i<=n-1;i++)
		{
			var xz0=x[i-1][0],xn0=x[i-1][1];
			var xz1=x[i][0],xn1=x[i][1];
			var xz2=x[i+1][0],xn2=x[i+1][1];
			var yz0=y[i-1][0],yn0=y[i-1][1];
			var yz1=y[i][0],yn1=y[i][1];
			var yz2=y[i+1][0],yn2=y[i+1][1];
			mz[(i+1)*(n+2)-1]=3*xn1*(yn0*(yn1*yz2*xn2*(xn0*xz1-xn1*xz0)+yn2*yz1*xn1*(xn2*xz0-xn0*xz2))+yn1*yn2*yz0*xn0*(xn1*xz2-xn2*xz1));
			mn[(i+1)*(n+2)-1]=yn0*yn1*yn2*(xn0*xz1-xn1*xz0)*(xn1*xz2-xn2*xz1);
			//m[(i+1)*(n+2)-1]=3*((y[i+1]-y[i])/(x[i+1]-x[i])-(y[i]-y[i-1])/(x[i]-x[i-1]));
		}
		//alert(mz+"\n\n"+mn);
		for(i=0;i<j;i++)kuerzen(mz,mn,i);
		Erkl=false;
		t=status;
		GLSLB(mz,mn,bz,bn,n+1);
		status=t;
		//alert(mz+"\n\n"+mn);
		//alert(bz+"\n\n"+bn);
		for(i=0;i<n;i++)
		{
			var bz1=bz[i],bn1=bn[i],bz2=bz[i+1],bn2=bn[i+1];
			var xz1=x[i][0],xn1=x[i][1],xz2=x[i+1][0],xn2=x[i+1][1];
			var yz1=y[i][0],yn1=y[i][1],yz2=y[i+1][0],yn2=y[i+1][1];
			
			cz[i]=bn1*(3*bn2*xn1*xn1*xn2*xn2*yn1*yz2-yn2*(3*bn2*xn1*xn1*xn2*xn2*yz1+bz2*yn1*(xn1*xz2-xn2*xz1)*(xn1*xz2-xn2*xz1))) - 2*bn2*bz1*yn1*yn2*(xn1*xz2 - xn2*xz1)*(xn1*xz2 - xn2*xz1);
			    //3·bn2·xn1^2  ·xn2^2·  (yn1·yz2-yn2·yz1)-yn1·yn2·(2·bz1+bz2)·(xn1·xz2-xn2·xz1)^2
			cn[i]=3*bn1*bn2*xn1*xn2*yn1*yn2*(xn1*xz2 - xn2*xz1);
			    //3·bn1·bn2·xn1·xn2·yn1·yn2·(xn1·xz2 - xn2·xz1)
			kuerzen(cz,cn,i);
			//c[i]=(y[i+1]-y[i])/(x[i+1]-x[i])-(b[i+1]+2*b[i])/3*(x[i+1]-x[i]);
		}
		for(i=0;i<n;i++)
		{
			var bz1=bz[i],bn1=bn[i],bz2=bz[i+1],bn2=bn[i+1];
			var xz1=x[i][0],xn1=x[i][1],xz2=x[i+1][0],xn2=x[i+1][1];
			az[i]=xn1*xn2*(bn1*bz2-bn2*bz1);
			an[i]=3*bn1*bn2*(xn1*xz2-xn2*xz1);
			kuerzen(az,an,i);
			//a[i]=(b[i+1]-b[i])/(3*(x[i+1]-x[i]));
		}
		t="";
		for(i=0;i<n;i++)
		{
			var X=("(x-"+bstr(x[i][0],x[i][1])+")").replace(/--/,"+");
			if(x[i][0]==0)X="x";
			t+="x aus ["+bstr(x[i][0],x[i][1])+"; "+bstr(x[i+1][0],x[i+1][1])+"]\n";
			t+="S"+i+"(x) =";
			if(az[i]!=0){t+=(" + "+bstr(az[i],an[i])+"·").replace(/ 1·/," ").replace(/\+ -1·/,"- ")+X+"^3";}
			if(bz[i]!=0){t+=(" + "+bstr(bz[i],bn[i])+"·").replace(/ 1·/," ").replace(/\+ -1·/,"- ")+X+"^2";}
			if(cz[i]!=0){t+=(" + "+bstr(cz[i],cn[i])+"·").replace(/ 1·/," ").replace(/\+ -1·/,"- ")+X;}
			if(y[i][0]!=0){t+=(" + "+bstr(y[i][0],y[i][1])+" ");}
			t+="\n______="
			var xxz=x[i][0],xxn=x[i][1];
			var bbz=an[i]*bz[i]*xxn - 3*az[i]*bn[i]*xxz,bbn=an[i]*bn[i]*xxn;
			var ccz=an[i]*xxn*(bn[i]*cz[i]*xxn - 2*bz[i]*cn[i]*xxz) + 3*az[i]*bn[i]*cn[i]*xxz*xxz;
			var ccn=bbn*cn[i]*xxn;
			var ddz=an[i]*xxn*(bn[i]*xxn*(cn[i]*y[i][0]*xxn - cz[i]*y[i][1]*xxz) + bz[i]*cn[i]*y[i][1]*xxz*xxz) - az[i]*bn[i]*cn[i]*y[i][1]*xxz*xxz*xxz;
			var ddn=ccn*y[i][1]*xxn;
			var g=ggT(bbz,bbn);bbz/=g;bbn/=g;
			g=ggT(ccz,ccn);ccz/=g;ccn/=g;
			g=ggT(ddz,ddn);ddz/=g;ddn/=g;
			if(az[i]!=0){t+=(" + "+bstr(az[i],an[i])+"·").replace(/ 1·/," ").replace(/\+ -1·/,"- ")+"x^3";}
			if(bbz!=0){t+=(" + "+bstr(bbz,bbn)+"·").replace(/ 1·/," ").replace(/\+ -1·/,"- ")+"x^2";}
			if(ccz!=0){t+=(" + "+bstr(ccz,ccn)+"·").replace(/ 1·/," ").replace(/\+ -1·/,"- ")+"x";}
			if(ddz!=0){t+=(" + "+bstr(ddz,ddn)+" ");}
			t+="\n";
 		}
		t=t.replace(/\+ \n/g,"\n").replace(/\+ -/g,"- ").replace(/\+ \+/g,"+");
		t=t.replace(/= \+/g,"= ").replace(/= - /g,"= -").replace(/ +/g," ");
		t=t.replace(/_/g," ");
		//tt=tt.substring(1,tt.length).replace(/\./g,",").replace(/\t,/g," 0,").replace(/ ,/g," 0,").replace(/-,/g,"-0,");
		N=n+1;
		for(i=0;i<n;i++){aa[i]=az[i]/an[i];bb[i]=bz[i]/bn[i];cc[i]=cz[i]/cn[i];dd[i]=y[i][0]/y[i][1];xx[i]=x[i][0]/x[i][1];}
		xx[n]=x[n][0]/x[n][1];dd[n]=y[n][0]/y[n][1];
		document.f.s.value=t;//.replace(/,/g,".").replace(/\[,/g,"[0,").replace(/-,/g,"-0,").replace(/ ,/g," 0,");
		var maxx=0,maxy=0,maxxx=0,maxyy=0;
		for(i=0;i<=n;i++)
		{
			maxx=Math.max(maxx,String(x[i][0]).length);
			maxy=Math.max(maxy,String(y[i][0]).length);
			maxxx=Math.max(maxx,String(x[i][1]).length);
			maxyy=Math.max(maxy,String(y[i][1]).length);
		}
		tt="";
		for(i=0;i<=n;i++)
		{
			var d=(x[i][1]==1)?1:0;
			var ttt="                      ".substr(0,maxx-String(x[i][0]).length+1+d)+bstr(x[i][0],x[i][1]);
			d=(y[i][1]==1)?1:0;
			tt+=ttt+"                      ".substr(0,maxx+maxxx+3-ttt.length)+"                 ".substr(0,maxy-String(y[i][0]).length+1+d)+bstr(y[i][0],y[i][1])+"\n";
		}
		document.f.w.value=tt;
		interpol();
	}
	else
	{
		for(i=0;i<=n;i++){x[i]=Number(eval(T[j++]));y[i]=Number(eval(T[j++]));}
		p0=Number(eval(String(p0).replace(/,/,".")));p1=Number(eval(String(p1).replace(/,/,".")));
		quicksort2(x,y);
		var m=new Array(j=(n+2)*(n+1))
		for(i=0;i<j;i++)m[i]=0;
		for(i=1;i<n;i++)
		{
			if(x[i]==x[i+1]){alert("Fehler:\nZwei identische x-Werte: "+rund(x[i],100000000000000));return;}
			var I=i*(n+2)+i;
			m[I-1]=x[i]-x[i-1];
			m[I]=2*(x[i+1]-x[i-1]);
			m[I+1]=(x[i+1]-x[i]);
		}
		m[0]=2;m[n+1]=p0;
		m[j-2]=2;m[j-1]=p1;
		for(i=1;i<=n-1;i++)m[(i+1)*(n+2)-1]=3*((y[i+1]-y[i])/(x[i+1]-x[i])-(y[i]-y[i-1])/(x[i]-x[i-1]));
		var v=new Array(n+1);
		GLSL(m,v,n+1);//alert(v);
		var b=new Array(n+1),c=new Array(n+1),a=new Array(n+1);
		for(i=0;i<n+1;i++)b[i]=v[i];
		//if(p0[0]=="k")b[0]=p0[1]/2;else b[0]=(-3*(p0[1]*x[1]-p0[1]*x[0]-y[1]+y[0])/((x[1]-x[0])*(x[1]-x[0]))-b[1])/2;
		//if(p1[0]=="k")b[n]=p1[1]/2;else b[n]=-3*(p1[1]*x[n]-p1[1]*x[n-1]-y[n]+y[n-1])/((x[n]-x[n-1])*(x[n]-x[n-1]))-b[n-1]*2;	

		for(i=0;i<n;i++)
		{
			c[i]=(y[i+1]-y[i])/(x[i+1]-x[i])-(b[i+1]+2*b[i])/3*(x[i+1]-x[i]);
		}

		//if(p1[0]=="m"){c[n-1]=c[n-2]+(b[n-1]+b[n-2])*(x[n-1]-x[n-2]);b[n]=(p1[1]-c[n-1])/(x[n]-x[n-1])-b[n-1];}
		//c[0]=0;
		//c[n]=0;
		for(i=0;i<n;i++)a[i]=(b[i+1]-b[i])/(3*(x[i+1]-x[i]));
		t="";var p=new Array(4),tt="\n";
		var maxx=0,maxy=0,maxxx=0,maxyy=0;
		for(i=0;i<=n;i++)
		{
			maxx=Math.max(maxx,Math.abs(x[i]));
			maxy=Math.max(maxy,Math.abs(y[i]));
			if(x[i]!=Math.floor(x[i]))maxxx=Math.max(String(x[i]).length-String(x[i]).indexOf("."),maxxx);
			if(y[i]!=Math.floor(y[i]))maxyy=Math.max(String(y[i]).length-String(y[i]).indexOf("."),maxyy);
		}
		maxx=Math.floor(Math.log(maxx)/2.30258509299405)+1;
		maxy=Math.floor(Math.log(maxy)/2.30258509299405)+1;
		for(i=0;i<n;i++)
		{
			p[0]=rund(y[i],r);p[1]=rund(c[i],r);p[2]=rund(b[i],r);p[3]=rund(a[i],r);
			var X=("(x-"+x[i]+")").replace(/\./,",").replace(/-,/,"-0,").replace(/--/,"+");
			if(x[i]==0)X="x";
			t+="x aus ["+x[i]+"; "+x[i+1]+"]\n";
			t+="S"+i+"(x) = "+pstr(p).replace(/x/g,X)+"\n";
			p[0]=rund(-a[i]*x[i]*x[i]*x[i] + b[i]*x[i]*x[i] - c[i]*x[i] + y[i],r);
			p[1]=rund(3*a[i]*x[i]*x[i] - 2*b[i]*x[i] + c[i],r);
			p[2]=rund(b[i]-3*a[i]*x[i],r);
			p[3]=rund(a[i],r);
			if(i>9)t+=" ";
			t+="      = "+pstr(p)+"\n";
			tt+=tab(x[i],maxx+2,maxxx+1)+tab(y[i],maxy+3)+"\n";

 		}
		tt+=tab(x[i],maxx+2,maxxx+1)+tab(y[i],maxy+3);
		tt=tt.substring(1,tt.length).replace(/\./g,",").replace(/\t,/g," 0,").replace(/ ,/g," 0,").replace(/-,/g,"-0,");
		N=n+1;
		for(i=0;i<a.length;i++){aa[i]=a[i];bb[i]=b[i];cc[i]=c[i];yy[i]=dd[i]=y[i];xx[i]=x[i];}
		xx[N]=x[N];dd[N]=y[N];
		document.f.s.value=t.replace(/\./g,",").replace(/\[,/g,"[0,").replace(/-,/g,"-0,").replace(/ ,/g," 0,");
		document.f.w.value=tt;

		interpol();
	}
	if((document.kubsplineplot!=null)&&navigator.javaEnabled())
	{
		document.kubsplineplot.ks_modus=1;
		document.kubsplineplot.zeigePunkte=true;
		document.kubsplineplot.PunkteVerschiebbar=false;
		var t="",i;
		for(i=0;i<N-1;i++)t+=aa[i]+" "+bb[i]+" "+cc[i]+" "+dd[i]+" ";
		document.kubsplineplot.setKubSpline(N-1,xx.join(" "),t);
		sqauto(false);
		var q=Math.abs((sqautoa[2]-sqautoa[3])/(sqautoa[1]-sqautoa[0]));
		if((q>0.1)&&(q<1.0))sqanpassen(false);
		document.kubsplineplot.kubsplineplot();
	}
	nxx=n+1;
	document.f.Ix0.value=document.f.Vx0.value=String(xx[0]).replace(/\./,",");
	document.f.Ix1.value=document.f.Vx1.value=String(xx[nxx-1]).replace(/\./,",");
	ns=Nullstellen();
	if(ns.length>1){document.f.Ix0.value=document.f.Vx0.value=String(rund(ns[0],1e8)).replace(/\./,",");document.f.Ix1.value=document.f.Vx1.value=String(rund(ns[1],1e8)).replace(/\./,",");}
	if((ns.length==1)&&(ns[0]!=xx[0])){document.f.Ix1.value=document.f.Vx1.value=String(rund(ns[0],1e8)).replace(/\./,",");document.f.Ix0.value=document.f.Vx0.value=String(xx[0]).replace(/\./,",");}
	Integrale();
	Extrema();Wendepunkte();
	document.f.Ky.value=" <—— klicken!";
	if((xx0alt!=xx[0])&&((Number(document.f.Kx0.value.replace(/,/,"."))==xx0alt))||(xx1alt!=xx[nxx-1]))document.f.Kx0.value=String(xx[0]).replace(/\./,",");
	if((xx1alt!=xx[nxx-1])&&((Number(document.f.Kx1.value.replace(/,/,"."))==xx1alt))||(xx0alt!=xx[0]))document.f.Kx1.value=String(xx[nxx-1]).replace(/\./,",");
	xx0alt=xx[0];xx1alt=xx[nxx-1];
	if((document.f.gen.selectedIndex<=4)&&(document.f.autoKurvenintegral.checked))
	{
		Kurvenintegral();
	}
}
var xx0alt=0,xx1alt=0,t0ki;
var sqautoa=new Array(0,0,0,0);
function sqauto(plotten)
{
	var x0=xx[0],x1=xx[N-1],i,maxy=-1e100,miny=1e100,d,x,y,dx;
	for(i=0;i<N-1;i++)
	{
		dx=xx[i+1]-xx[i];
		d=dx/5;
		for(x=0;x<=dx;x+=d)
		{
			y=dd[i]+x*(cc[i]+x*(bb[i]+x*aa[i]));
			maxy=Math.max(maxy,y);miny=Math.min(miny,y);
		}
	}
	//alert(x0+"   "+x1+"   "+miny+"   "+maxy);
	d=(x1-x0)/8;x0-=d;x1+=d;
	d=(maxy-miny)/8;if(d==0)d=(x1-x0)/2;maxy+=d;miny-=d;
	if((document.kubsplineplot!=null)&&navigator.javaEnabled())document.kubsplineplot.setRange(x0,x1,miny,maxy);
	if((plotten)&&(document.kubsplineplot!=null)&&navigator.javaEnabled())document.kubsplineplot.plot();
	sqautoa[0]=x0;sqautoa[1]=x1;sqautoa[2]=miny;sqautoa[3]=maxy;
}

function tab(x,m,l)
{
	var X=String(x);
	var ik=X.replace(/\./,",").indexOf(",");if(ik==-1)ik=X.length;
	return "                  ".substr(0,m-ik)+X+"                   ".substr(0,l-(X.length-ik));
}

function interpol()
{
	if(N==0)return;
	document.f.yy.value="";
	var x=Number(document.f.xx.value.replace(/,/,".")),X,Y,rat=(1==0);
	if(document.f.xx.value.replace(/\D/g,"")=="")return;
	if(isNaN(x))
	{
		X=toBruch(document.f.xx.value.replace(/,/,"."));
		x=X[0]/X[1];
		rat=true;
	}
	if((x<xx[0])||isNaN(x))return;
	var i;	
	for(i=N-1;i>=0;i--)if(x>xx[i])break;
	if(i==N-1)return;
	if(i==-1)i=0;
	x-=xx[i];
	var y=dd[i]+x*(cc[i]+x*(bb[i]+x*aa[i]));
	if(rat)
	{
		Y=kettenbruchapprox(y,10000000,1e-13);document.f.yy.value=String(bstr(Y[0],Y[1])).replace(/\./,",");
	}
	else document.f.yy.value=String(rund(y,1000000000000)).replace(/\./,",");
}
function rund(x,r){return Math.round(x*r)/r;}

function bstr(z,n)
{
	if(z==0)return 0;
	if(n==1)return z;
	return z+"/"+n;
}

function sqanpassen(plotten)
{
	if((document.kubsplineplot==null)||(!navigator.javaEnabled()))return;
	var r=String(document.kubsplineplot.getRange(";")).split(";");
	var x0=Number(r[0]),x1=Number(r[1]),y1=Number(r[2]),y0=Number(r[3]),xm=(x1+x0)/2,ym=(y0+y1)/2;
	var q=(y1-y0)/(x1-x0),d=3*(x1-x0)/8;
	if(q>0.75){d=2*(y1-y0)/3;x0=xm-d;x1=xm+d;}else{y0=ym-d;y1=ym+d;}
	document.kubsplineplot.setRange(x0,x1,y1,y0);
	if(plotten)document.kubsplineplot.kubsplineplot();
}
function fx(i,x_)
{
	var x=x_-xx[i];
	return ((aa[i]*x+bb[i])*x+cc[i])*x+dd[i];
}
function FInt(a,b,c,d,x0,x1)
{
	return FStf(a,b,c,d,x1)-FStf(a,b,c,d,x0);
}
function FStf(a,b,c,d,x)
{
	return (((a/4*x+b/3)*x+c/2)*x+d)*x;
}
function VInt(a,b,c,d,x0,x1)
{
	return VStf(a,b,c,d,x1)-VStf(a,b,c,d,x0);
}
function VStf(a,b,c,d,x)
{
	return Math.PI*(((((((a*a/7*x+b*a/3)*x+(2*c*a+b*b)/5)*x+(d*a+c*b)/2)*x+(2*d*b+c*c)/3)*x+d*c)*x+d*d)*x);
}
function Integrale()
{
	document.f.Iy.value=document.f.Vy.value="  [?]";
	if(nxx<2){alert("S(x) ist nicht definiert.\nKein Spline gespeichert");return;}
	var i,i0,f=0,v=0,x0,x1,xx0,xx1;
	x0=Number((xx0=document.f.Ix0.value).replace(/ /g,"").replace(/,/,"."));
	x1=Number((xx1=document.f.Ix1.value).replace(/ /g,"").replace(/,/,"."));
	if((x0>=xx[0])&&(x1<=xx[nxx-1])&&(xx0.replace(/ /g,"")!="")&&(xx1.replace(/ /g,"")!=""))
	{
		for(i0=nxx-2;i0>=0;i0--){if(xx[i0]<=x0)break;}
		if(x1<=xx[i0+1]){f=FInt(aa[i0],bb[i0],cc[i0],dd[i0],x0-xx[i0],x1-xx[i0]);}
		else
		{
			f=FInt(aa[i0],bb[i0],cc[i0],dd[i0],x0-xx[i0],xx[i0+1]-xx[i0]);
			for(i=i0+1;i<aa.length;i++)
			{
				if(xx[i+1]>=x1)break;
				f+=FInt(aa[i],bb[i],cc[i],dd[i],0,xx[i+1]-xx[i]);
				v+=VInt(aa[i],bb[i],cc[i],dd[i],0,xx[i+1]-xx[i]);
			}
			if(i<nxx){f+=FInt(aa[i],bb[i],cc[i],dd[i],0,x1-xx[i]);}
		}
		document.f.Iy.value=String(Math.round(f*1e12)/1e12).replace(/\./,",");
	}
	x0=Number((xx0=document.f.Vx0.value).replace(/ /g,"").replace(/,/,"."));
	x1=Number((xx1=document.f.Vx1.value).replace(/ /g,"").replace(/,/,"."));
	if((x0>=xx[0])&&(x1<=xx[nxx-1])&&(xx0.replace(/ /g,"")!="")&&(xx1.replace(/ /g,"")!=""))
	{
		for(i0=nxx-2;i0>=0;i0--){if(xx[i0]<=x0)break;}
		if(x1<=xx[i0+1]){v=VInt(aa[i0],bb[i0],cc[i0],dd[i0],x0-xx[i0],x1-xx[i0]);}
		else
		{
			v=VInt(aa[i0],bb[i0],cc[i0],dd[i0],x0-xx[i0],xx[i0+1]-xx[i0]);
			for(i=i0+1;i<aa.length;i++)
			{
				if(xx[i+1]>=x1)break;
				v+=VInt(aa[i],bb[i],cc[i],dd[i],0,xx[i+1]-xx[i]);
			}
			if(i<nxx){v+=VInt(aa[i],bb[i],cc[i],dd[i],0,x1-xx[i]);}
		}
		document.f.Vy.value=String(Math.round(v*1e12)/1e12).replace(/\./,",");
	}
}
function Nullstellen()
{
	var i=0,j,x,zp,xxx,yyy=yy[0],yyyy,y,x0=xx[0],x1=xx[nxx-1],dx=(x1-x0)/100,ns=new Array(),nsy=new Array();
	for(i=0;i<nxx;i++){if(yy[i]==0)ns[ns.length]=xx[i];}
	i=0;
	for(x=x0+dx;x<=x1;x+=dx)
	{
		if((x>=xx[i+1])&&(i<nxx-2)){i++;x=xx[i];}
		xxx=x-xx[i];
		yyyy=y=((xxx*aa[i]+bb[i])*xxx+cc[i])*xxx+dd[i];
		if((!(yyy*y>0))||(Math.abs(y)<1e-5))
		{
			for(j=0;j<30;j++)
			{
				if((Math.abs(y)<1e-15)||(Math.abs(y)>10)||(xxx<0)||(xxx>xx[i+1]-xx[i])||isNaN(xxx))break;
				xxx-=(y=((xxx*aa[i]+bb[i])*xxx+cc[i])*xxx+dd[i])/((3*xxx*aa[i]+2*bb[i])*xxx+cc[i]);
			}
			if((Math.abs(y)<1e-8)&&(xxx>=0)&&(xxx<=xx[i+1]-xx[i])&&(!isNaN(xxx)))
			{
				zp=1e12;
				while((Math.abs(((xxx*aa[i]+bb[i])*xxx+cc[i])*xxx+dd[i])>=Math.abs(((rund(xxx,zp/10)*aa[i]+bb[i])*rund(xxx,zp/10)+cc[i])*rund(xxx,zp/10)+dd[i]))&&(zp>1)){zp/=10;xxx=rund(xxx,zp);}
				for(j=0;j<ns.length;j++){if(Math.abs(ns[j]-(xxx+xx[i]))<1e-3)break;}
				if(j==ns.length){ns[ns.length]=rund(xxx,zp)+xx[i];nsy[nsy.length]=y;}
			}
		}
		yyy=yyyy;
	}
	if(ns.length>1)quicksort2(ns,nsy);
	document.f.ns.value="{ "+String(ns.join("; ")).replace(/\./g,",")+" }";
	return ns;
}
function Extrema()
{
	var i=0,j,x,zp,a,b,c,p,q,xxx,x1,x2,r,w,yyy=yy[0],yyyy,y,x0=xx[0],x1=xx[nxx-1],dx=(x1-x0)/20,min=new Array(),max=new Array(),nsy=new Array(),t="";
	for(i=0;i<nxx-1;i++)
	{
		if(aa[i]!=0)
		{
			a=3*aa[i];b=2*bb[i];c=cc[i];p=b/a;q=c/a;
			r=p*p/4-q;if(r<0)continue;
			if(r==0)testextremum(-p/2,xx[i],xx[i+1],min,max,2*a,b);
			else{testextremum(-p/2-(w=Math.sqrt(r)),xx[i],xx[i+1],min,max,2*a,b);testextremum(-p/2+w,xx[i],xx[i+1],min,max,2*a,b);}
		}
		else if(bb[i]!=0)testextremum(-cc[i]/2/bb[i],xx[i],xx[i+1],min,max,0,2*bb[i]);
	}
	if(min.length!=0)t+="lok. Minim"+((min.length==1)?"um":"a")+": { "+min.join("; ")+" }";
	if(max.length!=0)t+=((t!="")?" — ":"")+"lok. Maxim"+((max.length==1)?"um":"a")+": { "+max.join("; ")+" }";
	if(t=="")t="{  }";
	document.f.es.value=t.replace(/\./g,",").replace(/k,/g,"k.");
}
function Wendepunkte()
{
	var i,wp=new Array(),t,x;
	for(i=0;i<nxx-1;i++)
	{
		if(aa[i]==0)continue;
		x=-bb[i]/(aa[i]*3);	
		if((x>=0)&&(x<xx[i+1]-xx[i]))wp[wp.length]=x+xx[i];
	}
	x=-bb[i-1]/(aa[i-1]*3);
	if(x==xx[i]-xx[i-1])wp[wp.length]=xx[i];
	t="{ "+wp.join("; ")+" }";
	document.f.wp.value=t.replace(/\./g,",").replace(/k,/g,"k.");
}
function testextremum(x,x0,x1,min,max,m,b)
{	//alert(x+x0+"\n"+x0+"  "+x1+"\n"+m+"x+"+b+"  "+(m*x+b));
	if((x<0)||(x>x1-x0))return;
	if((m*x+b>0)&&((Math.abs(min[min.length-1]-(x+x0))>1e-8)||(min.length==0)))min[min.length]=x+x0;
	if((m*x+b<0)&&((Math.abs(max[max.length-1]-(x+x0))>1e-8)||(max.length==0)))max[max.length]=x+x0;
}
function Kurvenintegral(geklickt)
{
	t0ki=Date.parse(new Date());
	if(geklickt==1)t0ki+=120000;
	document.f.Ky.value="  [?]";var vzt=0==1;
	if(nxx<2){alert("S(x) ist nicht definiert.\nKein Spline gespeichert");return;}
	var x0=Number(document.f.Kx0.value.replace(/,/,"."));if(isNaN(x0))return;
	var x1=Number(document.f.Kx1.value.replace(/,/,"."));if(isNaN(x1))return;
	if(document.f.Kx0.value.replace(/ /g,"")=="")return;
	if(document.f.Kx1.value.replace(/ /g,"")=="")return;
	if(x1<x0){var x2=x1;x1=x0;x0=x2;vzt=true;}
	if(x0<xx[0])return;
	if(x1>xx[nxx-1])return;
	document.f.Ky.value="Berechnung läuft";
	var i,i0=0,i1=nxx-1,s=0,r=Math.pow(10,document.f.gen.selectedIndex+2);
	while(x0>xx[i0+1])i0++;
	while(x1<=xx[i1])i1--;
	if(x0==x1)s=0;
	else if(x1<xx[i0+1])
	{
		s=approxKurvenIntegral(x0-xx[i0],x1-xx[i0],i0,1/nxx/r);//alert(s+"   i0="+i0);
	}
	else
	{
		s=approxKurvenIntegral(x0-xx[i0],xx[i0+1]-xx[i0],i0,1/nxx/r);//alert(s+"   i0="+i0);
		for(i=i0+1;i<i1;i++)
		{
			s+=approxKurvenIntegral(0,xx[i+1]-xx[i],i,1/nxx/r);
			if(isNaN(s)){document.f.Ky.value="<—— klicken!";return;}
			/*alert(s+"   i="+i);*/
		}
		if(i0<i1){s+=approxKurvenIntegral(0,x1-xx[i1],i1,1/nxx/r);if(isNaN(s)){document.f.Ky.value="<—— klicken!";return;}/*alert(s+"   i1="+i1);*/}
	}
	if(vzt)s=-s;
	document.f.Ky.value=String(rund(s,r)).replace(/\./,",");
}
var lhr=true;//location.href.toLowerCase().indexOf("rndt-br")>-1;
function approxKurvenIntegral(x0,x1,I,r)
{
	var dx=(x1-x0);
	if(dx==0)return null;
	var rr=Math.round(1/r);
	var n=10;
	var x,d=dx/n,i,s,y1,y2,y3,ss=-99999999999.99999;
	do{
		if((Date.parse(new Date())-t0ki>1000)&&(document.f.autoKurvenintegral.checked))
		{
			document.f.autoKurvenintegral.checked=false;
			return "Abbruch";
		}
		d=dx/n;
		status="n = "+n;
		y1=fkt(x0-d,I);
		y2=fkt(x0,I);
		y3=fkt(x0+d,I);
		s=-d*(y1-11*y2-2*y3)/24;
		if(isNaN(s)){s=(y3+y2)*d/4;}
		for(i=2;i<=n;i++)
		{
			x=x0+i*d;y1=y2;y2=y3;y3=fkt(x,I);
			s+=d*(y1+22*y2+y3)/24;
		}
    		y1=y2;y2=y3;y3=fkt(x1+d,I);
		if(isNaN(y3))
			s+=(y2+y1)*d/4;
		else
			s+=d*(2*y1+11*y2-y3)/24;
		if((n>1e5)||(Math.abs(s-ss)<r))break;
		if(isNaN(s)){alert("Fehler.\nSind bereits Splines definiert?");break;}
		var g_=Math.floor(-Math.log(Math.abs(s-ss))/Math.log(10));var r_=Math.pow(10,-g_),rr_=Math.round(1/r_);
		//document.f.integral.value="["+String(Math.round(s*rr_)/rr_).replace(/\./,",")+"...]";
		ss=s;n*=10;
	}while(true);
	if(Math.abs(s-ss)>r)
	{
		g=Math.floor(-Math.log(Math.abs(s-ss))/Math.log(10));r=Math.pow(10,-g);rr=Math.round(1/r);
		document.f.gen.selectedIndex=(g>2)?g-2:0;alert("Die Genauigkeit mußte nach unten korrigiert werden: 10^-"+g);
	}
	status="";
	return s;
}
function fkt(x,i)
{
	var abl=(3*aa[i]*x+2*bb[i])*x+cc[i];
	return Math.sqrt(1+abl*abl);
}
