Obliczanie pola trójkąta - C#

0

Witam serdecznie.
Chciałbym zaznaczyć, że zaczynam swoją przygodę z programowaniem i proszę o wyrozumiałość.

Mam stworzyć prosty program w C#, którego treść brzmi następująco:

"Napisz program w C#:

  1. obliczający i wypisujący na ekranie pole powierzchni dowolnego trójkąta o zadanych długościach trzech boków.
  2. wypisujący informację, czy trójkąt jest prostokątny, rozwartokątny czy ostrokątny,
  3. W przypadku błędnych danych program winien wypisać odpowiedni do sytuacji komunikat."

w pkt. 1 zastosowałem wzór Herona i działa, natomiast nie mam pojęcia co zrobić aby rozwiązać 2 i 3 pkt...
mój kod wygląda następująco:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Pole 

{ 

    class Program
    {

        double p, a, b, c, tr;

        static void Main(string[] args)
        {

            Console.WriteLine("Podaj wartosc pierwszego boku:");
            a = Convert.ToDouble(Console.ReadLine());
            Console.WriteLine("Podaj wartosc drugiego boku:");
            b = Convert.ToDouble(Console.ReadLine());
            Console.WriteLine("Podaj wartosc trzeciego boku:");
            c = Convert.ToDouble(Console.ReadLine());
            p = (a + b + c) / 2;
            tr = Math.Sqrt(p * (p - a) * (p - b) * (p - c));
            Console.WriteLine("Pole trojkata to: " + tr);

            if (((a * a) + (b * b) < (c * c)) || ((b * b) + (c * c) < (a * a)) || ((a * a) + (c * c) < (b * b))) ;

                Console.WriteLine(" Trojkat jest rozwartokatny.");

            if (((a * a) + (b * b) > (c * c)) || ((b * b) + (c * c) > (a * a)) || ((a * a) + (c * c) > (b * b))) ;

                Console.WriteLine(" Trojkat jest ostrokatny.");

            if (((a * a) + (b * b) == (c * c)) || ((b * b) + (c * c) == (a * a)) || ((a * a) + (c * c) == (b * b))) ;

                Console.WriteLine(" Trojkat jest prostokatny.");

            else

            {
                Console.WriteLine(" Trojkat jest rownoramienny.");
            }

        }

      Console.ReadKey();
       Console.Clear();
        }

Trochę ciężko mi się połapać w c#...
Za wszelaką pomoc z góry bardzo dziękuje.

0

tak się nie porównuje liczb zmiennoprzecinkowych!
Brakuje ci jeszcze nierówności trójkąta. Nie ze wszystkich możliwych długości boków da się stworzyć trójkąt.
Poza tym dobrze kombinujesz.

Najlepiej jak na początek posortujesz długości boków (tak by c było najdłuższe), wtedy sprawdzanie warunków, będzie dużo prostsze.

0

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Pole 

{ 

    class Program
    {

        double p, a, b, c, tr;

        static void Main(string[] args)
        {

            Console.WriteLine("Podaj wartosc pierwszego boku:");
            a = Convert.ToDouble(Console.ReadLine());
            Console.WriteLine("Podaj wartosc drugiego boku:");
            b = Convert.ToDouble(Console.ReadLine());
            Console.WriteLine("Podaj wartosc trzeciego boku:");
            c = Convert.ToDouble(Console.ReadLine());
            p = (a + b + c) / 2;
            tr = Math.Sqrt(p * (p - a) * (p - b) * (p - c));
            Console.WriteLine("Pole trojkata to: " + tr);

            if (Math.Abs(a + b > c) && (b + c > a) && (a + c > b))

                Console.Write("Dobrze, z podanych bokow mozna zbudowac trojkat.");

                if (Math.Abs((a * a) + (b * b) < (c * c)) && ((b * b) + (c * c) < (a * a)) && ((a * a) + (c * c) < (b * b)));

                Console.WriteLine(" Trojkat jest rozwartokatny.");

            if (Math.Abs((a * a) + (b * b) > (c * c)) && ((b * b) + (c * c) > (a * a)) && ((a * a) + (c * c) > (b * b)));

                Console.WriteLine(" Trojkat jest ostrokatny.");

            if (Math.Abs((a * a) + (b * b) == (c * c)) && ((b * b) + (c * c) == (a * a)) && ((a * a) + (c * c) && (b * b)));

                Console.WriteLine(" Trojkat jest prostokatny.");

            else

                Console.WriteLine(" Trojkat jest rownoramienny.");

        }

      Console.ReadKey();
       Console.Clear();

Doszedłem do takiego etapu, niestety nadal nie wiem dlaczego nie chce zadziałać mi pkt2. , będę bardzo wdzięczny jeżeli ktoś z was pokaże mi jakie błędy robię, edytując mój kod abym mógł sobie to przeanalizować, bo ja pierwsze kroki i niekiedy nawet podpowiedzi nie wiele mi mówią ;)

1
MarekR22 napisał(a):

tak się nie porównuje liczb zmiennoprzecinkowych!

Skończona precyzja liczb zmiennoprzecinkowych!
dla boków o długości 2 4 5 zadziała, bo te liczby są dokładnie reprezentowane w postaci binarnej, natomiast dla boków o długości 0.3 0.4 0.5 już może nie zadziałać bo nie ma dokładnej reprezentacji binarnej niektórych z tych liczb (podobnie jak 1/3 w zapisie dziesiętnym).

Musisz wprowadzić jakaś tolerancję za miast po prostu używać operatora ==.

Inne mankamenty:

  • za dużo Math.Abs
  • (a * a) + (b * b) > (c * c) to jest zły warunek bo jeśli c jest najkrótsze to zawsze będzie spełnione mimo, że trójkąt może być w dowolnej wersji (jeszcze raz posortuj a, b c - to uprości warunki, a masz z nimi poważny problem).
  • miałeś chyba użyć alternatywy a nie koniunkcję
0

Math.Abs(a + b > c) oznacza wykonanie Math.Abs(true) lub Math.Abs(false) w zależności jaki będzie wynik porównania a + b > c

0

Zmień też kolejność działań - wpierw sprawdzaj czy można zbudować trójkąt, jeśli nie można to nie próbuj wyliczać pola. We wzorze Herona będziesz wtedy pierwiastkował liczbę ujemną i pojawi się błąd wykonania.

0

Jesli punktem dwa jest trójkąt rozwartokatny to nie może zadziałać bo ten warunek nigdy nie bedzie prawdziwy,

moje a b c to odpowiednio a*a b*b c*c
Masz warunek w stylu
{a +b <c & a+c <b }==>{b<c-a &  b>c+a}
 ponieważ  a,b,c należy do R & a,b,c > 0 (kwadraty liczb są zawsze dodatnie)
to wychodzi sprzeczność np. dla a=1 b<c-1 & b>c+1 
0

U mnie to działa:


 public static class Builder
    {
        public static Triangle BuildTriangle(double a, double b, double c)
        {
            Triangle tri;
            if (a + b > c & a + c > b & b + c > a)
            {
                if (licz_kat(a, b, c) > 90 | licz_kat(b, c, a) > 90 | licz_kat(c, a, b) > 90)

                {
                    tri = new Obtuse(a, b, c);
                    //tworzymy trójkąt rozwarokątny
                }

                if (licz_kat(a, b, c) == 90 | licz_kat(b, c, a) == 90 | licz_kat(c, a, b) == 90)
                {
                    tri = new Rectangular(a, b, c);
                    //tworzymy trójkąt prostokątny
                }

                else
                {
                    tri = new Acute_angled(a, b, c);
                    //Tworzymy trójkąt ostrokątny
                }
            }
            else
            {
                tri = new NotTriangle(a, b, c);
            }
            return tri;
        }
        static double licz_kat(double a, double b, double c)
        {
            double cos_kat;
            cos_kat = (b * b + c * c - a * a) / 2 * b * c;
            return (Math.Acos(cos_kat) * 180 / 3.14159265);
        }
    }

Klasy trójkątów to:

 public abstract class Triangle
    {
        double a, b, c, p, tr;
       protected string triType;
        public Triangle(double a,double b, double c)
        {
            this.a = a;
            this.b = b;
            this.c = c;
        }
        public double Area()
        {
            p = (a + b + c) / 2;
            tr = Math.Sqrt(p * (p - a) * (p - b) * (p - c));
            return tr;
        }
        public string TriType { get { return triType; } }
    }
    class Obtuse : Triangle
    {
        public Obtuse(double a, double b, double c):base (a,b,c)
        {
            triType = "Rozwartokątny";
        }
    }
2

http://ideone.com/A9OiTd
a tu demo czemu potrzebne jest epsilon: http://ideone.com/OcrNYW

1 użytkowników online, w tym zalogowanych: 0, gości: 1, botów: 0