Dreiecks-Berechnung



  • Hallo,

    ich hoffe ich bin im richtigen Unterforum mit meiner Frage. Und zwar soll ich ein Programm zu Dreiecksberechnung schreiben, bei dem mir 2 Seiten und Winkel Alpha gegeben sind, ich soll die 3. Seite und Winkel Beta berechnen. Doch bei manchen eingaben will mein Programm einfach keine gescheiten Ergebnisse liefern, ich weis nicht ob es an der Programmierung oder an meinen Formeln liegt (die ich aber schon mehrfach verglichen hab).

    #include <iostream>
    #include <cmath>
    
    using namespace std;
    const double PI = acos(-1),
                S3=200;
    
    int main()
    {
        double S1 = 0.0;
        double S1b = 0.0;
        double S2;
        double S_min;
        double alpha;
        double beta = 0.0;
        double beta2 = 0.0;
        double gamma;
        double a_neu;
        double b_neu;
        double b_neu2;
        double g_neu;
    
        int    t;
        int x = 1;
        int y = 0 ;
    
        while (x)
        {
            if ((t=1))                                  // Eingabe
                x=1;
            else {x=0;}
    
            cout << "Bitte geben Sie Winkel Alpha(gon) und Strecke S2(m) ein." << endl;
            cin >> alpha;
            cin >> S2;
            cout << "Winkel: " << alpha; cout << " Gon" << endl;
            cout << "Strecke: " << S2; cout << " Meter" << endl;
    
            a_neu = alpha * PI / 200;
            S_min= S3*sin(a_neu)/sin(PI/2);
    
            if (S2<S_min || (alpha >= 100 && S2<=200) || (alpha>=200 || alpha<=0))
            {
                cout << "Eingaben nicht korrekt, es kann kein Dreieck gebildert werden." << endl;
                return 0;
    
            }
    
            else
            {
    
                                                                        // Berechnung
    
                    if (alpha == 100 )
                    {
                        S1 = sqrt(pow(S2, 2) - S3*S3);
                        b_neu= acos(S3 / S2);
                        beta= b_neu * 200 / PI;
                        y = 1;
                    }
                    else
    
                        if (alpha > 100)
                        {
                            g_neu = asin( S3 * sin (a_neu) / S2);
                            gamma = g_neu * 200 / PI;
                            beta = 200 - alpha - gamma;
                            b_neu = beta * PI / 200;
                            S1= S2 * sin (b_neu) / sin (a_neu);
                            y=1;
                        }
    
                        else
                        {
                            if (S2 == S_min)
                            {
                                S1 = sqrt ( S3 * S3 - pow (S_min, 2));
                                beta = 100 - alpha;
                                y = 1;
                            }
    
                            if (S2 > 200)
                            {
                                S1 = sqrt ( S3 * S3 - pow(S_min, 2)) + sqrt (pow(S2, 2) - pow(S_min, 2));
                                b_neu = asin (S1 * sin(a_neu) / S2);
                                beta = b_neu * 200/PI;
                                y = 1;
                            }
    
                            else
                            {
    
                                S1 = sqrt (S3 * S3 - pow(S_min, 2)) + sqrt ( pow(S2, 2) - pow(S_min, 2));
                                S1b = sqrt ( S3 * S3 - pow(S_min, 2)) - sqrt (pow(S2, 2) - pow(S_min, 2));
                                b_neu = sin (S1 * sin(a_neu) / S2);
                                beta  = b_neu * 200/PI;
                                b_neu2 = asin ( S1b * sin(a_neu) / S2);
                                beta2 = b_neu2 * 200/PI;
                                y=0;
                            }
                        }
    
            }
    
                                                             // Ausgabe
            if (y==1)
            {
                cout << "Der Winkel Beta beträgt " << beta << " Gon" << endl;
                cout << "Die Strecke S1 beträgt  " << S1 << " Meter" << endl;
            }
    
            if (y==0)
            {
                cout << "Zwei Lösungen:" << endl;
                cout << "Der Winkel Beta beträgt " << beta2 << " Gon" << endl;
                cout << "Die Strecke S1 beträgt " << S1b << " Meter" << endl;
                cout << "oder  " << S1 << " Meter" << endl;
            }
    
            cout << "Wenn Sie weitere Dreiecke berechnen wollen, geben sie eine 1 ein. Ansonsten beliebige Tasten zum Beenden drücken. " << endl;
            cin >> t;
            { if (t != 1) return 0;}                // Schleife zum Wiederholen des Programms
    
        }
    
    }
    


  • Zorenda schrieb:

    Doch bei manchen eingaben will mein Programm einfach keine gescheiten Ergebnisse liefern,

    Wenn du eine KI mit eigenem Willen implementiert hast, kann man nichts machen.

    Ansonsten: was soll das konkret bedeuten?



  • Und was soll die Formel

    alpha * PI / 200
    

    bedeuten?

    Edit: OK, der Winkel ist in Gon angegeben (nicht im Gradmaß).

    Wenn dir 2 Seiten vorgegeben sein sollen, warum wird dann nur 1 Seite (S2) abgefragt, oder soll es ein gleichschenkliges Dreieck mit 2 gleichlangen Seiten sein?



  • der code sieht so aus, als wäre er für das problem viel zu kompliziert.
    zwei seiten und ein winkel (soll das alles der user eingeben?) - zwei, drei zeilen sollten doch reichen?

    allgemein: der code ist unverständlich, und vermutlich falsch. aber um das genau zu sagen, muss man sehr konzentriert lesen, weil
    * variablen keine aussagekräftigen namen haben
    * globale variablen das ganze verkomplizieren
    * variablen nicht erst dann definiert werden, wenn sie gebraucht werden
    * variablen nicht sofort initialisiert werden
    * das:

    int t;
    int x = 1;
    //...
    while (x) {
      if ((t=1))                                
        x=1;
      else {x=0;}
    

    https://en.wikipedia.org/wiki/Not_even_wrong



  • Zorenda schrieb:

    int main()
    {
        double S1 = 0.0;
        double S1b = 0.0;
        double S2;
        double S_min;
        double alpha;
        double beta = 0.0;
        double beta2 = 0.0;
        double gamma;
        double a_neu;
        double b_neu;
        double b_neu2;
        double g_neu;
        
        int    t;
        int x = 1;
        int y = 0 ;
    

    Hui, das sind aber viele Variablen! Viel zu viele! Es ist sinnvoll, Variablen nur in dem Bereich zu deklarieren, wo man sie auch wirklich nutzt. Und sowas wie "b_neu" und "b_neu2" sind keine guten Namen.

    while (x)
        {
            if ((t=1))                                  // Eingabe
                x=1;
            else {x=0;}
    

    Erstens: x ist nicht nur ein schlechter Name, sondern auch immer 1. Wozu also mit einer Variablen arbeiten?

    Zweitens: Was soll das if? Es ist äquivalent zu t=1;x=1; . Vermutlich hatte dich der Compiler sogar deswegen gewarnt, denn sonst wären da ja nicht die doppelten Klammern um das ((t=1)) ... Man muss Warnungen auch verstehen!

    cout << "Bitte geben Sie Winkel Alpha(gon) und Strecke S2(m) ein." << endl;
    

    Es benutzt tatsächlich jemand Gon? Krass! Ist mir bislang noch nicht untergekommen!

    cout << "Winkel: " << alpha; cout << " Gon" << endl;
    

    Du brauchst kein doppeltes cout! Einfach:

    cout << "Winkel: " << alpha  << " Gon\n";
    
    a_neu = alpha * PI / 200;
            S_min= S3*sin(a_neu)/sin(PI/2);
    

    Ah, a_neu sollte besser a_gon heißen (Neugrad, falls das das "neu" bedeuten soll, soll nicht mehr verwendet werden). Deklariere es erst hier, nicht schon am Programmanfang. Und sin(π/2)=1\sin(\pi/2)=1. Durch 1 zu teilen ist sinnlos.

    if (S2<S_min || (alpha >= 100 && S2<=200) || (alpha>=200 || alpha<=0))
    

    So, jetzt mal ne generelle Frage: welche Strecke liegt gegenüber von welchem Winkel? Ich kenne die Konvention, dass aa gegenüber von α\alpha, bb ggü. von β\beta und cc ggü. von γ\gamma liegt. Warum wird S2 mit 200 verglichen, was ist das Problem bei großen Dreiecken? Wofür Fallunterscheidungen, ob α\alpha größer als ein rechter Winkel ist?

    Zurück zur Anfangsfrage: dir sind 2 Seiten und der Winkel α\alpha gegeben. Du liest α\alpha und S2 ein. Wo liest du die 2. Seite ein? Sind immer dieselben Seiten gegeben? Usw.



  • Danke für die vielen Antworten!

    @manni66 : Ich hab kein KI implementiert, die Strecke S2 und Winkel Alpha werden eingelesen. Bei manchen Eingaben kommen aber falsche Werte für das Dreieck raus.

    @Th69: Genau, ich rechne mit Gon (wegen Vermessung,usw.). Die Seite S3 ist gegeben und als Konstante definiert. Die zweite Seite wird dann vom Benutzer eingegeben.

    @dove: Ich sollte vllt. anmerken, dass das mein 2. Programm ist dass ich in meiner aller ersten Programmiersprache verfasst habe, lerne erst seit 2 Wochen. Klar, mit den Variablen hast du vollkommen Recht, bis jetzt wurde mir nur so beigebracht zu definieren. Aber ich glaube dass das Problem nicht wirklich einfacher zu berechnen ist, aber wenn du eine Idee hast wie man das Dreieck in zwei, drei Zeilen korrekt berechnen kann, dann her damit 😃 mein Prof würde sicher staunen 😉 !

    @wob: Ja, die Variablen sollte ich anders definieren, aber so weit sind wir in der Vorlesung noch nicht 🙂 . Im Bereich Geodäsie und Vermessungstechnik wird ausschließlich in Gon gerechnet 🕶 . Die Seite S3 ist konstant, also gegeben. Ich Versuchs mal so zu beschreiben: Links unten ist Alpha, rechts unten Beta, oben Gamma. Die untere Seite ist S3, die Linke S2 und die (auszurechnende) Rechte ist S1. Ich hoffe man konnte es so verstehen 😃 Die Fallunterscheidung dient zur Überprüfung, ob überhaupt ein Dreieck gebildet werden kann (hab ich schon mit anderen Programmen verglichen, das stimmt).

    Danke für die vielen Antworten! Ich werd mich heut Abend noch mal ran setzen und schauen ob es besser wird, ansonsten melde ich mich morgen nochmal 😉



  • Naja, wenn du die beiden Seiten und den eingeschlossenen Winkel hast, kannst du ja den Cos-Satz benutzen um die dritte Länge zu berechnen.

    a=b2+c22bccosαa = \sqrt{b^2 + c^2 -2bc \cos \alpha}

    So, die Buchstaben in S1,2,3 zu übersetzen bleibt dir überlassen und die Winkel errechnest du bestimmt auch schnell.

    Du brauchst jetzt nur ne Fallunterscheidung, ob der Radikant < 0 ist (dann geht da was nicht).



  • Hallo,

    In Zeile 102 steht

    b_neu = sin (S1 * sin(a_neu) / S2);
    

    .. das soll wohl der Sinussatz werden. Dann muss es aber asin statt sin heißen. So wie in Zeile 104.

    Tipp: definiere eine Variable GON2RAD (Gon to radiant alias Bogenmass)

    const double GON2RAD = PI/200;
    

    und verwende sie bei jedem trigonometrischen Aufruf - z.B.:

    beta = asin( S1 * sin( alpha * GON2RAD ) / S2 ) / GON2RAD;
    

    Dann sparst Du Dir einige Variablen und verbesserst die Lesbarkeit.

    Tipp 2: minimiere die Fallunterscheidungen. Das if( alpha == 100 ) ist sicher unnötig. Umso mehr ifs , desto mehr Möglichkeiten für

    Doch bei manchen eingaben will mein Programm einfach keine gescheiten Ergebnisse liefern

    Gruß
    Werner


Anmelden zum Antworten