Kyaria icon

Code für die Welt!

Kyaria | PRO | 04/20/18 07:13:27 PM UTC | 0 ⭐ | 381 👁️ | Never ⏰ | []
C# |

22.3 KB

|

None

|

0 👍

/

0 👎

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