编程三角计算器

时间:2012-10-12 21:04:34

标签: c# asp.net math geometry

我必须编写一个三角形计算器,它可以从三个给定值计算所有其他缺失信息。我知道如何计算值 - 这不是问题。 但我不知道,我怎么能以一种好的方式编程。

界面如下所示:

enter image description here

有了这12个输入字段,有许多可能的组合。我的第一个想法是为每个组合使用if / else语句。但这不是很有效。 我敢肯定,有一个更好的解决方案,但我不知道如何。 有人能帮助我吗?

EDIT 我的代码看到了这一刻:

protected void FlaecheBerechnen_Click(object sender, EventArgs e)
    {     
        WerteAuslesen();
        Berechnen();
    }

    protected void WerteAuslesen()
    {
        //Sides
        string strSeite_a = this.txt_a.Text; if (strSeite_a == string.Empty) { i++; } else { if ((double.TryParse(strSeite_a, out seite_a) == false)) { GenerateErrorReport("Seite a"); } }
        string strSeite_b = this.txt_b.Text; if (strSeite_b == string.Empty) { i++; } else { if ((double.TryParse(strSeite_b, out seite_b) == false)) { GenerateErrorReport("Seite b"); } }
        string strSeite_c = this.txt_c.Text; if (strSeite_c == string.Empty) { i++; } else { if ((double.TryParse(strSeite_c, out seite_c) == false)) { GenerateErrorReport("Seite c"); } }

        //Angles
        string strWinkel_a = this.txtAlpha.Text; if (strWinkel_a == string.Empty) { i++; } else { if ((double.TryParse(strWinkel_a, out winkel_a) == false)) { GenerateErrorReport("Winkel Alpha"); } }
        string strWinkel_b = this.txtBeta.Text; if (strWinkel_b == string.Empty) { i++; } else { if ((double.TryParse(strWinkel_b, out winkel_b) == false)) { GenerateErrorReport("Winkel Beta"); } }
        string strWinkel_y = this.txtGamma.Text; if (strWinkel_y == string.Empty) { i++; } else { if ((double.TryParse(strWinkel_y, out winkel_y) == false)) { GenerateErrorReport("Winkel Gamma"); } }

        //Height
        string strHoehe_a = this.txt_ha.Text; if (strHoehe_a == string.Empty) { i++; } else { if ((double.TryParse(strHoehe_a, out hoehe_a) == false)) { GenerateErrorReport("Höhe a"); } }
        string strHoehe_b = this.txt_hb.Text; if (strHoehe_b == string.Empty) { i++; } else { if ((double.TryParse(strHoehe_b, out hoehe_b) == false)) { GenerateErrorReport("Höhe b"); } }
        string strHoehe_c = this.txt_hc.Text; if (strHoehe_c == string.Empty) { i++; } else { if ((double.TryParse(strHoehe_c, out hoehe_c) == false)) { GenerateErrorReport("Höhe c"); } }

        //ErrorReport:
        if (ErrorMessage != null)
        {
            Page.ClientScript.RegisterStartupScript(this.GetType(), "ErrorAlert", "alert('Folgende Angaben sind fehlerhaft: " + ErrorMessage + "');", true);
            return;
        }

        //Logic
        //If more than 3 values....

        string AlertText;

        if (i < 6)
        {
            AlertText = "Es dürfen nur 3 Angaben gemacht werden!";
            Page.ClientScript.RegisterStartupScript(this.GetType(), "ErrorAlert", "alert('" + AlertText + "');", true);
            return;
        }
        if (i > 6)
        {
            AlertText = "Es müssen mindestens 3 Angaben gemacht werden!";
            Page.ClientScript.RegisterStartupScript(this.GetType(), "ErrorAlert", "alert('" + AlertText + "');", true);
            return;
        }
    }

    protected void Berechnen()
    {
        //Höhensatz

        if (seite_a != 0 && seite_b != 0 && seite_c != 0)
        {
            //Calculate missing angles

                //Winkel Gamma
                cos_y = (seite_a * seite_a) + (seite_b * seite_b) - (seite_c * seite_c); //Zähler berechnen
                cos_y = cos_y / (2 * seite_a * seite_b); //Durch Nenner teilen
                winkel_y = Math.Acos(cos_y); //Bogenradius berechnen
                winkel_y = winkel_y * 180 / Math.PI; //In Winkel umrechnen

                //Winkel Beta
                cos_b = (seite_c * seite_c) + (seite_a * seite_a) - (seite_b * seite_b); //Zähler berechnen
                cos_b = cos_b / (2 * seite_c * seite_a); //Durch Nenn teilen
                winkel_b = Math.Acos(cos_b); //Bogenradius berechnen
                winkel_b = winkel_b * 180 / Math.PI; //In Winkel umrechnen

                //Winkel Alpha
                double winkel_a = 180 - winkel_b - winkel_y;

                //Werte eintragen
                txtAlpha.Text = Convert.ToString(winkel_a);
                txtBeta.Text = Convert.ToString(winkel_b);
                txtGamma.Text = Convert.ToString(winkel_y);

            //Flächen berechnen

                //Mit Satz des Heron
                Heron heron = new Heron(seite_a, seite_b, seite_c);
                double FlaecheHeron = heron.Area;
                Page.ClientScript.RegisterStartupScript(this.GetType(), "ErrorAlert", "alert('" + FlaecheHeron + "');", true);     
        }
    }

问题是,有太多可能的组合。 如果(seite_a!= 0&amp;&amp; seite_b!= 0&amp;&amp; seite_c!= 0)等等......

1 个答案:

答案 0 :(得分:2)

您可以记下可能用于执行计算的所有规则。我想你会使用角度和,正弦定律,余弦定律等等。将这些规则中的每一个写为一个类,并为每个可能的标签创建一个实例(即,您是否使用余弦定律来计算γ或β)。您应该最终得到一个对象列表,它们共享一个公共接口,您可以使用它来计算其他一些值的某些值。然后,您可以遍历此列表以查看适用的规则,并使用它们来计算其他值。一旦缺失值的计数达到零,就完成了。

如果您在没有找到要应用的规则的情况下迭代所有规则,那么您的可能规则集就不够完整。我相信写一个unit test是一个非常好的主意,它会尝试所有220种可能的方法来填充12个输入中的3个,以确保你有足够的规则来处理所有这些。只需从一组完整的12个值开始,计算所有三元素子集,将它们输入到您的应用程序代码中,并将结果与​​预期值进行比较,并考虑数值误差。

上述方法既未针对性能进行优化,也未针对数值稳定性进行优化。如果其中任何一个对您来说都是一个问题,那么另一种方法可能更适合。