[C++] coordinate cartesiane dubbio/ Numeri complessi

84Valery84
Ciao a tutti
chiedo scusa ma ho un dubbio che non riesco a chiarirmi. Forse è una sciocchezza ma mi sto incartando e non riesco a venirne a capo.
Devo implementare una classe rettangolo che contiene le coordinate cartesiane dei 4 angoli di un rettangolo.
Il costruttore attraverso una funzione set accetta quattro coppie di coordinate e verifica che sono nel primo quadrante. Poi l'esercizio chiede di calcolare area, perimetro etc.. e qui non ho difficoltà.
La mia difficoltà sta nel rappresentare le coordinate.
Innanzitutto devo scriverle per forza tutte e 4 o posso assumere che i lati del rettangolo siano paralleli agli assi coordinati e usarne solo due?
Posso esprimerle in questo modo?
float punto1(a,b);
float punto2(d,c);
...  

e poi assegnare i valori con set.
Onestamente ho difficoltà a capire come impostarle.
Qualcuno può darmi uno spunto gentilmente?
Ringrazio tutti
P.

Risposte
Omega1
Ciao !
Come hai definito la classe rettangolo?
Il mio consiglio, è quello di definire anche la classe punto, con i metodi per calcolare la distanza ecc.
Quindi, nella classe rettangolo, puoi definire un costruttore che riceve 2 punti ( il rettangolo è ortogonale agli assi ) ed un secondo costruttore che riceve tre punti ( il rettangolo è inclinato rispetto agli assi ).

Rggb1
Certo il tutto dipende da cosa vuoi realizzare e quali limitazioni vuoi imporre.

La struttura dati minima e completa per definire correttamente un rettangolo in un piano dovrebbe essere composta da:
- un punto $(x, y)$
- due lati $a$ e $b$
- un angolo $alpha$

Il rettangolo ha quindi vertici in $(x,y)$, in $(x+a*cos(alpha), y+a*sin(alpha))$ e così via. Qualunque valore di $x$, $y$, $a$, $b$ e $alpha$ definisce correttamente un rettangolo, anche se il costruttore potrebbe essere implementato con dei controlli (per esempio per evitare - se si vuole - lunghezze dei lati nulle).

Se non hai bisogno di definire rettangoli comunque orientati ma solo con i lati paralleli agli assi di riferimento, il metodo migliore è quello di usare due punti, oppure un punto e due lati, e come puoi intuire le cose si semplificano molto.

PS. Usa comunque i double e non i float.

84Valery84
grazie delle dritte, vedrò cosa riesco a tirare fuori ;)

84Valery84
Allora, onestamente ho abbandonato l'esercizio perchè non sono riuscita ad implementarlo. :cry: Mi sono dedicata ad un altro in particolare ad un esercizio che mi chiede di creare una classe di numeri complessi che effettua delle operazioni su di essi. In particolare l'addizione e la sottrazione. Io ho provato a farlo, ma ho un pò di difficoltà nello scrivere le operazioni. Facendo un pò di ricerca noto che molti usano l'overloading degli operatori. Poichè non è ancora un argomento approfondito, vorrei farlo diversamente.
Di seguito posto il codice che ho scritto, qualcuno può gentilmente darmi una dritta?
Grazie sempre per la disponibilità preziosa. ;-)

#include <iostream>
#include <complex>
#include <cmath>
using namespace std;
class Complesso {
public:
	Complesso (); // costruttore
	double Sum();
	double Substract();
	void setRe(double a); // assegno valori alla parte reale
	void setIm (double b);// assegno o modifico valore parte immaginaria
	double getRe (); // visualizzo il valore parte reale
    double getIm();// visualizzo il valore parte immaginaria

	private:
	double x;
	double y;
};

//metodi
Complesso::Complesso()
{
	x=0;
	y=0;
}

void Complesso :: setRe(double a)
{
	x=a;
}
void Complesso:: setIm (double b)
{
	y=b;
}
double Complesso:: getRe()
{
	return x;
}

