[Graphics Lab Logo Image] Home  Up  Feedback  Contents  Search 

Lucrarea nr.13:

Obiecte Grafice 3D

[ Prev ] Lucrarea 13 [ Next ]

[Under Construction]

Descriere

Implementare

Aplicatii

A.Descriere

Un corp poliedral poate fi modelat ca o lista de fatete plane poligonale. Un corp ale carui suprafete exterioare sunt curbe poate fi aproximat printr-o lista de poligoane generate pornind de la puncte ale suprafetei. Aproximarea poate fi imbunatatita desigur prin marirea numarului de poligoane care "acopera" suprafata exterioara a corpului. Aceasta forma de modelare a corpurilor poarta denumirea de reprezentare prin retea de poligoane (poligon-mesh).

Fiecare fateta poligonala plana a modelului corpului este definita de o lista de puncte din spatiul obiect numita lista de vertex-uri, si de o serie de atribute precum vizibilitatea, culoarea, textura, etc.

Structurile de date necesare reprezentarii unui corp pot fi statice sau dinamice. In cele ce urmeaza vom prezenta o metoda de reprezentare care utilizeaza structuri de date statice.

Fiecarui corp component al unei scene grafice 3D i se asociaza o tabela de puncte care contine valorile coordonatelor x, y, z ale tuturor vertex-urilor care compun fatetele poligonale plane ale modelului. Aceste valori sunt date in general relativ la un sistem de coordonate propriu.

Fiecare fateta poligonala va cita cate un index in tabela punctelor pentru fiecare vertex din componenta sa.

Identificarea unui corp se face printr-un nume simbolic. Vom considera ca atribute ale corpului culoarea si matricea de transformare.

Tabela de puncte, lista de poligoane, numele si atributele formeaza o structura de date care implementeaza un obiect grafic 3D.

La randul lor corpurile formeaza o lista de corpuri componente ale unui grup de corpuri componente ale unui grup de corpuri (scena grafica 3D). In aceasta forma se pot descrie structuri ierarhice de corpuri si grupuri de corpuri de orice nivel.

In mod evident, pachetul grafic trebuie sa puna la dispozitie un set de operatii (proceduri si functii) pentru crearea si manipularea acestor structuri de date, de exemplu:

  • preluarea descrierii obiectelor 3D din fisiere externe
  • salvarea descrierii obiectelor 3D din fisiere externe
  • reprezentarea grafica pe dispozitivele de iesire
  • transformari geometrice
  • instantierea obiectelor grafice 3D

Descrierea obiectelor se preia din fisiere text, realizate fie prin utilizarea unui editor de texte, fie ca urmare a operatiilor de salvare. Aceste fisiere (avand, de exemplu, extensia .SYM) pot avea structura urmatoare:

 <nume_obiect>
 <nr_puncte in tabela de puncte: n> <culoarea>
 <tabela de puncte>  {cate un punct pe o linie}
  x1 y1 z1
  x2 y2 z2
  xn yn zn
 <definitie poligon 1>
 {sub forma p k i1 i2 i3 ... ik}
 <definitie poligon 2>
 <definitie poligon m>
 e {sfarsit definitie obiect}

Aceasta structura poate fi repetata in cadrul aceluiasi fisier pentru mai multe corpuri. De exemplu pentru definirea unui cub cu un colt tesit, avand latura de 10 unitati si centrul in punctul C(5,5,5), avem:

 

Vertexurile din lista de poligoane se vor specifica intr-o ordine inversa acelor de ceasornic atunci cand se parcurge fateta, privita dinspre observator.

Pentru obtinerea scenelor dorite, corpurile trebuie pozitionate in spatiu ceea ce implica transformari 3D asupra lor. Aceste transformari se pot realiza atat la nivel individual cat si ca grup.

B. Implementare

In cadrul lucrarii se vor implementa structurile de date si operatiile care permit definirea si manipularea obiectelor grafice 3D. Acestea se vor include in unitatea G3D_OBIECTE.

/*======================================================================*/
/* G3Dobiecte.h                                                         */
/*======================================================================*/

/* 
 * Preia descrierea unei scene grafice 3D din fisierul fis_descriere 
 */
extern void incarca (char *fis_descriere);

/*
 * Reprezinta pe ecran obiectul grafic 3D cu numele nume_obiect
 */
extern void display_obiect (char *nume_obiect);

/*
 * Reprezinta pe ecran intregul grup de obiecte 3D care
 * formeaza scena grafica 
 */
extern void display_grup (void);

/*
 * Aplica obiectului grafic nume_obiect o translatie cu param. tx, ty, tz
 */
extern void translatie_obiect (char *nume_obiect, double tx,
                               double ty, double tz);

/*
 * Aplica intregului grup o translatie cu param. tx, ty, tz
 */
extern void translatie_grup (double tx, double ty, double tz);

/*
 * Aplica obiectului grafic nume_obiect o rotatie cu unghiul fi (in grade)
 * in jurul axei determinate de vectorii de pozitie v1, v2 in sens
 * trigonometric privind in directia v1-v2
 */
