Pitäisi tehdä ohjelma joka kysyy aloitus- ja lopetuskoordinaatit ja sitten tulostaa "viivan" niiden väliin. Destruktorissa pitäisi pystyä poistamaan viiva.
class viiva ...jotain... gotoxy(x.xy1,x.yy1); cout << x.viiva1; gotoxy(x.xy2,x.yy2); cout << x.viiva1;
Osaan kyllä poimia tällaisia yksittäisiä koordinaatteja mutta miten ihmeessä pystyn piirtämään viivan kahden koordinaatin välille?
void gotoxy(int x, int y) //koordinaatteja varten, netistä poimittu { static HANDLE hStdout = NULL; COORD coord; coord.X = x; coord.Y = y; if(!hStdout) { hStdout = GetStdHandle(STD_OUTPUT_HANDLE); } SetConsoleCursorPosition(hStdout,coord); }
EDIT: viivan voi piirtää vaikka * merkeillä.
EDIT2: Laitoin vielä kaiken varalle gotoxy funktion koodin.
Sopivia viivalle osuvia koordinaattipareja voi laskea esim. tällä algoritmilla:
Aiheesta on keskusteltu ennenkin esimerkiksi aiheessa 16354, Vinon viivan koordinaatit.
Tässä vielä yksi uusi, rekursioon perustuva ratkaisuvaihtoehto, joka voi kylläkin piirtää tietyissä tapauksissa hieman mutkikkaampia viivoja.
struct piste { int x, y; bool operator == (piste const& p2) { return x == p2.x && y == p2.y; } }; void viiva(piste a, piste b) { if (a == b) { // Päätepisteet samat, piirretään tämä yksi piste. piirra(a); // Piste kohtaan (a.x, a.y), tämän jo osaatkin. return; } // Muussa tapauksessa yritetään jakaa viiva kahdeksi lyhyemmäksi: piste c = {(a.x + b.x) / 2, (a.y + b.y) / 2}; if (a == c || b == c) { // "Keskikohta" pyöristyi samaksi kuin toinen pää, joten ei tarvitse jakaa piirra(a); piirra(b); return; } viiva(a, c); viiva(c, b); }
Löytyykkö ohjelmasi kirjastosta 'line'-funktiota. JVM
Mikä on line funktio? ja ei oo omia kirjastoja jos niitä tarkotit.
void PiirraPiste(short x,short y,unsigned char color); /* tämän funktion saat tehdä itse(erilainen käyttöjärjestelmästä riippuen yms..) */ void Line(short left,short top,short right,short bottom,unsigned char c) { short temp,dx,dy,x,y,x_sign,y_sign,flag; dx=abs(right-left);dy=abs(bottom-top); if (((dx>=dy) && (left>right)) || ((dy>dx) && (top>bottom))) { temp=left; left=right; right=temp; temp=top; top=bottom; bottom=temp; } if ((bottom-top) < 0) y_sign=-1;else y_sign=1; if ((right-left) < 0) x_sign=-1;else x_sign=1; if (dx>=dy) { for (x=left,y=top,flag=0;x<=right;x++,flag+=dy) { if (flag>=dx) { flag -=dx; y+=y_sign; } if (y>-1 && x>-1 && x<640 && y<480) { PiirraPiste(x,y,c); } } else { for (x=left,y=top,flag=0;y<=bottom;y++,flag+=dx) { if (flag>=dy) { flag -=dy; x+=x_sign; } if (y>-1 && x>-1 && x<640 && y<480) { PiirraPiste(x,y,c); } } } }
Juu tuon tapainen löytyy :)
Nyt tuli uusi ongelma eteen :(. Onnistun kyllä tekemään janan, mutta janan luonti pitäisi jollain tapaa sijoittaa konstruktoriin ja se pitäisi poistaa destruktorissa. Älkää välittäkö jos on jotain ylimääräistä.. testailin jotain tapoja enkä oo välttämättä pyyhkinyt kaikkien jälkiä koodista. Jos koodi on liian pitkä joku mod voi karsia turhia kohtia.
#include <iostream> #include <cmath> #include <windows.h> #include <conio.h> using namespace std; class viiva { public: int x1,y1,x2,y2; viiva(); ~viiva(); void Bresenham(viiva x); void Gotoxy(int x, int y); int Piirra(viiva x); }; void Bresenham(viiva x); int Piirra(viiva x); void Gotoxy(int x, int y); int main() { viiva x; Bresenham(x); //Bresenham(x); getchar(); //system("PAUSE"); } void Bresenham(viiva x) //algoritmi viivan piirtämiseen { int dx = std::abs(x.x2 - x.x1) << 1; int dy = std::abs(x.y2 - x.y1) << 1; signed char ix = x.x2 > x.x1?1:-1; signed char iy = x.y2 > x.y1?1:-1; Piirra(x); if (dx >= dy) { int virhe = dy - (dx >> 1); while (x.x1 != x.x2) { if (virhe >= 0) { if (virhe || (ix > 0)) { x.y1 += iy; virhe -=dx; } } x.x1 += ix; virhe += dy; Piirra(x); } } else { int virhe = dx - (dy >> 1); while (x.y1 != x.y2) { if (virhe >= 0) { if (virhe || (iy > 0)) { x.x1 += ix; virhe -= dy; } } x.y1 += iy; virhe += dx; Piirra(x); } } } viiva::viiva() { x1 = 3; y1 = 5; x2 = 8; y2 = 5; void Bresenham(); } viiva::~viiva() { } int Piirra(viiva x) { char nakki = { '*' }; Gotoxy(x.x1,x.y1); cout << nakki; } void Gotoxy(int x, int y) //koordinaatteja varten { static HANDLE hStdout = NULL; COORD coord; coord.X = x; coord.Y = y; if(!hStdout) { hStdout = GetStdHandle(STD_OUTPUT_HANDLE); } SetConsoleCursorPosition(hStdout,coord); }
Pala tehtävänannosta: Luokan konstruktorissa määritellään viivan alku-ja loppupisteen koordinaatit sekä
piirretään viiva. Destruktorissa pyyhitään viiva pois
Laita piirtofunktiolle parametrina, mitä merkkiä käyttäen piirto tehdään. Muodostimessa voit sitten kutsua piirtofunktiota haluamallasi piirtomerkillä (esim. '*'), ja tuhoajassa voit kutsua samaa funktiota välilyönnillä, jolloin jana pyyhkiytyy pois.
Jäsenfunktioille ei pidä antaa viivaa itseään parametrina. Kannattaa ehkä tuon olio-ohjelmointipuolen puitteissa paneutua johonkin aihetta käsittelevään oppaaseen, jotta selviää, kuinka jäsenfunktioita oikein käytetään.
Ehdin ratkaista pulman jo (huonommalla tavalla tietenkin), mutta miten funktiolle voi laittaa parametrinä yksittäisiä merkkejä? kun etin netistä löydän vain tavallisia int funktio(int abc) tyylisiä ohjeita. Seuraavan viestin jälkeen tämän voi lopettaa :]
Merkin muuttujatyyppi on char.
void tulosta(char merkki) { std::cout << merkki; } tulosta('H'); tulosta('e'); tulosta('i'); tulosta('!'); tulosta('\n'); // Rivinvaihto
Ok kiitos paljon! *Aihe on suljettu*
Aihe on jo aika vanha, joten et voi enää vastata siihen.