double Complesso :: getIm()
{
	return y;
}
double Complesso::Sum()
{
	return (x_re + y_re, x_im + y_im) // ?????
}
double Complesso::Substract() {
	return ();
}

int main ()
{

double x;
double y;
cout << "inserisci la parte reale:";
cin >> x;
cout << "inserisci la parte immaginaria: " ;
cin >> y;
Complesso c;
cout << "\nLa somma è: " << c.Sum();
cout <<"\n\n La sottrazione è: " << c.Substract();
 cout << endl;
 return 0;
}

Ho pensato di usare delle funzioni set per modificare i valori di parte reale ed immaginaria e get per visualizzarli. Ma non so,onestamente se sono andata a complicarmi la vita. E poi devo sistemare ancora il main. :smt012

apatriarca
La somma di numeri complessi è una operazione binaria. Un qualsiasi metodo che implementa tale operazione ha quindi bisogno di accedere a due istanze diverse della classe Complesso. Queste istanze possono essere this e un'altra passata come argomento, oppure due istanze passate come argomento. Inoltre il risultato della somma di due complessi è un'altro numero complesso. Per cui devi fare ricorso ad una delle seguenti soluzioni (ho supposto l'esistenza di un costruttore che riceva due argomenti double per inizializzare x e y):
// funzione membro non statica
Complesso Complesso::Sum(Complesso c) { return Complesso(x + c.x, y + c.y); }

// funzione membro statica
static Complesso Complesso::Sum(Complesso c0, Complesso c1) { return Complesso(c0.x + c1.x, c0.y + c1.y); }

// funzione non membro
Complesso Sum(Complesso c0, Complesso c1) {return Complesso(c0.getRe() + c1.getRe(), c0.getIm() + c1.getIm()); }

Omega1
Ciao!

Cosa non ti funziona nella classe rettangolo? (Posta il codice. )

Per quanto riguarda la classe complesso, hai fatto bene a definire i metodi set e get per modificare i dati.
La funzione Sum(), calcola la somma tra due numeri complessi, quindi non può restituire un double.

Dovresti fare qualcosa del genere:
Complesso Complesso::Sum(Complesso b) // passo alla finzione, complesso
                                   // il numero da sommare
{
    Complesso temporaneo; // creo un oggetto temporaneo
    temporaneo.x=x + b.x;
    temporaneo.y=y + b.y;
    return temporaneo; // restituisco l' oggetto
}


Nel main, ci sara:
int main ()
{

double x;
double y;
cout << "inserisci la parte reale:";
cin >> x;
cout << "inserisci la parte immaginaria: " ;
cin >> y;
Complesso c, i, somma;
c.setRe(x);
c.setIm(y);
i.setRe(0.0);
i.setIm(1.0);
somma=c.Sum(i); // in somma, salvo il risultato
cout << "\nLa somma e': ( " << somma.getRe() << ", " <<somma.getIm() << " )";
cout << endl;
cin.ignore(210, '\n');
return 0;
}

84Valery84
grazie ad apatriarca ed Omega, gentilissimi.

@ Omega
ho aggiunto il codice secondo tuo suggerimento solo che ho questi due errori che non riesco a sistemare:
#include <iostream>
#include <complex>
#include <cmath>
using namespace std;
class Complesso {
public:
   Complesso (); // costruttore
Complesso ComplessoSum();
   void setRe(double a); // assegno valori alla parte reale
   void setIm (double b);// assegno o modifico valore parte immaginaria
   double getRe (); // visualizzo il valore parte reale
    double getIm();// visualizzo il valore parte immaginaria

   private:
   double x;
   double y;
};

//metodi
Complesso::Complesso()
{
   x=0;
   y=0;
}

void Complesso :: setRe(double a)
{
   x=a;
}
void Complesso:: setIm (double b)
{
   y=b;
}
double Complesso:: getRe()
{
   return x;
}

double Complesso :: getIm()
{
   return y;
}
 Complesso Complesso::Sum(Complesso b) // passo alla funzione, complesso
                                   // il numero da sommare
{
    Complesso temporaneo; // creo un oggetto temporaneo
    temporaneo.x=x + b.x;
    temporaneo.y=y + b.y;
    return temporaneo; // restituisco l' oggetto
}

int main ()
{
double x;
double y;
cout << "inserisci la parte reale:";
cin >> x;
cout << "inserisci la parte immaginaria: " ;
cin >> y;
Complesso c, i, somma;
c.setRe(x);
c.setIm(y);
i.setRe(0.0);
i.setIm(1.0);
somma=c.Sum(i); // in somma, salvo il risultato
cout << "\nLa somma e': ( " << somma.getRe() << ", " <<somma.getIm() << " )";
cout << endl;

return 0;
}



errori:
**** Build of configuration Debug for project CLASSE COMPLEX ****

**** Internal Builder is used for build               ****
g++ -O0 -g3 -Wall -c -fmessage-length=0 -ocompl.o ..\compl.cpp
..\compl.cpp:50: error: no 'Complesso Complesso::Sum(Complesso)' member function declared in class 'Complesso'
..\compl.cpp: In function 'int main()':
..\compl.cpp:72: error: 'class Complesso' has no member named 'Sum'
Build error occurred, build is stopped
Time consumed: 279  ms.  


ah P.S: per quanto riguarda la classe rettangolo è solo abbozzata, appena ricavo qualcosa in più posto il codice. Sto cercando di spratichirmi, solo che a volte mi perdo davvero in un bicchier d'acqua.

Omega1
Il compilatore, ti segnala un malinteso, perché non c' e corrispondenza tra i metodi dichiarati nella classe, con quelli effettivamente implementati.

..\compl.cpp:50: error: no 'Complesso Complesso::Sum(Complesso)' member function declared in class 'Complesso'
..\compl.cpp: In function 'int main()':
..\compl.cpp:72: error: 'class Complesso' has no member named 'Sum'


Ti segnala che Sum ( Complesso ) non è dichiarato in Complesso

84Valery84
Grazie mille a tutti! Ho risolto :-)
A volte errori banali mi sembrano così complicati... dopo un pò ho capito l'errore e ho risolto.
Grazie a tutti voi per l'aiuto dato :-)
Provvederò anche con la classe rettangolo :-)
thanks!!!!