extern void rotatie_obiect (char *nume_obiect, vector v1, vector v2,
                            double fi);

/*
 * Aplica intregului grup de obiecte o rotatie cu unghiul fi (in grade)
 * in jurul axei determinate de vectorii de pozitie v1, v2 in sens
 * trigonometric privind in directia v1-v2
 */
extern void rotatie_grup (vector v1, vector v2, double fi);

/*
 * Aplica obiectului grafic nume_obiect o scalare cu parametrii
 * sx, sy, sz relativ la punctul a carui vector de pozitie este v
 */
extern void scalare_obiect (char *nume_obiect, vector v,
                            double sx, double sy, double sz);

/*
 * Aplica intregului grup de obiecte o scalare cu parametrii sx, sy, sz
 * relativ la punctul a carui vector de pozitie este v
 */
extern void scalare_grup (vector v, double sx, double sy, double sz);

/*======================================================================*/
/* End of G3Dobiecte.h                                                  */
/*======================================================================*/
/*======================================================================*/
/* G3Dobiecte.c                                                         */
/*======================================================================*/
#include <stdio.h>
#include <math.h>
#include <string.h>

#include "Graph.h"
#include "G2Dprimitive.h"
#include "G3Dvizual.h"
#include "G3Dvector.h"
#include "G3Dmatrice.h"
#include "G3Dtransformari.h"

/* 
 * Date private
 */
#define TRUE 1
#define FALSE 0

#define MAXT 20
#define MAXV 20
#define MAXP 20
#define MAXO 10 /* dimensiunile tabelelor */

typedef punct_3D tabela_vertex[MAXT];
typedef struct _poligon_3D 
{
  int np;
  int index[MAXT];
} poligon_3D;
typedef poligon_3D tabela_poligoane[MAXP];
typedef struct _obiect_3D 
{
  char nume[40];
  int culoareR, culoareG, culoareB;
  MAT3D trmat;
  int ltv;
  int ltp;
  tabela_vertex tv;
  tabela_poligoane tp;
} obiect_3D;

static obiect_3D lista_obiecte[MAXO];
static int nr_obiecte,j;

/* Proceduri publice */

/* 
 * Preia descrierea unei scene grafice 3D din fisierul fis_descriere 
 */
void incarca (char *fis_descriere)
{
  FILE *f;
  int i,j,k,aux;
  int exit;
  char c;

  /* incearca deschidere in citire */
  f = fopen (fis_descriere, "r");
  if (NULL == f)
  {
    fprintf (stderr, "\nNu pot deschide in citire %s",fis_descriere);
    perror(fis_descriere);
  }
  nr_obiecte = 0;
  while (!feof(f)) 
  {
    nr_obiecte++;
    id_mat (lista_obiecte[nr_obiecte-1].trmat); /* transformare identitate */ 
    if (fscanf (f, "%s", lista_obiecte[nr_obiecte-1].nume) !=1 )
    {
      fprintf (stderr, "\nNu pot citi din fis. nume obiect! ");
      fclose(f);
      return ;
    }
    if (fscanf (f, "%d%d%d%d", 
                &lista_obiecte[nr_obiecte-1].ltv, 
                &lista_obiecte[nr_obiecte-1].culoareR, 
                &lista_obiecte[nr_obiecte-1].culoareG, 
                &lista_obiecte[nr_obiecte-1].culoareB) != 4)
    {
      fprintf (stderr, "\nNu pot citi din fis. nr puncte si culoarea! ");
      fclose(f);
      return ;
    }
    for ( i = 0; i < lista_obiecte[nr_obiecte-1].ltv; i++)
      if (fscanf (f, "%lf%lf%lf",
                  &lista_obiecte[nr_obiecte-1].tv[i].x, 
                  &lista_obiecte[nr_obiecte-1].tv[i].y, 
                  &lista_obiecte[nr_obiecte-1].tv[i].z) != 3)
      {
        fprintf (stderr, "\nNu pot citi din fis. x,y,z pt tv! ");
        fclose(f);
        return ;
      }
    exit = FALSE;
    lista_obiecte[nr_obiecte-1].ltp = 0;
    while (!exit)
    {
      do {
        fscanf(f,"%c",&c);
      } while (c == ' ' || c == '\n' || c == '\t');
      switch (c) {
      case 'e': 
        exit = TRUE;
        break;
      case 'p':
        lista_obiecte[nr_obiecte-1].ltp++;
        fscanf(f,"%d",&aux);
        lista_obiecte[nr_obiecte-1].tp[lista_obiecte[nr_obiecte-1].ltp].np = aux;
        for (i = 0; i < aux; i++)
        { 
          fscanf (f, "%d",
            &lista_obiecte[nr_obiecte-1].tp[lista_obiecte[nr_obiecte-1].ltp].index[i]);
        } 
      }
    } /* while */
  } /* while */
  fclose(f);
} 

/*
 * Determina indexul in lista de obiecte pentru obiectul nume_obiect. In caz
 * de esec returneaza valoarea 0
 */
