Wzór Herona

Mamy dany dowolny trójkąt o bokach równych a, b i c:

 

obrazek

 

Obliczamy parametr p równy połowie obwodu tego trójkąta:

 

obrazek

 

Aby obliczyć pole tego trójkąta, stosujemy wzór Herona:

 

obrazek

 

Poniższy program oblicza pole trójkąta o znanych długościach boków:
Przykładowe dane dla programu:

 

a = 1
b = 1
c = 1.4142   (wpisując c, zwróć uwagę na wpisanie kropki po 1, a nie przecinka!)

S = 0.5000

 

// Wzór Herona - wersja nr 1
// (C)2010 I LO w Tarnowie
//------------------------

#include <iostream>
#include <iomanip>
#include <cmath>

using namespace std;

int main()
{
    double a,b,c,p,S;

    // ustawiamy strumień cout do pracy z liczbami rzeczywistymi

    cout << fixed << setprecision(4);

    cout << "Obliczanie pola trojkata wzorem Herona\n"
            "======================================\n\n";

    // odczytujemy długości boków

    cout << "a = "; cin >> a;
    cout << "b = "; cin >> b;
    cout << "c = "; cin >> c;

    // Obliczamy pole trójkąta

    p = (a + b + c) / 2;

    S = sqrt(p * (p-a) * (p-b) * (p-c));

    // wyświetlamy wyniki

    cout << "\n------------\n\n"
            "S = " << S << endl;

    return 0;
}

 

Często trójkąt będzie zadany współrzędnymi wierzchołków A, B i C.

 

obrazek

 

Danymi wejściowymi będą współrzędne:
 

dla wierzchołka A:  xA, yA

dla wierzchołka B:  xB, yB

dla wierzchołka C:  xC, yC

 

Aby rozwiązać to zadanie, musimy umieć policzyć odległość pomiędzy dwoma punktami na płaszczyźnie kartezjańskiej:

 

obrazek

 

Poprowadźmy prostą równoległą do osi OX, aby przechodziła przez punkt A, oraz prostą równoległą do osi OY, aby przechodziła przez punkt B:

 

obrazek

 

Proste te wyznaczą nam trójkąt prostokątny:

 

obrazek

 

W trójkącie prostokątnym obowiązuje twierdzenie Pitagorasa:

 

obrazek

 

Zatem poszukiwany bok c możemy wyliczyć ze wzoru:

 

obrazek

 

Aby rozwiązać ten nowy problem, musimy wyznaczyć długości odcinków a i b. W tym celu rzutujemy prostopadle punkty A i B na osie OX i OY:

 

obrazek

 

Na osiach otrzymamy współrzędne tych punktów: A (xA,yA) i B (xB,yB). Poszukiwane długości są długościami przedziałów a: (xA,xB)  i b (yA,yB). Długość przedziału obliczamy, odejmując od jego końca początek. Zatem:

 

obrazek

 

Odległości te wstawiamy do wzoru na c, otrzymując ostatecznie:

 

obrazek

 

W przypadku naszego trójkąta należy obliczyć odległości pomiędzy wierzchołkami:

 

obrazek

 

Obliczenia te będą wymagały trzykrotnego zastosowania wzoru na odległość pomiędzy dwoma punktami. Powtarzające się obliczenia lepiej umieścić w funkcji. Znamy już jedną funkcję - main(). Programista może tworzyć w programie swoje własne funkcje. Funkcja jest fragmentem programu, który można wielokrotnie wykorzystywać. Definicja funkcji w języku C++ wygląda następująco:

 

typ_wyniku nazwa(argumenty)
{
    treść funkcji

    return wartość_zwracana;
}
 

typ_wyniku  określa rodzaj informacji, którą funkcja zwraca. Może to być jeden ze znanych nam typów int, unsigned lub double.

nazwa  - dowolna nazwa wymyślana przez programistę. Zasady tworzenia nazw funkcji są identyczne jak dla zmiennych. Nazwa umożliwia odwołanie się do funkcji w programie.

argumenty  - informacja przekazywana do funkcji. Argumenty mają postać listy:

    typ  nazwa, typ  nazwa, ...

treść funkcji - tutaj umieszczamy instrukcje C++, które są niezbędne do wykonania zadania realizowanego przez funkcję.

return wartość_zwracana  - tutaj określamy, co funkcja zwraca jako swój wynik. Wartość zwracana jest dowolnym wyrażeniem. Komputer oblicza jego wartość i zwraca jako wynik działania funkcji.

 

Poniższy program odczytuje współrzędne trzech wierzchołków, oblicza odległości pomiędzy nimi i na tej podstawie wylicza pole trójkąta zdefiniowanego przez te wierzchołki.

Dane wejściowe dla programu:

 

obrazek

xa = 1
ya = 1

xb = 2
yb = 1

xc = 1
yc = 2

 

