[Graphics Lab Logo Image]  

Home  Up  Feedback  Contents  Search 

Lucrarea nr.9: Obiecte Grafice

[ Prev ] Lucrarea 9 [ Next ]

[Under Construction]

Descriere

Implementare

Aplicatii

 

A.Descriere

1.Definitie

Scenele grafice realizate cu ajutorul calculatorului sunt compuse, in majoritatea cazurilor, din elementele grafice de baza prezentate. De multe ori insa este necesar ca utilizatorul pachetului grafic sa poata avea acces nemijlocit la un grup de elemente grafice de baza pe care sa le trateze ca o unitate de sine statatoare, identificata eventual printr-un nume specific. Acest grup de elemente grafice va putea fi manipulat in mod distinct fata de celelalte elemente. Un astfel de grup va fi numit in cele ce urmeaza obiect grafic. Elaborarea programelor de grafica pe calculator, utilizand conceptul de obiect grafic va fi numita programare orientata pe obiecte grafice.

Un obiect grafic incapsuleaza mai multe elemente grafice de baza intr-o singura unitate, fiind format din liste de elemente grafice. O scena grafica consta in general din mai multe obiecte grafice :

                                             

Divizarea unei scene grafice in obiecte grafice este arbitrara, fiind la latitudinea utilizatorului.

Obiectele grafice se proiecteaza, in general, pe rand unul cate unul intr-un spatiu de coordonate propriu, iar apoi  sunt stocate intr-un fisier pe disc. Construirea obiectelor grafice se poate face in regim interactiv, daca sistemul prevede acesta posibilitate, sau prin descrierea lui intr-un fisier disc utilizand un editor de texte, urmand desigur, schita grafica reala si folosind o codificare convenabila pentru descrierea elementelor grafice de baza. Fisierele contin descrierile obiectelor grafice pot fi privite ca biblioteci grafice. Aceste fisiere vor avea extensia SYM. Pentru realizarea scenei grafice finale, aceste biblioteci vor fi consultate si vor fi selectate in mod secvential obiectele grafice necesare.

Elaborarea pachetelor grafice care utilizeaza programarea bazata pe obiecte grafice presupune luarea a doua decizii:

  • stabilirea setului de elemente grafice de baza ce vor intra in componenta obiectelor grafice.
  • modul de descriere al acestora prin structuri de date interne adecvate.

In aceasta lucrare vom considera ca obiectele grafice pot fi constituite din urmatoarele obiecte grafice de baza: segmentul de dreapta, cercul si arcul de cerc. Aceasta alegere reprezinta o optiune minimala. Ea poate fi imbogatita prin adaugarea la setul minim a altor elemente grafice de baza ca: dreptunghi, poligon, curbele Bezier, curbele spline, etc.

Structurile de date necesare pentru stocarea elementelor grafice de baza pot fi statice sau dinamice. Obiectele grafice sunt entitati dinamice care isi modifica frecvent componenta. Structurile de date statice sunt simple dar restrictive. Mult mai eficiente, structurile dinamice pot fi realizate in Pascal utilizand listele inlantuite si tipul inregistrare cu variante insa cu un efort de programare mai consistent.

Alegerea parametrilor pentru definirea elementelor grafice de baza s-a facut avand in vedere necesitatea de a manipula aceste obiecte, in special prin transformari liniare, intr-un mod uniform.

Un set minim de operatii executate asupra obiectelor grafice sunt:

  1. reprezentarea
  2. incarcarea
  3. salvarea
  4. transformarea
  5. instantierea

2. Incarcarea si salvarea obiectelor grafice

Preluarea descrierii obiectelor grafice din fisiere disc respectiv salvarea lor ca operatie opusa presupune definirea prealabila a modului de structurare a fisierului extern. Obiectele grafice vor fi stocate in fisiere tip TEXT ceea ce da posibilitatea crearii sau editarii obiectului cu ajutorul unui editor de texte. In cadrul fisierului un obiect grafic se descrie in forma urmatoare:

        NUME 'nume_obiect_grafic' (numele obiectului grafic)
        SEG   x1 y1 x2 y2
        CERC  x1 y1 x2 y2
        ARC   x1 y1 x2 y2 x3 y3
        END

Coordonatele xi, yi sunt date intr-un spatiu de coordonate propriu al obiectului.

Pentru descrierea elementelor, primul caracter este suficient, deci se permite si utilizarea formei:

        N 'nume_obiect_grafic'
        S x1 y1 x2 y2
        C x1 y1 x2 y2
        A x1 y1 x2 y2 x3 y3
        E