int identifica(char *nume_obiect)
{
  int i;
  int exit;

  i = 1;
  exit = FALSE;
  while (i < nr_obiecte && !exit)
    if (!strcmp (lista_obiecte[i].nume, nume_obiect))
      exit = TRUE;
    else
      i++;
  if (exit)
    return i;
  else
    return 0;
}


/*
 * Reprezinta pe ecran obiectul grafic 3D cu numele nume_obiect
 */
void display_obiect (char *nume_obiect)
{
  int i, j, k, indice;
  punct_3D ptran1, ptran2, *pinit;

  indice = identifica(nume_obiect);
  if (indice > 0)
  {
    setRGBcolor (lista_obiecte[indice].culoareR,
                 lista_obiecte[indice].culoareG,
                 lista_obiecte[indice].culoareB);
    /* generare fatete poligonale */
    for (i = 0; i < lista_obiecte[indice].ltp; i++)
    {
      k = lista_obiecte[indice].tp[i].index[1];
      pinit = &lista_obiecte[indice].tv[k];
      /* aplica matricea curenta de transformare */
      transforma_punct (*pinit, lista_obiecte[indice].trmat, &ptran1);
      for (j = 0; j < lista_obiecte[indice].tp[i].np; j++)
      {
        k = lista_obiecte[indice].tp[i].index[j];
        pinit = &lista_obiecte[indice].tv[k];
        /* aplica matricea curenta de transformare */
        transforma_punct (*pinit, lista_obiecte[indice].trmat, &ptran2);
        linie_3D (ptran1, ptran2);
        ptran1.x = ptran2.x;
        ptran1.y = ptran2.y; 
        ptran1.z = ptran2.z;
      } /*for j*/
    } /*for i*/
  } /* if */
}

/*
 * Reprezinta pe ecran intregul grup de obiecte 3D care formeaza scena grafica 
 */
void display_grup ()
{
  int i;

  for (i = 0; i < nr_obiecte; i++)
  display_obiect (lista_obiecte[i].nume);
}

/*
 * Aplica obiectului grafic nume_obiect o translatie cu param. tx, ty, tz
 */
void translatie_obiect (char *nume_obiect, double tx, double ty, double tz)
{
  MAT3D trans;

  tran_mat (tx, ty, tz, trans);
  transforma_obiect (nume_obiect, trans);
}

/*
 * Aplica intregului grup o translatie cu param. tx, ty, tz
 */
void tranlatie_grup (double tx, double ty, double tz)
{
  int i;
  MAT3D trans;

  tran_mat (tx, ty, tz, trans);
  for (i = 0; i < nr_obiecte; i++)
    transforma_obiect (lista_obiecte[i].nume, trans);
}


/*
 * Aplica obiectului grafic nume_obiect o rotatie cu unghiul fi (in grade)
 * in jurul axei determinate de vectorii de pozitie v1, v2 in 
 * sens trigonometric privind in directia v1-v2
 */
void rotatie_obiect (char *nume_obiect, vector v1, vector v2, double fi)
{
  /* de implementat */
}

/*
 * Aplica intregului grup de obiecte o rotatie cu unghiul fi (in grade)
 * in jurul axei determinate de vectorii de pozitie v1, v2 in 
 * sens trigonometric privind in directia v1-v2
 */
void rotatie_grup (vector v1, vector v2, double fi)
{
  /* de implementat */
}

/*
 * Aplica obiectului grafic nume_obiect o scalare cu parametrii sx, sy, sz
 * relativ la punctul a carui vector de pozitie este v
 */
void scalare_obiect (char *nume_obiect, vector v, 
                     double sx, double sy, double sz)
{
  /* de implementat */
}


/*
 * Aplica intregului grup de obiecte o scalare cu parametrii sx, sy, sz
 * relativ la punctul a carui vector de pozitie este v
 */
void scalare_grup (vector v, double sx, double sy, double sz)
{
  /* de implementat */
}

/*======================================================================*/
/* End of G3Dobiecte.c                                                  */
/*======================================================================*/

Download G3Dobiecte.h, G3Dobiecte.c.

C. Aplicatii

1. Definiti intr-un fisier tip .SYM cubul dat ca exemplu in lucrare si apoi vizualizati-l utilizand diverse tipuri de proiectii.

 2. Sa se defineasca si sa se reprezinte o scena formata din 2 cuburi in urmatoarele pozitii:

  • cub 1 – rotit cu 90º in jurul axei Oz si apoi rotit cu 90º in jurul axei Oy
  • cub 2 – rotit cu 90º in jurul axei Oy si apoi rotit cu 90º in jurul axei Oz

 3. Sa se defineasca si sa se reprezinte o scena formata din 3 cuburi in urmatoarele pozitii:

  • cub 1 – rotit cu 60º in jurul axei Oz si apoi translatat cu 12 unitati pe Oz
  • cub 2 – rotit cu -60º in jurul axei Oz si apoi translatat cu -12 unitati pe Oz
  • cub 3 – rotit cu 90º in jurul axei Ox si apoi translatat cu 12 unitati pe Oy

 

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: