Trapez zadanie na zaliczenie

0

Witam, dostałem do zrobienia na zaliczenie zadanie o poniższej treści
OPIS ZADANIA
Mały Bajtocjanin - Bajtek ma problemy z obliczeniem pól trapezu. Pomóż mu pisząc uniwersalną aplikacje wyręczającą go w męczących obliczeniach.
WEJSCIE
W pliku datain.txt znajdują się dane o wierzchołkach trapezu w układzie kartezjańskim.
Wierzchołki nie są w żaden sposób uporządkowane. Należy napisać program obliczający pole i obwód zadanego trapezu . Należy uwzględnić wszystkie sytuacje nietypowe (np. trójkąt, kwadrat, prostokąt, lub nie prawidłowe dane) i poinformować Bajtka o zaistniałej sytuacji lub problemie.
WYJSCIE
Wyprowadzić wyniki obliczeń do pliku dataout.txt
Np. dla danych wejściowych
1 1
3 1
2.5 2
1.5 2
pole = 1.5
obwód = 4,232
a dla danych
-1 -1
-1 0
1 1
0 1
Pole = 1.5
Obwód = 6.242

Póki co udało mi się napisać coś takiego

#include <iostream>
#include <cstdio>
#include <math.h>
#include <cmath>
#include <fstream>
#include <string>
using namespace std;

string tablica[5];
double dl_w[5];
fstream plik1;
fstream plik2;
int x;
int y;



/*
1. sprawdzanie ilosci danych
jesli > 4 -> nieprawidlowe dane
jesli = 3 -> trojkat
jesli < 3 -> nieprawidlowe dane
jesli = 4 ->
  komb1
   liczmy dlugosci bokow
   jesli wszystkie boki sa rowne -> kwadrat
   jesli (a-b)^2 > |c^2-d^2| -> trapez
      liczymy pole i obw
   jesli wszystkie boki rozne -> wielokat (bledne dane)
   jesli a = b i c = d ale a <> c i b <> d -> prostokat
*/
void komb1()
{
   for(int i=0;i>3;i++)
   {
       x= //x 1 pkt
       y= //y 1 pkt
       dl_w[i] = sqrt((x*x)+(y*y));
   }
   if(dl_w[0]==dl_w[1] || dl_w[0]==dl_w[2] || dl_w[0]==dl_w[3])
   {
       cout<<"kwadrat"<<endl;
   }
   int j=(dl_w[0]-dl_w[1]);
   int wb=abs((dl_w[2]*dl_w[2])-(dl_w[3]*dl_w[3]));
   if((j*j)>wb)
   {
       cout<<"trapez"<<endl;
       //wyliczenie p i obw
   }
   //to samo dla wszystkich bokow rownych i prostokata

}


int main()
{

   plik1.open("dane1.txt", std::ios::in);
   for(int i=0;i=5;i++)
   {
       getline(plik1,tablica[i]);
       if (tablica[i]=="")
       {
           if (tablica[4]!="")
           {
            cout<<"Nieprawidlowe dane"<<endl;
           }
           else{

               switch(i)
               {
               case 1:
                   cout<<"Nieprawidlowe dane, tylko 1 pkt"<<endl;
                   break;
               case 2:
                   cout<<"Nieprawidlowe dane, tylko 2 pkt"<<endl;
                   break;
               case 3:
                   cout<<"Powstanie trojkat"<<endl;
                   break;
               case 4:
                   komb1();
                   //[..]komb24();
                   break;
               }

           }
       }
   }
   plik1.close();


};

Niestety tu pojawił się problem bo nie wiem jak wyciągnąć liczby z wczytanego wiersza( w całości bez pomijania fragmentów)
oraz jak to zrobić w wypadku liczb ujemnych
Wszelka pomoc byłaby mile widziana, Pozdrawiam.

0

Użyj istringstream, coś w tym stylu:

int x[10], y[10];
string linia;
int liczbaLinii = 0;