De exemplu:

                     

         NUME 'TRIUNGHI'
         SEG 75 100 50 50
         SEG 50 50 100 50
         SEG 100 50 75 100
         END

Operatia de incarcare are ca efect citirea descrierii obiectului urmator din fisierul extern si transferarea ei in zona de date a aplicatiei. Obiectul incarcat devine obiect grafic curent. Operatia de salvare adauga descrierea obiectului grafic curent la sfarsitul fisierului extern.

3. Reprezentarea obiectelor grafice

Reprezentarea unui obiect grafic realizeaza transpunerea in ecran a elementelor grafice care il compun. Deoarece orice obiect grafic este construit din liste formate din elemente grafice de baza, procedura de reprezentare va trasa toate segmentele de dreapta apeland procedura arc.

Procedura de reprezentare va transpune in ecran pe rand, obiectele grafice ale unei scene grafice. Obiectul grafic asupra caruia se opereaza la un moment dat se numeste obiect grafic curent.

 

B. Implementare

In cadrul lucrarii se vor implementa structurile de date, procedurile si functiile necesare pentru realizarea operatiilor:

  • incarcarea descrierii obiectelor grafice din fisierele disc
  • salvarea descrierii obiectelor grafice in fisiere disc
  • reprezentarea obiectelor grafice
/*======================================================================*/
/* G2Dobiecte.h                                                         */
/*======================================================================*/

/* Rutine exportate ----------------------------------------------------*/

/*
 * Deschide fisierul care contine descrierea obiectelor grafice.
 * la un moment dat poate fi deschis un singur fisier de intrare.
 */
extern void deschide_fisier_intrare (char *nume_fisier_i);


/*
 * Deschide fisierul in care se salveaza descrierea obiectului grafic curent.
 * La un moment dat poate fi deschis un singur fisier de iesire, altul
 * decat fisierul de intrare.
 */
extern void deschide_fisier_iesire (char *nume_fisier_e);


extern void inchide_fisier_intrare (void);


extern void inchide_fisier_iesire (void);


/*
 * Transfera descrierea urmatorului obiect grafic din fisierul de intrare
 * in obiectul grafic curent.
 */
extern void incarca_obiect (void);


/*
 * Transfera descrierea obiectului grafic curent la sfarsitul fisierului de 
 * iesire.
 */
extern void salveaza_obiect (void);


/*
 * Transpune pe ecran descrierea obiectului grafic curent.
 */
extern void display_obiect (void);

/*======================================================================*/
/* End of G2Dobiecte.h                                                  */
/*======================================================================*/
/*======================================================================*/
/* G2Dobiecte.c                                                         */
/*======================================================================*/

#include <stdio.h>
#include <string.h>
#include <ctype.h>


/* Tipuri si Structuri Private -----------------------------------------*/

/* Numarul maxim de elemente grafice de baza admise */
#define MAX_SEG 20
#define MAX_CERC 20
#define MAX_ARC 20

typedef struct _tip_segment
{
   double x1, y1;
   double x2, y2;
} tip_segment;

typedef struct _tip_cerc
{
   double x1, y1;
   double x2, y2;
} tip_cerc;

typedef struct _tip_arc
{
   double x1, y1;
   double x2, y2;
   double x3, y3;
} tip_arc;


typedef struct _tip_obiect_grafic
{
   char nume[40];

   int nr_seg;
   tip_segment seg[MAX_SEG];

   int nr_cerc;
   tip_cerc crc[MAX_CERC];

   int nr_arc;
   tip_arc arce[MAX_ARC];

} tip_obiect_grafic;


static tip_obiect_grafic ob_gr_crt;

static char nume_f_i[1024];
static FILE *fisier_intrare = NULL;
static FILE *fisier_iesire = NULL;

/* Rutine Publice ------------------------------------------------------*/

/*
 * Deschide fisierul care contine descrierea obiectelor grafice.
 * la un moment dat poate fi deschis un singur fisier de intrare.
 */
void 
deschide_fisier_intrare (char *nume_fisier_i)
{
   if (NULL != fisier_intrare)
   {
      fprintf (stderr, "\nFisierul de intrare este deja deschis.\n");
      return;
   }

   /* memoreaza numele pentru verificare fisier iesire */
   strcpy (nume_f_i, nume_fisier_i);

   /* incearca deschidere in citire */
   fisier_intrare = fopen (nume_fisier_i, "r");
   if (NULL == fisier_intrare)
   {
      fprintf (stderr, "\nNu pot deschide in citire ");
      perror (nume_fisier_i);
   }
} /* deschide_fisier_intrare */