S = 0.5000

 

// Wzór Herona - wersja nr 2
// (C)2010 I LO w Tarnowie
//------------------------

#include <iostream>
#include <iomanip>
#include <cmath>

using namespace std;

// Oblicza odległość pomiędzy dwoma punktami

double odcinek(double xa,double ya,double xb,double yb)
{
    return sqrt((xb-xa)*(xb-xa) + (yb-ya)*(yb-ya));
}

int main()
{
    double xa,ya,xb,yb,xc,yc;
    double a,b,c,p,S;

    // ustawiamy strumień cout do pracy z liczbami rzeczywistymi

    cout << fixed << setprecision(4);

    cout << "Obliczanie pola trojkata wzorem Herona\n"
            "======================================\n\n";

    // odczytujemy współrzędne wierzchołków

    cout << "xa = "; cin >> xa;
    cout << "ya = "; cin >> ya;
    cout << endl;

    cout << "xb = "; cin >> xb;
    cout << "yb = "; cin >> yb;
    cout << endl;

    cout << "xc = "; cin >> xc;
    cout << "yc = "; cin >> yc;
    cout << endl;

    // obliczamy długości boków trójkąta

    a = odcinek(xa,ya,xb,yb);
    b = odcinek(xb,yb,xc,yc);
    c = odcinek(xc,yc,xa,ya);

    // Obliczamy pole trójkąta

    p = (a + b + c) / 2;

    S = sqrt(p * (p-a) * (p-b) * (p-c));

    // wyświetlamy wyniki

    cout << "\n------------\n\n"
            "S = " << S << endl;

    return 0;
}

 

Na koniec dodamy do programu test na trójkąt prostokątny. Jeśli trójkąt jest trójkątem prostokątnym, to powinien spełniać jeden z warunków:

 

obrazek

 

Dlaczego jeden z trzech, a nie pierwszy? Otóż nie wiemy, które z boków a, b i c są przyprostokątnymi i przeciwprostokątną. Dlatego musimy przetestować wszystkie trzy możliwości. Wystarczy, że jedna z nich będzie spełniona, aby trójkąt był prostokątny. Pamiętamy jednakże, iż liczb zmiennoprzecinkowych NIE WOLNO przyrównywać do siebie. Dlatego będziemy badać ich różnice:

 

obrazek

 

// Wzór Herona - wersja nr 3
// (C)2010 I LO w Tarnowie
//------------------------

#include <iostream>
#include <iomanip>
#include <cmath>

using namespace std;

// Oblicza odległość pomiędzy dwoma punktami

double odcinek(double xa,double ya,double xb,double yb)
{
    return sqrt((xb-xa)*(xb-xa) + (yb-ya)*(yb-ya));
}

int main()
{
    double xa,ya,xb,yb,xc,yc;
    double a,b,c,p,S;

    // ustawiamy strumień cout do pracy z liczbami rzeczywistymi

    cout << fixed << setprecision(4);

    cout << "Obliczanie pola trojkata wzorem Herona\n"
            "======================================\n\n";

    // odczytujemy współrzędne wierzchołków

    cout << "xa = "; cin >> xa;
    cout << "ya = "; cin >> ya;
    cout << endl;

    cout << "xb = "; cin >> xb;
    cout << "yb = "; cin >> yb;
    cout << endl;

    cout << "xc = "; cin >> xc;
    cout << "yc = "; cin >> yc;
    cout << endl;

    // obliczamy długości boków trójkąta

    a = odcinek(xa,ya,xb,yb);
    b = odcinek(xb,yb,xc,yc);
    c = odcinek(xc,yc,xa,ya);

    // Obliczamy pole trójkąta

    p = (a + b + c) / 2;

    S = sqrt(p * (p-a) * (p-b) * (p-c));

    // wyświetlamy wyniki

    cout << "\n------------\n\n"
            "S = " << S << endl << endl;

    // sprawdzamy, czy trójkąt jest prostokątny

    double ak,bk,ck,EPS;

    ak = a * a;
    bk = b * b;
    ck = c * c;

    EPS = 0.00001;

    if((fabs(ak+bk-ck) < EPS) || (fabs(bk+ck-ak) < EPS) || (fabs(ck+ak-bk) < EPS))
        cout << "Trojkat jest prostokatny\n\n";

    return 0;
}

 


   I Liceum Ogólnokształcące   
im. Kazimierza Brodzińskiego
w Tarnowie

©2024 mgr Jerzy Wałaszek

Dokument ten rozpowszechniany jest zgodnie z zasadami licencji
GNU Free Documentation License.

Pytania proszę przesyłać na adres email: i-lo@eduinf.waw.pl

W artykułach serwisu są używane cookies. Jeśli nie chcesz ich otrzymywać,
zablokuj je w swojej przeglądarce.
Informacje dodatkowe