//--------------------------------------------------------------------------- // osuuko2.cpp // // Ohjelmalla tutkitaan piste johonkin kuvioon joukossa. // // Vesa Lappalainen 1.3.2001, luennolla klo 12-14. // Muutokset 1.3.2001/vl // Metodit cKuviot-luokkaan: // ~cKuviot(); // cKuvio *eka_osuma(const cPiste &piste); // cKuvio *seuraava_osuma(const cPiste &piste); // Metodit cNaytto-luokkaan: // void kysy_kuviot(); // void kysele_pisteita(); // int kysy_tiedot(cKuvio *kuvio); // // Projektiin: osuuko2.cpp, ALI\ioali.c, ALI\mjonot.c, ALI\dout.cpp // // Tehtäviä: // 1) Laita neliö toimivaksi, mitä pitää muuttaa cPisteestä? // "Poikkeava" ehdotus: loo (l-ääretön) metriikka kahdelle pisteelle: // d(x,y) = max(abs(x1-y1),abs(x2-y2)) x = (x1,x2) // Tällöin "Ympyrät" ovat neliöitä! (vrt analyysin kurssi). // 2) Laske moneenko eri paikkaan tulisi muutos jos // lisättäisiin tasasivuinen kolmio (=jokainen sivu yhtäpitkä) // 3) Suunnittele systeemi, missä uuden kuviotyypin lisääminen // vaatisi vain luokan tekemisen sekä yhden rivin lisäyksen johonkin // 4) Kuvioiden tallettaminen tiedostoon // 5) Kuvioiden lukeminen tiedostosta // 6) Virhekäsittely (try-catch) // 7) Graafinen käyttöliittymä /* Suunnitelma: Ohjelmalla tutkitaan osuuko piste johonkin kuvioon joukossa. Syötä kuviot: L = lopeta kuvioiden syöttö 1 = ympyrä 2 = neliö Valitse kuvio: 1 Anna ympyrän säde>2[ret] Anna keskipiste >3 4[ret] Lisäsit kuvion Ympyrä: säde 2: keskipiste (3,4) L = lopeta kuvioiden syöttö 1 = ympyrä 2 = neliö Valitse kuvio: 2 Anna neliön säde>3[ret] Anna keskipiste >5 6[ret] Lisäsit kuvion Neliö: säde 3: keskipiste (5,6) L = lopeta kuvioiden syöttö 1 = ympyrä 2 = neliö Valitse kuvio: L Anna tutkittava piste>1.5 4[ret] Piste (1.5,4) osuu kuvioon Ympyrä: säde 2: keskipiste (3,4) Anna tutkittava piste>4 4[ret] Piste (4,4) osuu kuvioon Ympyrä: säde 2: keskipiste (3,4) Piste (4,4) osuu kuvioon Neliö: säde 3: keskipiste (5,6) Anna tutkittava piste>[ret] Anna tutkittava piste>1 1[ret] Piste (1,1) ei osu yhteenkään kuvioon! Anna tutkittava piste>[ret] Kiitoksia!! */ #if 0 Tietorakenteet: cNaytto cKuviot |--------| |----------| <--------------------------|- o | | | | ------ | | 6 | max_lkm | |3,4 | | cPiste | 2 | lkm |--------| | | | o | alkiot |----------| | | | v cYmpyra |----------| |-------| 0 | o----+---------> | 2 | |----------| | 3,4 | cPiste 1 | o----+-----| |-------| |----------| | cNelio 2 | | | |-------| |----------| ------------------->| 3 | 3 | | | 5,6 | cPiste |----------| |-------| 4 | | |----------| 5 | | |----------| #endif /* cKuviot - tallettaa kuvioita (lisää yms...) - etsi kuvio johon piste osuu cNaytto - hoitaa yhteistyön käyttäjään cPiste - osaa muuttaa merkkijonon pisteeksi cYmpyra - kp, säde - osuuko piste ympyrään cNelio - kp, säde - osuuko piste neliöön */ #include #include #include #include #include "ioali.h" #include "dosout.h" using namespace std; //--------------------------------------------------------------------------- class cPiste{ double x,y; public: cPiste(double ix=0,double iy=0) : x(ix), y(iy) { } void setAsString(const string &s); string getAsString() const; double etaisyys(const cPiste &piste) const { return sqrt((x-piste.x)*(x-piste.x) + (y-piste.y)*(y-piste.y)); } }; void cPiste::setAsString(const string &s) // kaivaa jonosta 3 4 arvoit x:lle ja y:lle { char apu[10]; sscanf(s.c_str(),"%lf%1[ ,]%lf",&x,apu,&y); } string cPiste::getAsString() const { char s[80]; sprintf(s,"(%lg,%lg)",x,y); return string(s); } //--------------------------------------------------------------------------- #if 0 int main(void) { cPiste piste; string s = "3 4"; string s2; piste.setAsString(s); // => piste on 3,4 s2 = piste.getAsString(); // => s2 = (3,4) cout << "Piste " << s2 << "\n"; return 0; } #endif //--------------------------------------------------------------------------- class cKuvio { protected: double r; cPiste kp; public: cKuvio() { r = 1; } virtual ~cKuvio() { } // Jos luokkaa aiotaan periä, virt. destruktori!!! void setR(double ir) { if ( ir >= 0 ) r = ir; } void setKP(const cPiste &piste) { kp = piste; } virtual string getAsString() { char s[200]; sprintf(s,": säde %lg: keskipiste ",r); return getNimi() + s + kp.getAsString(); } virtual string getNimi() const { return "Kuvio"; } virtual bool osuuko(const cPiste &piste) { double etaisyys = kp.etaisyys(piste); return etaisyys <= r; } }; //--------------------------------------------------------------------------- class cYmpyra : public cKuvio { public: virtual string getNimi() const { return "Ympyrä"; } }; class cNelio : public cKuvio { public: virtual string getNimi() const { return "Neliö"; } virtual bool osuuko(const cPiste &piste) { // ht double etaisyys = kp.etaisyys(piste); return etaisyys <= 2*r; // WWW } }; //--------------------------------------------------------------------------- class cKuviot { // Luokan lisaa-metodi ottaa lisättävästä osoittimesta vastuun int max_lkm; int lkm; cKuvio **kuviot; int kohdalla; public: cKuviot(int imax) : lkm(0),max_lkm(0),kohdalla(-1) { max_lkm = imax; kuviot = new cKuvio *[max_lkm]; } ~cKuviot(); string lisaa(cKuvio *kuvio) { if ( lkm >= max_lkm ) return "Ei mahu"; kuviot[lkm] = kuvio; lkm++; return ""; } cKuvio *eka_osuma(const cPiste &piste) { kohdalla = -1; return seuraava_osuma(piste); } cKuvio *seuraava_osuma(const cPiste &piste); }; cKuviot::~cKuviot() { for (int i=0; iosuuko(piste) ) return kuviot[kohdalla]; return 0; } //--------------------------------------------------------------------------- class cNaytto { cPiste piste; cKuviot *kuviot; public: cNaytto(cKuviot *ikuviot) : kuviot(ikuviot) {} void kysy_kuviot(); void kysele_pisteita(); void ohjeet() const { cout << "Ohjelmalla tutkitaan osuuko piste johonkin kuvioon joukossa." << endl; } void kiitokset() const { cout << "Kiitoksia!!" << endl; } int kysy_tiedot(cKuvio *kuvio); }; int cNaytto::kysy_tiedot(cKuvio *kuvio) { string nimi = kuvio->getNimi(); string jono; double r; cout << "Anna " << nimi << "n säde>"; getline(cin,jono); if ( jono == "" ) return 1; sscanf(jono.c_str(),"%lf",&r); kuvio->setR(r); cout << "Anna keskipiste >"; getline(cin,jono); if ( jono == "" ) return 1; piste.setAsString(jono); kuvio->setKP(piste); return 0; } void cNaytto::kysy_kuviot() { cKuvio *kuvio; cout << "Syötä kuviot:\n"; while (1 ) { cout << "\n"; cout << " L = lopeta kuvioiden syöttö\n"; cout << " 1 = ympyrä\n"; cout << " 2 = neliö\n"; cout << "\n"; cout << " Valitse kuvio:"; char nappain = odota_nappain("L12",'L',MERKKI_ISOKSI); switch ( nappain ) { case 'L': return; case '1': kuvio = new cYmpyra; break; case '2': kuvio = new cNelio; break; } cout << "\n\n"; if ( !kuvio ) return; if ( kysy_tiedot(kuvio) ) { delete kuvio; return; } string virhe = kuviot->lisaa(kuvio); if ( virhe != "" ) { cout << "Ei voi lisätä: " << virhe << "\n"; delete kuvio; return; } cout << "Lisäsit kuvion " << kuvio->getAsString() << "\n"; } } void cNaytto::kysele_pisteita() { string jono; cout << "\n\n"; while ( 1 ) { cout << "Anna tutkittava piste>"; getline(cin,jono); if ( jono == "" ) return; piste.setAsString(jono); cKuvio *kuvio = kuviot->eka_osuma(piste); if ( !kuvio ) { cout << "Piste " << piste.getAsString() << " ei osu yhteenkään kuvioon!\n"; continue; } do { cout << "Piste " << piste.getAsString() << " osuu kuvioon " << kuvio->getAsString() << "\n"; kuvio = kuviot->seuraava_osuma(piste); } while ( kuvio ); } } //--------------------------------------------------------------------------- #if 1 int main(void) { cKuviot kuviot(6); cNaytto naytto(&kuviot); naytto.ohjeet(); naytto.kysy_kuviot(); naytto.kysele_pisteita(); naytto.kiitokset(); return 0; } #endif