/*
 * Deschide fisierul in care se salveaza descrierea obiectului grafic curent.
 * La un moment dat poate fi deschis un singur fisier de iesire, altul
 * decat fisierul de intrare.
 */
void 
deschide_fisier_iesire (char *nume_fisier_e)
{
   if (NULL != fisier_iesire)
   {
      fprintf (stderr, "\nFisierul de iesire este deja deschis.\n");
      return;
   }

   /* incearca deschidere in append */
   fisier_iesire = fopen (nume_fisier_e, "a");
   if (NULL == fisier_iesire)
   {
      fprintf (stderr, "\nNu pot deschide in scriere ");
      perror (nume_fisier_e);
   }
} /* deschide_fisier_iesire */


void 
inchide_fisier_intrare ()
{
   if (NULL == fisier_intrare)
   {
      fprintf (stderr, "\nFisierul de intrare este deja inchis.\n");
      return;
   }

   fclose (fisier_intrare);
   fisier_intrare = NULL;
} /* inchide_fisier_intrare */


void 
inchide_fisier_iesire ()
{
   if (NULL == fisier_iesire)
   {
      fprintf (stderr, "\nFisierul de iesire este deja inchis.\n");
      return;
   }

   fclose (fisier_iesire);
   fisier_iesire = NULL;
} /* inchide_fisier_iesire */


/*
 * Transfera descrierea urmatorului obiect grafic din fisierul de intrare
 * in obiectul grafic curent.
 */
void 
incarca_obiect ()
{
   int gata;
   char buffer[256];
   char *chPtr;
   int i;

   /* initializeaza ob_gr_crt */
   ob_gr_crt.nr_seg = 0;
   ob_gr_crt.nr_cerc = 0;
   ob_gr_crt.nr_arc = 0;
   ob_gr_crt.nume[0] = '\0';

   if (NULL == fisier_intrare)
   {
      fprintf (stderr, "\nFisierul de intrare nu este deschis.\n");
      return;
   }

   gata = FALSE;

   while (!gata)
   {
      /* citeste o linie */
      if (NULL == fgets (buffer, 256, fisier_intrare))
      {
         /* sfarsit de fisier */
         return;
      }

      /* fgets() nu elimina newline de la sfarsitul sirului */
      if (buffer[strlen(buffer)-1] == '\n')
      {
         buffer[strlen(buffer)-1] = '\0';
      }

      chPtr = buffer;
      /* sare peste eventuale spatii de la inceput */
      while ((*chPtr) && isspace(*chPtr))
         chPtr++;

      if (!(*chPtr))
      {
         /* ignora liniile goale */
         continue; /* while */
      }

      /* determina cuvantul cheie */
      if (0 == strncmp (chPtr, "NUME", 4))
      {
         chPtr += 4;
         /* sare peste eventuale spatii de la inceput */
         while ((*chPtr) && isspace(*chPtr))
            chPtr++;
         strcpy (ob_gr_crt.nume, chPtr);
      }
      else if (0 == strncmp (chPtr, "SEG", 3))
      {
         i = ob_gr_crt.nr_seg;
         sscanf (chPtr+3, "%lf%lf%lf%lf",
            &(ob_gr_crt.seg[i].x1), &(ob_gr_crt.seg[i].y1), 
            &(ob_gr_crt.seg[i].x2), &(ob_gr_crt.seg[i].y2));
         ob_gr_crt.nr_seg++;
      }
      else if (0 == strncmp (chPtr, "CERC", 4))
      {
         /* citire cerc */
      }
      else if (0 == strncmp (chPtr, "ARC", 3))
      {
         /* citire arc */
      }
      else if (0 == strncmp (chPtr, "END", 3))
      {
         gata = TRUE;
      }
   }
} /* incarca_obiect */


/*
 * Transfera descrierea obiectului grafic curent la sfarsitul fisierului de 
 * iesire.
 */