84Valery84
Ho provato a fare anche la classe rettangolo, ma quello che noto è che mi blocco principalmente nello sviluppare le funzioni richieste dall'esercizio.

L'esercizio chiede di sviluppare una classe rettangolo che contiene le coordinate cartesiane dei quattro angoli del rettangolo.
Il costruttore chiama una funzione set che accetta quatto coppie di coordinate e verifica che ognuna si esse si trovi nel primo quadrante(cioè verifichi che x e y siano maggiori di zero) e che tutti i calori delle coppie x e y non siano maggiori di 20.0. Ci sono inoltre altre funzioni membro che calcolano l'area e il perimetro e poi una funzione predicativa square che determina se il rettangolo è un quadrato.

Quest'ultimo punto, onestamente l'ho tralasciato al momento. Ho provato a fare tutto il resto. Solo credo di aver fatto confusione con le coordinate che son state il mio cruccio dall'inizio.
Posto il codice e come sempre, se possibile, accetto ben volentieri suggerimenti e critiche.
Grazie per la disponibilità :)

#include <iostream>
#include <cmath>
using namespace std;
 class Rettangolo {
 public:
	Rettangolo(); // costruttore
	double ax, ay, bx, by,cx, cy, dx, dy;
	void setCoord();// verifica condizioni sulle coordinate
	double getCoord();
	double Area();
	double Perimetro();
 private:
	double a,b,c,d, x, y;
};

Rettangolo::Rettangolo (double ax, double bx, double cx, double dx, double x, double y)
{
	a=ax;
	b=bx;
	c=cx;
	d=dx;
	x=0;
	y=0;
}
// devo verificare con set che le mie coordinate sono maggiori di zero e mminori di 20.00
void Rettangolo::setCoord()
{
	if (a(x,y) >= 0.0 && a(x,y) < 20.0)
		cout <<"le coordinare ax e ay sono positive";
	{
	else
		cout << "fuori range"  ;
}
}
{
if (b(x,y) >= 0.0 && b(x,y) < 20.0)
		cout <<"le coordinare bx e by sono positive";
{
	else
		cout << "fuori range"  ;
}
}

