Exemplo n.º 1
0
void gui::plot(double x1, double x2, double y1, double y2, double gen, parser term, bool diff, bool tay){	
	//Optimale Größe des angezeigten Bildes wird berechnet.
	double hg = ausgabe->height()-40;
	double y_width = (fabs(y2-y1));	
	double x_width = (fabs(x2-x1));
	double wd = hg*(x_width/y_width);
	cout << wd << endl;
	if (wd > ausgabe->width()-40){
		double faktor = (ausgabe->width()-20)/wd;
		wd *= faktor;
		hg *= faktor;
	}	
	hg = int(hg);
	wd = int(wd);
	//Sklarierung der Koordinatenachsen.
	double x_scale = wd/x_width;
	double y_scale = hg/y_width;	
	
	//Stifte für die verschiedenen Zeichenstile festlegen.
	QPen koord(Qt::black, 1);
	QPen f(Qt::black, 2);
	QPen f_(QColor(150,0,0), 1,Qt::DashLine);
	QPen f__(QColor(0,0,150), 1,Qt::DashLine);
	QPen tayl_pen(QColor(180,180,180), 1);
	
	//Bild zum Reinzeichnen wird angelegt
	QImage img(wd,hg, QImage::Format_ARGB32);
	QPainter painter(&img);	
	painter.begin(&img);
	painter.fillRect(0,0,wd,hg,Qt::white);
	painter.setRenderHint(QPainter::Antialiasing, true);	
	
	//Legende für die Funktion
	painter.drawText(40,10,"f(x)");
	painter.setPen(f);
	painter.drawLine(10,5,30,5);
	
	//Translation des Koordinatensystemns, dass der Ursprung richtig zu den Intervallen passt.
	painter.translate(-x1*x_scale,y2*y_scale);
	
	//Laufvariable in der Schleife	
	int i = 0;
	
	//x-Koordinate an der geplottet wird, Funktionswert und Ableitungen.
	double x,u,v,w;
	autodiff abl(0,0,0);
	
	//x-Koordinate an der geplottet wird, Funktionswert und Ableitungen aus letztem Plottschritt.
	double x_alt,u_alt,v_alt,w_alt;
	
	//Je nach Angaben in der GUI wird eine Instanz von Taylor erstellt.
	double t0 = taylor_1_2->value();
	int k = taylor_1_1->value();
	taylor tpol = term.tayl(k,t0,term.get_baum());
	
	//Array für die Funktionswerte des Taylorpolynoms für ein bestimmtes k.
	double *tayl_y, *tayl_y_alt;
	tayl_y = new double[k+1];
	tayl_y_alt = new double[k+1];	
	
	//Schleife durchläuft alle x-Werte in Abhängigkeit von [x1,x2] und der Genauigkeit.
	while (x1 + i*gen <= x2){		
		//x-Wert
		x = x1 + i*gen;
		
		//Funktionswert usw bei x
		abl = term.derive(x,term.get_baum());
		u = abl.get_u();
		
		//Ableitungen in Variablen schreiben, falls benötigt
		if (diff == true){
			v = abl.get_v();
			w = abl.get_w();
		}
		
		//Taylor-Polynome zeichnen
		if (tay == true){
			for (int i = 0;i <= k;i++){
				tayl_y[i] = tpol.xval(x, t0, i);		
			}
		}
		
		//Nach einem Durchlauf werden die ersten Linien gezeichnet
		if (i>0){			
			if (diff == true){
				painter.setPen(f_);
				painter.drawLine(x_alt*x_scale,-v_alt*y_scale,x*x_scale,-v*y_scale);
				painter.setPen(f__);
				painter.drawLine(x_alt*x_scale,-w_alt*y_scale,x*x_scale,-w*y_scale);
			}
			painter.setPen(tayl_pen);
			if (tay == true){
				for (int i = 0;i < k;i++){
					painter.drawLine(x_alt*x_scale,-tayl_y_alt[i]*y_scale,x*x_scale,-tayl_y[i]*y_scale);							
				}				
			}
			
			painter.setPen(f);
			painter.drawLine(x_alt*x_scale,-u_alt*y_scale,x*x_scale,-u*y_scale);
		}
		
		i++;
		
		//Merken der Werte für nächsten Durchlauf
		if (tay == true){
			for (int i = 0;i < k;i++){
				tayl_y_alt[i] = tayl_y[i];		
			}
		}
		x_alt = x;
		u_alt = u;
		v_alt = v;
		w_alt = w;
	}
	
	//Rücktransformation des Koordinatensystems
	painter.setPen(koord);	
	
	//Koordinatensystem wird über die Graphen gezeichnet, um sichtbar zu bleiben.
	painter.drawLine(x1*x_scale,0,x2*x_scale,0);
	painter.drawLine(0,-y1*y_scale,0,-y2*y_scale);
	painter.drawLine(x2*x_scale-8,5,x2*x_scale,0);
	painter.drawLine(x2*x_scale-8,-5,x2*x_scale,0);
	painter.drawText(x2*x_scale-8,-10,"x");	
	painter.drawLine(-5,-y2*y_scale+8,0,-y2*y_scale);	
	painter.drawLine(5,-y2*y_scale+8,0,-y2*y_scale);
	painter.drawText(10,-y2*y_scale+8,"y");
	
	//Einheiten auf den Achsen
	for(int i = x1+1; i <= x2-1; i++){
		if (x_scale > 20){		
			if (i != 0){
				painter.drawLine(x_scale*i,-5,x_scale*i,5);
				painter.drawText(x_scale*i-7,+17,QString("%1").arg(i));
			}
		}
		else{
			if ((i % int(x_scale/5))==0){
				painter.drawLine(x_scale*i,-5,x_scale*i,5);
				painter.drawText(x_scale*i-7,+17,QString("%1").arg(i));
			}
		
		}
	}
	for(int i = y1+1; i <= y2-1; i++){
		if (y_scale > 20){		
			if (i != 0){
				painter.drawLine(-5,-i*y_scale,+5,-i*y_scale);
				painter.drawText(-17,-y_scale*i+5,QString("%1").arg(i));
			}
		}
		else{
			if ((i % int(y_scale/5))==0){
				painter.drawLine(-5,-i*y_scale,+5,-i*y_scale);
				painter.drawText(-17,-y_scale*i+5,QString("%1").arg(i));
			}
		
		}		
	}
	
	//Legende für die Ableitungen wird zuletzt gezeichnet, um sichtbar zu bleiben.	
	if (diff==true){
		painter.translate(x1*x_scale,-y2*y_scale);	
		painter.drawText(40,25,"f'(x)");
		painter.drawText(40,40,"f''(x)");	
		painter.setPen(f_);
		painter.drawLine(10,20,30,20);
		painter.setPen(f__);
		painter.drawLine(10,35,30,35);
	}
	
	painter.end();
	ausgabe->setTextColor(QColor(0,0,0,150));
	ausgabe->append("> Plot: ");
	ausgabe->append(" ");
	ausgabe->append(" ");
	int suffix = rand();
	img.save(QString("plots/plot_%1.png").arg(suffix),"PNG");
	ausgabe->insertHtml(QString("<img src=plots/plot_%1.png>").arg(suffix));
}