using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace Funktionsplotter
{
public partial class Form1 : Form
{
private Bitmap bmp;
private Pen blackPen, redPen, greenPen, violetPen;
private PointF[] point_a = new PointF[2000];
private PointF[] point_b = new PointF[2000];
private PointF[] point_c = new PointF[2000];
private PointF[] point_d = new PointF[2000]; // Punktearrays für die Funktion und die Ableitungen
private int counter_ableitungen = 0, count_saver = 0; // Counter um Ausgabe-Ableitung zu steuern
private string func_a, func_b, func_c, func_d; // Die Funktionen werden hier gespeichert
public Form1()
{
InitializeComponent();
textBox3.Enabled = false;
textBox6.Enabled = false;
textBox7.Enabled = false;
init_pic(); // Achsenkreuz wird erstellt
}
private void button2_Click(object sender, EventArgs e) // Grafik wird auf dem Desktop gesichert
{
string path = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
count_saver++;
pictureBox1.Image.Save(path + "/bitmap_grafik_" + count_saver + ".bmp", System.Drawing.Imaging.ImageFormat.Bmp);
}
private void button1_Click(object sender, EventArgs e)
{ // Formt Eingabe zur Normalform um
textBox3.Clear();
textBox6.Clear();
textBox7.Clear();
listBox2.Items.Clear();
init_pic();
counter_ableitungen = 0; // Counter um die Ausgabe nach Ableitungen zu leiten
if (richTextBox1.Text != "" && textBox1.Text != "" && textBox2.Text != "" && Convert.ToDouble(textBox1.Text) > Convert.ToDouble(textBox2.Text))
{ // Überprüft Eingabe auf Richtigkeit
string str = richTextBox1.Text;
if (str[0] != '+' && str[0] != '-') str = '+' + str; // Wenn kein Rechenzeichen am Beginn des Strings steht, wird eins hinzugefügt
for (int i = 0; i < str.Length; i++) // Überprüft ob ein einzelnes X in der Funktion ist und setzt ein ^1 ein
{
if (str[i] == 'x' && str[i + 1] != '²' && str[i + 1] != '³')
{
str = str.Insert(i + 1, "¹");
}
}
if (!str.Contains('³')) // Wenn kein x³ vorhanden wird eines eingefügt
{
str = str.Insert(0, "0x³");
}
if (str.Contains('³') && !str.Contains('²')) // Wenn kein x² vorhanden, so wird eines an der passenden Stelle eingefügt
{
for (int i = 0; i < str.Length; i++)
{
if (str[i] == 'x' && str[i + 1] == '³')
str = str.Insert(i + 2, "+0x²");
}
}
if (str.Contains('²') && !str.Contains('¹')) // Wenn kein x^1 vorhanden ist wird eines eingefügt
{
for (int i = 0; i < str.Length; i++)
{
if (str[i] == 'x' && str[i + 1] == '²')
str = str.Insert(i + 2, "+0x¹");
}
}
for (int i = 0; i < str.Length; i++) // Setzt ein 'd' ein wenn nicht vorhanden
{
if (str[i] == '¹')
{
if ((i + 1) >= str.Length)
{
str = str.Insert(i + 1, "+0");
}
}
}
string new_string_two = str;
int new_count_two = 0;
for (int i = 0; i < str.Length; i++) // Wenn x alleine steht wird eine 1 hinzugefügt
{
if (str[i] == 'x')
{
if (!Char.IsDigit((str[i - 1])))
{
new_string_two = new_string_two.Insert(i - new_count_two, "1");
new_count_two++;
}
}
}
str = new_string_two;
string new_string = str;
int new_count = 0;
for (int i = 0; i < str.Length; i++) // Setzt vor ein x ein *
{
if (str[i] == 'x')
{
new_string = new_string.Insert(i + new_count, "*");
new_count++;
}
}
str = new_string;
func_a = str; // Original Funktion wird in func_a gesichert
calc_ableitung(str); // Zur Ableitungsfunktion
draw_stuff(); // Nach den Ableitungen wird der Zeichnenmethode übergeben
}
else
{
MessageBox.Show("Bitte geben Sie eine gültige Funktion 3. Grades und gültige Grenzen ein!");
}
}
private void draw_stuff() // Zeichnet meine Funktionen
{
bool calc_b_check = false, calc_c_check = false, calc_d_check = false;
for (int i = 0; i < func_b.Length; i++)
{ // Überprüft ob Funktion Zeichenbar ist. (a, b, c oder d nicht null)
if (Char.IsDigit(func_b[i]))
{
if (func_b[i] != '0') calc_b_check = true;
}
}
for (int i = 0; i < func_c.Length; i++)
{ // Überprüft ob Funktion Zeichenbar ist. (a, b, c oder d nicht null)
if (Char.IsDigit(func_c[i]))
{
if (func_c[i] != '0') calc_c_check = true;
}
}
for (int i = 0; i < func_d.Length; i++)
{ // Überprüft ob Funktion Zeichenbar ist. (a, b, c oder d nicht null)
if (Char.IsDigit(func_d[i]))
{
if (func_d[i] != '0') calc_d_check = true;
}
}
for (int i = -1000; i < 1000; i++)// Rechnet das Punktearray der Originalfunktion
{
string question = func_a.Replace("x", "(" + i.ToString() + ")");
float py = Convert.ToSingle(rechne_funktion(question)), px = i;
if (i < 0) py = py * -1; // Der Workaround von dem unten geredet wird. (Bei der Rechnenfunktion)
if (i >= Convert.ToInt32(textBox2.Text) && i <= Convert.ToInt32(textBox1.Text))
{
listBox2.Items.Add("y= " + py + ", x= " + px);
}
point_a[i + 1000] = new PointF(px, py);
}
if (calc_b_check) // Überprüft ob Rechnen sinnvoll ist
{
listBox2.Items.Add("Ableitung 1: \n");
for (int i = -1000; i < 1000; i++)// Rechnet das Punktearray der ersten Ableitung
{
string question = func_b.Replace("x", "(" + i.ToString() + ")");
float py = Convert.ToSingle(rechne_funktion(question)), px = i;
if (i < 0) py = py * -1; // Der Workaround von dem unten geredet wird. (Bei der Rechnenfunktion)
if (i >= Convert.ToInt32(textBox2.Text) && i <= Convert.ToInt32(textBox1.Text))
{
listBox2.Items.Add("y= " + py + ", x= " + px);
}
point_b[i + 1000] = new PointF(px, py);
}
}
if (calc_c_check) // Überprüft ob Rechnen sinnvoll ist
{
listBox2.Items.Add("Ableitung 2: \n");
for (int i = -1000; i < 1000; i++)// Rechnet das Punktearray der zeiten Ableitung
{
string question = func_c.Replace("x", "(" + i.ToString() + ")");
float py = Convert.ToSingle(rechne_funktion(question)), px = i;
if (i < 0) py = py * -1; // Der Workaround von dem unten geredet wird. (Bei der Rechnenfunktion)
if (i >= Convert.ToInt32(textBox2.Text) && i <= Convert.ToInt32(textBox1.Text))
{
listBox2.Items.Add("y= " + py + ", x= " + px);
}
point_c[i + 1000] = new PointF(px, py);
}
}
if (calc_d_check) // Überprüft ob das Zeichnen sinnvoll ist
{
listBox2.Items.Add("Ableitung 3: \n");
for (int i = -1000; i < 1000; i++)// Rechnet das Punktearray der dritten Ableitung
{
string question = func_d.Replace("x", "(" + i.ToString() + ")");
float py = Convert.ToSingle(rechne_funktion(question)), px = i;
if (i < 0) py = py * -1; // Der Workaround von dem unten geredet wird. (Bei der Rechnenfunktion)
if (i >= Convert.ToInt32(textBox2.Text) && i <= Convert.ToInt32(textBox1.Text))
{
listBox2.Items.Add("y= " + py + ", x= " + px);
}
point_d[i + 1000] = new PointF(px, py);
}
}
draw_my_field(); // Übergibt an die Zeichnenfunktion
}
private void calc_ableitung(string str)
{ // Berechnet Ableitungen
char calc_sym_1 = str[0], calc_sym_2 = '+', calc_sym_3 = '+';
for (int i = 0; i < str.Length; i++) // Nimmt Rechenzeichen nach der Hochzahl
{
try // Fliegt aus dem Indexbereich wenn ³ z.B. nicht vorhanden ist. Führt zu keinen Problemen im übrigen Code.
{
if (str[i] == '³')
calc_sym_2 = str[i + 1];
if (str[i] == '²')
calc_sym_3 = str[i + 1];
}catch { }
}
string[] str_content = str.Split('+', '-');
int multiplikator = 0;
string erg = "";
for (int i = 0; i < str_content.Length - 1; i++) // Geht der Länge des arrays nach durch die Splits um abzuleiten
{
for (int j = 0; j < str_content[i].Length ; j++) // Checkt jeden Part der Funktion nach Hochzeichen um ableiten zu können
{
string new_str_content = str_content[i];
if (new_str_content[j] == '³')
{ // Wenn im Part dieses Hochzeichen gefunden wurde so wird abgeleitet
multiplikator = 3;
string[] new_str_array = new_str_content.Split('*');
string ins = calc_sym_1 + new_str_array[0]; // Nimmt Rechenzeichen vor dem ^3 und verbindet es mit der Zahl vor dem *
double varia = Convert.ToDouble(ins) * multiplikator; // Rechnet die neue Basis aus
erg = erg + calc_sym_1 + varia.ToString() + "*x²"; // Fügt den neuen Exponenten an
}
if (new_str_content[j] == '²')
{
multiplikator = 2;
string[] new_str_array = new_str_content.Split('*');
string ins = calc_sym_2 + new_str_array[0];
double varia = Convert.ToDouble(ins) * multiplikator;
erg = erg + calc_sym_2 + varia.ToString() + "*x¹";
}
if (new_str_content[j] == '¹')
{
multiplikator = 1;
string[] new_str_array = new_str_content.Split('*');
string ins = calc_sym_3 + new_str_array[0];
double varia = Convert.ToDouble(ins) * multiplikator;
erg = erg + calc_sym_3 + varia.ToString();
}
}
}
if (erg.Contains('x')) calc_ableitung(erg); // Wenn noch Xe vorhanden sind, so wird die Ableitungsfunktion noch einmal aufgerufen
counter_ableitungen++;
if (erg != "" && counter_ableitungen == 1)
{ // Fügt 3te Ableitung ein
textBox7.Text = erg;
func_d = erg;
}
if (erg != "" && counter_ableitungen == 2)
{ // Fügt 2te Ableitung ein
textBox6.Text = erg;
func_c = erg;
}
if (erg != "" && counter_ableitungen == 3)
{ // Fügt 1te Ableitung ein
textBox3.Text = erg;
func_b = erg;
}
}
private void draw_my_field() // Zeichnet meine Punktearrays
{
blackPen = new Pen(System.Drawing.Color.Black);
redPen = new Pen(System.Drawing.Color.Red);
greenPen = new Pen(System.Drawing.Color.Green);
violetPen = new Pen(System.Drawing.Color.Violet);
using (Graphics g = Graphics.FromImage(bmp))
{
g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias; // Kantenglättung
g.TranslateTransform(pictureBox1.Width / 2, pictureBox1.Height / 2); // Koordinatensystem Ursprung wird verlegt
g.ScaleTransform(1, -0.25F); // Skalierung
g.DrawLines(blackPen, point_a); // Originalfunktion
g.DrawLines(redPen, point_b); // Erste Ableitung
g.DrawLines(greenPen, point_c); // Zweite Ableitung
g.DrawLines(violetPen, point_d); // Dritte Ableitung
}
pictureBox1.Image = bmp; // Bild wird eingefügt
}
private void init_pic() // Achsenkreuz wird erstellt
{
blackPen = new Pen(Color.Black, 3);
// Create points that define line.
Point point1y = new Point(pictureBox1.Width / 2, 0);
Point point2y = new Point(pictureBox1.Width / 2, pictureBox1.Height);
Point point1x = new Point(0, pictureBox1.Height / 2);
Point point2x = new Point(pictureBox1.Width, pictureBox1.Height / 2);
// Draw lines to screen.
bmp = new Bitmap(pictureBox1.Width, pictureBox1.Height);
using (Graphics g = Graphics.FromImage(bmp))
{
g.Clear(Color.White);
g.DrawImage(bmp, 0, 0); // Zeichnet bmp weiß
for (int x = -250; x <= 500; x += 25)
{ // Raster X Achse
g.DrawLine(new Pen(Color.Green), x, -pictureBox1.Height, x, pictureBox1.Height);
}
for (int y = -250; y <= 500; y += 25)
{ // Raster Y Achse
g.DrawLine(new Pen(Color.Red), -pictureBox1.Width, y, pictureBox1.Width, y);
}
g.DrawLine(blackPen, point1y, point2y);
g.DrawLine(blackPen, point1x, point2x); // Achsenkreuz
}
pictureBox1.Image = bmp;
}
private double rechne_funktion(string str)
{ // BSP: 2*(3)²+1*(-2)¹-3
string[] calc_array = str.Split('³', '²', '¹');
bool calc_1_check = false, calc_2_check = false, calc_3_check = false;
for (int i = 0; i < str.Length; i++)
{ // Checkt Funktion auf vorhandene Grade
if (str[i] == '¹')
calc_1_check = true;
if (str[i] == '²')
calc_2_check = true;
if (str[i] == '³')
calc_3_check = true;
}
int pow = 0; // Zahl zum hochnehmen
int begin_index = 0, end_index = 0;
for (int i = 0; i < calc_array.Length; i++) // Geht Array durch
{// BSP: 2*(3)²+1*(-2)¹-3
for (int j = 0; j < calc_array[i].Length; j++) // Geht Teil i des Arrays durch
{
string new_array = calc_array[i];
if (new_array[j] == '(')
{
begin_index = j;
}
if (new_array[j] == ')')
{ // Checkt nach Klammern
end_index = j;
if (calc_1_check)
{
pow = 1;
calc_1_check = false;
}
if (calc_2_check)
{
pow = 2;
calc_2_check = false;
}
if (calc_3_check)
{
pow = 3;
calc_3_check = false;
}
// Nimmt die höchste Hochzahl und setzt den Checkwert auf false um doppelte Hochrechnung zu verhindern
double pow_power = Math.Pow(Convert.ToDouble(new_array.Substring(begin_index + 1, end_index - begin_index - 1)), pow); // Nimmt die Zahl in den Indexen und nimmt sie mit der gegebenen Hochzahl hoch
new_array = new_array.Remove(begin_index, end_index - begin_index + 1).Insert(begin_index, pow_power.ToString()); // Entfernt die Klammern und die Hochzahl, während das Ergebnis eingefügt wird
calc_array[i] = new_array; // Wird im Array gesichert
}
}
}
string ergebnis_final = "";
for (int i = 0; i < calc_array.Length; i++)
{ // Das Ergebnis wird in einem String zusammengefügt
ergebnis_final = ergebnis_final + calc_array[i];
}
// I'm could not bring this **** to work properly! I will just use a workaround.
// BSP: 2 * -100 + 1 * -100 - 3
/*string[] mult_calc_array = i_will_hail_to_my_coffee_if_this_will_work.Split('*');
string a = "", b = "";
string mul_a = "", mul_b = "", mul_c = "";
for (int i = 0; i < mult_calc_array.Length - 1; i++)
{
int counter = 0, indexer = 0, counter_b = 0;
for (int j = mult_calc_array[i].Length - 1; j >= 0; j--)
{
//MessageBox.Show("fy");
string lost_count_of_arrays_or_strings = mult_calc_array[i];
if (Char.IsDigit(lost_count_of_arrays_or_strings[j]))
{
counter++;
indexer = j;
}
try
{
if (lost_count_of_arrays_or_strings[indexer - 1] == '-' || lost_count_of_arrays_or_strings[indexer - 1] == '+')
{
counter++;
break;
}
}
catch { }
}
int trying = (mult_calc_array[i].Length) - (counter );
a = mult_calc_array[i].Substring(trying, counter);
for (int j = 0; j < mult_calc_array[i + 1].Length; j++)
{
string lost_count_of_arrays_or_strings = mult_calc_array[i + 1];
if (lost_count_of_arrays_or_strings[j] == '-' && j == 0) counter_b++;
if (Char.IsDigit(lost_count_of_arrays_or_strings[j]))
{
counter_b++;
}
}
b = mult_calc_array[i + 1].Substring(0, counter_b - 1);
double c = Convert.ToDouble(a) * Convert.ToDouble(b);
if (i == 0) mul_a = c.ToString();
if (i == 1) mul_b = c.ToString();
if (i == 2) mul_c = c.ToString();
}
MessageBox.Show(mul_a + ", " + mul_b + ", " + mul_c);
int count_for = 0, count_back = 0;
for (int i = 0; i < i_will_hail_to_my_coffee_if_this_will_work.Length; i++)
{
if (i_will_hail_to_my_coffee_if_this_will_work[i] == '*')
{
for (int j = 0; j < i_will_hail_to_my_coffee_if_this_will_work.Length; j++)
{
if (Char.IsDigit(i_will_hail_to_my_coffee_if_this_will_work[i - j]) )
{
count_back++;
}
if (Char.IsDigit(i_will_hail_to_my_coffee_if_this_will_work[i + j]))
{
count_for++;
}
}
}
}
int index = i_will_hail_to_my_coffee_if_this_will_work.IndexOf('*');
int index_2 = i_will_hail_to_my_coffee_if_this_will_work.IndexOf('*', index);
int index_3 = i_will_hail_to_my_coffee_if_this_will_work.IndexOf('*', index_2);
int begin_a = 0, end_a = 0, begin_b = 0, end_b = 0, begin_c = 0, end_c = 0;
if(index != -1)
{
for (int i = 0; i < i_will_hail_to_my_coffee_if_this_will_work.Length; i++)
{
if (Char.IsDigit(i_will_hail_to_my_coffee_if_this_will_work[index - i])) begin_a++;
if (Char.IsDigit(i_will_hail_to_my_coffee_if_this_will_work[index + i]) && i_will_hail_to_my_coffee_if_this_will_work[index + i] == '-') end_a++;
}
}*/
var result = new DataTable().Compute(ergebnis_final, null); // Rechnet den Ergebnisstring durch
// Funktioniert nicht 100%ig.
return Convert.ToDouble(result); // Übergibt des Ergebnis
}
}
}
Comments