while(getline(plik1, linia) {
    istringstream dane(linia);
    if (dane >> x[liczbaLinii] >> y[liczbaLinii])
        liczbaLinii++;
}

Co do samego problemu, to trzeba kombinować z iloczynem skalarnym i wektorowym.
Przykładowo, jeśli iloczyny wektorowe dla poszczególnych i dla 2 wierzchołków są dodatnie, a dla pozostałych dwóch ujemne, to wtedy musisz zmienić kolejność punktów, bo masz "klepsydrę".

0

Niekoniecznie wystarczy posortowac odpowiednio punkty. Dolny lewy zawsze bedzie mial najmniejsze x i y, gorny lewy najmniejszy x itd. Potem po prostu znajac juz ich polozenie moze liczyc reszte.

0

@Krycho, a po co ta wiedza?

Po prostu trzeba sprawdzić, czy któreś dwie proste do których należą jakieś dwa punkty są równoległe, jeśli tak to jest to trapez.
Dodajemy długości równoległych odcinków utworzonych z tych prostych, i liczymy odległość między nimi, z elementarnego wzoru. odległość to będzie wysokość.
No i już mamy wszystkie dane.

Aha,

Jeżeli odległość prostych równoległych jest równa 0 to znaczy, że jakieś trzy punkty są współliniowe więc to nie jest trapez. Chyba wszystkie możliwości już rozpatrzyłem, jakbym o czymś zapomniał to napiszcie.

0
  1. Do obliczenia pola to wystarczy, ale trzeba policzyć również obwód.

Należy uwzględnić wszystkie sytuacje nietypowe (np. trójkąt, kwadrat, prostokąt

Co autor zadania miał na myśli? Wymienione nietypowe sytuacje nie mają przecież wpływu na stosowane wzory.

0

OK, krycho miał rację

  1. Sortowanie punktów, może być od lewej dolny , lewy górny... (jeżeli nakładają się jakieś punkty to wypisujemy że jest to trójkąt, jeśli trzy lub więcej, to prosta albo punkt), grupujemy je boki to będą odcinki 1,2 2,3 3,4 4,1

  2. sprawdzamy czy przeciwległe odcinki równoległe (jeśli żadne nie są to błąd), przy okazji liczymy ich długości i dodajemy do sumy, w biegu mamy obwód. Jeśli obydwa przeciwległe równoległe to prostokąt, do tego jeśli długości boków równe to kwadrat. Dodatkowo przy liczeniu wzoru na proste musimy sprawdzić czy jakaś wcześniejsza nie ma takiego samego wzoru. Jeżeli tak to znaczy że jest to trójkąt, albo wszystkie leżą na tej samej prostej, to wtedy nie wiem :P.

  3. Mamy już te dwa równoległe to liczymy ich odległość, mamy wcześniej wyliczone długości, podstawiamy do wzoru i jest pole.

  4. Zamiast komunikatu że to trójkąt można przejśćdo innej funkcji liczącej pole i obwód trójkąta.

  5. Równoległość chyba wiesz jak policzyć z wzoru na funkcje liniowe, jak nie to jest na google.

  6. Żadnych liczb ujemnych nie ma (poza tymi w układzie współrzędnych), odległość zawsze jest dodatnia

0

Należy uwzględnić wszystkie sytuacje nietypowe (np. trójkąt, kwadrat, prostokąt

Ponowię pytanie, co autor zadania miał na myśli. Przecież, ze wzoru na pole (obwód) trapezu, można też policzyć pole (obwód) prostokąta, kwadratu, trójkąta.
Nie trzeba sprawdzać, czy badana figura nie jest przypadkiem kwadratem, prostokątem, trójkątem.
Jeżeli wszystkie punkty leżą na jednej prostej, to pole=0. Z obwodem jest problem.
//Edit. Jeżeli potraktujemy "jednowymiarowy" trapez jak położenie graniczne normalnych trapezów, to obwód powinien być równy 2*(odległość między skrajnymi punktami).

0

A da radę zrobić to bez liczenia wyjątku (w tym wypadku któryś bok = 0)? Chyba nie, więc i tak trzeba to liczyć osobno. Chyba.

0

niech ai to niech będą wektory łączące kolejne punkty (i-ty i i+1):
pole = \frac{1}{2}|\vec{a_1}\times\vec{a_2}+\vec{a_3}\times\vec{a_4}|
dla dowolnego czworoboku.
Co do sortowania punktów to jest algorytm Grahama, który dla 4 punktów upraszcza się do togo co już napisałem, czyli jeśli znak w_i=\vec{a_i}\times\vec{a_{i+1}}, dla wszystkich i, dwa razy daje +, oraz dwa razy daje - to trzeba zamienić dowolne dwa niesąsiadujące punkty, co jest znacznie prostsze niż cały algorytm Grahama.
Trójkąt jest gdy tylko jeden wi jest równy zero, a odcinek gdy co najmniej dwa wi są zerowe.
Trapez jest gdy \vec{a_1}\times\vec{a_3}=0;\vee;\vec{a_2}\times\vec{a_4}=0

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