void 
salveaza_obiect ()
{
   int i;

   if (NULL == fisier_iesire)
   {
      fprintf (stderr, "\nFisierul de iesire nu este deschis.\n");
      return;
   }

   fprintf (fisier_iesire, "NUME %s\n", ob_gr_crt.nume);

   for (i = 0; i < ob_gr_crt.nr_seg; i++)
   {
      fprintf (fisier_iesire, "SEG %lf %lf %lf %lf\n",
         ob_gr_crt.seg[i].x1, ob_gr_crt.seg[i].y1,
         ob_gr_crt.seg[i].x2, ob_gr_crt.seg[i].y2);
   }

   for (i = 0; i < ob_gr_crt.nr_cerc; i++)
   {
      fprintf (fisier_iesire, "CERC %lf %lf %lf %lf\n",
         ob_gr_crt.crc[i].x1, ob_gr_crt.crc[i].y1,
         ob_gr_crt.crc[i].x2, ob_gr_crt.crc[i].y2);
   }

   for (i = 0; i < ob_gr_crt.nr_arc; i++)
   {
      fprintf (fisier_iesire, "ARC %lf %lf %lf %lf\n",
         ob_gr_crt.arce[i].x1, ob_gr_crt.arce[i].y1,
         ob_gr_crt.arce[i].x2, ob_gr_crt.arce[i].y2,
         ob_gr_crt.arce[i].x3, ob_gr_crt.arce[i].y3);
   }

   fprintf (fisier_iesire, "END\n");
} /* salveaza_obiect */


/*
 * Transpune pe ecran descrierea obiectului grafic curent.
 */
void 
display_obiect ()
{
   int i;
   double x1, y1;
   double x2, y2;
   double x3, y3;
   double xc, yc;
   double r;
   double th1, th2;

   for (i = 0; i < ob_gr_crt.nr_seg; i++)
   {
      x1 = ob_gr_crt.seg[i].x1; y1 = ob_gr_crt.seg[i].y1;
      x2 = ob_gr_crt.seg[i].x2; y2 = ob_gr_crt.seg[i].y2;
      linie_2d (x1, y1, x2, y2);
   }
   for (i = 0; i < ob_gr_crt.nr_cerc; i++)
   {
      x1 = ob_gr_crt.crc[i].x1; y1 = ob_gr_crt.crc[i].y1;
      x2 = ob_gr_crt.crc[i].x2; y2 = ob_gr_crt.crc[i].y2;
      conversie_cerc (x1, y1, x2, y2, &xc, &yc, &r);
      cerc (xc, yc, r);
   }
   for (i = 0; i < ob_gr_crt.nr_arc; i++)
   {
      x1 = ob_gr_crt.arce[i].x1; y1 = ob_gr_crt.arce[i].y1;
      x2 = ob_gr_crt.arce[i].x2; y2 = ob_gr_crt.arce[i].y2;
      x3 = ob_gr_crt.arce[i].x3; y3 = ob_gr_crt.arce[i].y3;
      conversie_arc (x1, y1, x2, y2, x3, y3, &xc, &yc, &r, &th1, &th2);
      arc (xc, yc, r, th1, th2);
   }
} /* display_obiect */


/*======================================================================*/
/* End of G2Dobiecte.c                                                  */
/*======================================================================*/

Download G2Dobiecte.h, G2Dobiecte.c.

C. Aplicatii

Exemplu de aplicatie:

#include "G2Dobiecte.h"
#include "G2Dnucleu.h"


int
my_main (int argc, char *argv[])
{
   InitG2Dnucleu ();

   deschide_fisier_intrare ("Simbol.sym");

   /* preia primul obiect grafic */
   incarca_obiect ();

   /* definiti corespunzator fereastra ! */
   display_obiect ();

   deschide_fisier_iesire ("Simbol.bak");

   /* salveaza primul obiect grafic */
   salveaza_obiect ();

   /* preia al doilea obiect grafic */
   incarca_obiect ();

   /* definiti corespunzator fereastra ! */
   display_obiect ();

   inchide_fisier_intrare ();
   inchide_fisier_iesire ();

   return (0);

} /* my_main */

1. Implementati modulul G2Dobiecte.

2. Construiti cu ajutorul unui editor de texte, cate un fisier de tip text corespunzator obiectelor urmatoare, iar apoi incarcati-le si vizualizati-le.

 

3. Implementati tipurile si structurile de date dinamice aferente obiectelor grafice si modificati corespunzator procedurile. Creati unitatea G2Dobd.

 

 

Home ][ Up ][ Previous ][ Next ]

Send mail to sorin@aspc.cs.utt.ro with questions or comments about this web site.
Copyright © 2000 Graphics Laboratory
Last modified: January 25, 2000