Kirjautuminen

Haku

Tehtävät

Keskustelu: Ohjelmointikysymykset: C++: Viivan pisteiden koordinaatit

Sivun loppuun

alottelijaa [18.05.2008 22:36:26]

#

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.

Antti Laaksonen [18.05.2008 22:47:44]

#

Sopivia viivalle osuvia koordinaattipareja voi laskea esim. tällä algoritmilla:

http://fi.wikipedia.org/wiki/Bresenhamin_algoritmi

Metabolix [18.05.2008 22:58:28]

#

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);
}

jormi [19.05.2008 08:34:29]

#

Löytyykkö ohjelmasi kirjastosta 'line'-funktiota. JVM

alottelijaa [19.05.2008 11:48:40]

#

Mikä on line funktio? ja ei oo omia kirjastoja jos niitä tarkotit.

DumTom [19.05.2008 12:15:35]

#

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);
          }
       }
   }
}

alottelijaa [19.05.2008 17:36:59]

#

Juu tuon tapainen löytyy :)

alottelijaa [19.05.2008 23:14:42]

#

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

Metabolix [21.05.2008 18:35:53]

#

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.

alottelijaa [22.05.2008 16:42:17]

#

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 :]

Metabolix [22.05.2008 16:54:49]

#

Merkin muuttujatyyppi on char.

void tulosta(char merkki) {
  std::cout << merkki;
}

tulosta('H');
tulosta('e');
tulosta('i');
tulosta('!');
tulosta('\n'); // Rivinvaihto

alottelijaa [23.05.2008 20:15:54]

#

Ok kiitos paljon! *Aihe on suljettu*


Sivun alkuun

Vastaus

Aihe on jo aika vanha, joten et voi enää vastata siihen.

Tietoa sivustosta