{
if (cx,cy >= 0.0 && cx,cy < 20.0)
		cout <<"le coordinare cx e cy sono positive";
	{
	else
	}
		cout << "fuori range"  ;
}
}
{
if (dx,dy >= 0.0 && dx,dy < 20.0)
		cout <<"le coordinare dx e dy sono positive";
	{
	else
		cout << "fuori range"  ;
}
}


double getCoord()
{
	return a,b,c,d;
}
double Rettangolo::Area(){
	return (ax-bx)*(ay-by);
}
double Rettangolo::Perimetro(){
	return ((ax-bx) + (ay-by))*2;
}
int main ()
{
	Rettangolo r; //oggetto rettangolo
	double ax, bx, ay, by;

	cout <<"Inserisci un valore per le coordinate"
			cin >> ax >> bx;
	r.setCoord(ax, bx);
	cout <<"Inserisci un valore per le coordinate"
			cin >> ay >> by ;
	r.setCoord(ay, by);

	cout << "L'area è: " << r.Area()<< endl;
	cout <<"\nIl perimetro è: " << r.Perimetro() << endl;
	return 0;
}

Omega1
Ho letto l' esercizio, e ti consiglio di definire la classe punto.
In essa, potrai delineare alcune funzioni, ad esempio:

-Calcolo della distanza tra due punti
-Determinazione del quadrante in cui sta il punto
-Ecc.

Così facendo, la risoluzione sarà facilitata.
In ogni modo, sta attenta a come definisci le funzioni, e quali parametri accettano.

Che cosa intendi con " calori delle coppie x e y " ?

84Valery84
ho sbagliato a digitare. Volevo scrivere "valori". Grazie delle dritte, proverò a fare così ;)

84Valery84
@Omega
scusa non mi è chiara una cosa. Con dichiarare una classe punto, intendi dire usare una classe base e una derivata? Usare l'ereditarietà?

vict85
"Rggb":
Certo il tutto dipende da cosa vuoi realizzare e quali limitazioni vuoi imporre.

La struttura dati minima e completa per definire correttamente un rettangolo in un piano dovrebbe essere composta da:
- un punto $(x, y)$
- due lati $a$ e $b$
- un angolo $alpha$

Il rettangolo ha quindi vertici in $(x,y)$, in $(x+a*cos(alpha), y+a*sin(alpha))$ e così via. Qualunque valore di $x$, $y$, $a$, $b$ e $alpha$ definisce correttamente un rettangolo, anche se il costruttore potrebbe essere implementato con dei controlli (per esempio per evitare - se si vuole - lunghezze dei lati nulle).

Se non hai bisogno di definire rettangoli comunque orientati ma solo con i lati paralleli agli assi di riferimento, il metodo migliore è quello di usare due punti, oppure un punto e due lati, e come puoi intuire le cose si semplificano molto.

PS. Usa comunque i double e non i float.


Seppur richieda un double in meno, hai comunque il problema che diminuisce la stabilità numerica della classe. Con lo stesso numero di variabili hai anche la memorizzazione di 2 punti e una lunghezza, oppure un punto, un vettore e una lunghezza. Tutto sommato io penso userei però 1 punto e 2 vettori (che segnano due punti).

vict85
"Pandora":
@Omega
scusa non mi è chiara una cosa. Con dichiarare una classe punto, intendi dire usare una classe base e una derivata? Usare l'ereditarietà?


Un rettangolo è un punto? No! Quindi la classe rettangolo conterrà dei punti come delle variabili membro. L'ereditarietà va usata con MOLTA parsimonia, e solo quando ha senso.

84Valery84
ok grazie mille

Rispondi
Per rispondere a questa discussione devi prima effettuare il login.