Klasa punkt, trójkąt + metody, prośba o pomoc

0

Cześć,

Zaczynam przygodę z C++ na studiach, i mam problem w jednym z zadań. Treść brzmi następująco:
Proszę stworzyć klasę Trojkat opartą na 3 zmiennych typu Punkt (x, y). Prosże stworzyć 3 konstruktory - bezparametrowy, parametrowe z 3 punktami i parametrowy z 6 doublami. Należy również stworzyć setery i getery (po punktach) oraz metody isTrojkat(), isRownoboczny(), isRownoramienny(), isProstokatny(). Na koniec należy dodać metody pole() i obwod() zwracające double.

Poniżej załączam swój kod, mam jednak problem z metodą isProstokatny, pomimo iż podaje zmienne spełniające ten warunek :
if(pow(A(),2)+pow(C(),2) == pow(B(),2)) c++ traktuje to jako false, jeśli wpiszę ręcznie te same wartości warunek działa ok.
Dodatkowo, czy jestem wstanie w jakiś sposób obiekty z klasy trójkąt w1,w2,w3 zmienić na prywatne? Próbowałem zrobić dziedziczenie z klasą Punkt ale i tak nie mogę się dostać później do zmiennych x i y.

Z góry dzięki za pomoc.

#include <iostream>
#include <math.h>

class Punkt{
	double x,y;
		public:
		void setP(double x1,double y1){
			x=x1;
			y=y1;
		}
		double getX(){
			return x;
		}
		double getY(){
			return y;
		}
		Punkt();
		Punkt(double,double);
};
Punkt::Punkt(){
	x=0;
	y=0;
}

Punkt::Punkt(double x1,double y1){
	x=x1;
	y=y1;
}

class Trojkat {
		public:
			Punkt w1,w2,w3;
			double dlugosc (double x1, double y1,double x2, double y2){
				return sqrt(pow((x2-x1),2) + pow((y2-y1),2));
			}	
			double A(){
				return dlugosc(w1.getX(),w1.getY(),w2.getX(),w2.getY());
			}
			double B(){
				return dlugosc(w2.getX(),w2.getY(),w3.getX(),w3.getY());
			}
			double C(){
				return dlugosc(w1.getX(),w1.getY(),w3.getX(),w3.getY());
			}
			void isTrojkat(){
				if(A()+B()>C())
					if(A()+C()>B())
						if(B()+C()>A())
							std::cout << "Podane punkty tworza trojkat" << std::endl;
				else
					std::cout << "Podane punkty nie tworza trojkata"  <<std::endl;
			}
			void isRownoboczny(){
				if(A()==C())
					if(C() == B())
						std::cout << "Trojkat jest rownoboczny" << std::endl;
				else
					std::cout << "Trojkat nie jest rownoboczny" << std::endl;
			}	
			void isRownoramienny(){
				if(A() == C())
					std::cout << "Trojkat jest rownoramienny" << std::endl;
				if(B() == A())
					std::cout << "Trojkat jest rownoramienny" << std::endl;
				if(C() == B())
					std::cout << "Trojkat jest rownoramienny" << std::endl;
				if (A() != B() && A() != C() && B() != C())
					std::cout << "Trojkat jest nie jest rownoramienny" << std::endl;
			}
			void isProstakatny(){
				if(A() > B () && A() > C())
					if((pow(B(),2)) + pow(C(),2) == pow(A(),2))
						std::cout << "Trojkat jest prostokatny" << std::endl;
					else
						std::cout << "Trojkat nie jest prostakatny" << std::endl;
				if(B() > A() && B()> C())
					if(pow(A(),2)+pow(C(),2) == pow(B(),2))
						std::cout << "Trojkat jest prostokatny" << std::endl;
					else
						std::cout << "Trojkat nie jest prostakatny" << std::endl;
				if(C() > A() && C() > B())
					if(pow(A(),2)+pow(B(),2)==pow(C(),2))
						std::cout << "Trojkat jest prostokatny" << std::endl;
					else
						std::cout << "Trojkat nie jest prostakatny"<< std::endl; 
			}
			double pole(){
				double p = obwod()/2;
				return sqrt(p*(p-A())+(p-B())*(p-C()));
			}
			double obwod(){
				return A()+B()+C();
			}
		Trojkat();
		Trojkat(Punkt,Punkt,Punkt);
		Trojkat(double,double,double,double,double,double);
};

Trojkat::Trojkat() : w1(),w2(),w3(){
	w1.setP(3,5);
	w2.setP(4,7);
	w3.setP(3,8);
}
Trojkat::Trojkat(double w1x,double w1y,double w2x,double w2y,double w3x,double w3y):w1(w1x,w1y),w2(w2x,w2y),w3(w3x,w3y) {
	w1.setP(w1x,w1y);
	w2.setP(w2x,w2y);
	w3.setP(w3x,w3y);
}
Trojkat::Trojkat(Punkt p1,Punkt p2,Punkt p3){
	w1 = p1;
	w2 = p2;
	w3 = p3;
}



/* run this program using the console pauser or add your own getch, system("pause") or input loop */

int main(int argc, char** argv) {
	Punkt p1(4,5);
	Punkt p2;
	Punkt p3(5,3);
	Trojkat t1;
	Trojkat t2(0,0,0,5,5,0);
	Trojkat t3(p1,p2,p3);
	t2.isTrojkat();
	t2.isRownoboczny();
	t2.isRownoramienny();
	t2.isProstakatny();
	std:: cout << "Obwod: " << t2.obwod() << std::endl;
	std:: cout << "Pole: " << t2.pole() << std::endl;
 	//t3.isTrojkat();
	return 0;
}

0

tzn? zaokrągla? masz jakiś inny pomysł jak to porównać?

0

Tutaj jest coś na ten temat: http://www.cs.technion.ac.il/users/yechiel/c++-faq/floating-point-arith.html
Tak na szybko to możesz sobie wprowadzić jakiś epsilon który będzie miał wartosć możliwego błędu.

0

Zobacz https://floating-point-gui.de/
W Twoim przypadku można pokusić się o użycie aproksymacji z użyciem epsilon - coś w tym stylu

bool isRightTraingle( double a , double b , double c , const double epsilon = 0.001 )
{
   return ( abs( a - sqrt( c*c + b*b ) ) <= epsilon ||
            abs( b - sqrt( a*a + c*c ) ) <= epsilon ||
            abs( c - sqrt( a*a + b*b ) ) <= epsilon    ) ? true:false;
}

Jednakże takie rozwiązanie będzie prowadziło do sytuacji w której wiele wyników będzie false-positive.
Jeżeli musisz być dokładny to proponuję użyć biblioteki https://gmplib.org/

Dodatkowo, czy jestem wstanie w jakiś sposób obiekty z klasy trójkąt w1,w2,w3 zmienić na prywatne?

Tak wystarczy przenieść ich definicję do zakresu private

class Trojkat 
{
    private:
        Punkt w1,w2,w3;
    public:
        // 
        //
}

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