1

toujours dans ma quete de defis sur la prog en c de ma cher TI89, j'ai lu (avec attention) le tuto de M Heulin (http://membres.lycos.fr/heulin/3D/Sommaire.html) et j'ai repris ses sources en c pour les utiliser dans TIGCC et donc de faire ses prog de démo sur ma TI89 et ... tout va bien j'ai a peu prés la meme chose que lui (un cube qui tourne).

J'aurai voulu savoir 2 choses:
-c assez lent sur TI donc comment peut-on faire pour "améliorer" la vitesse d'affichage (je pense que le calcul de la rotation y est pour quelque chose aussi non?)

-comment fait-on pour tracer des lignes pour délimiter les faces parce que j'ai beau utiliser les restes de mon cerveau, j'obtiens des lignes n'importe où n'importe comment

N.B.: vous pouvez trouver mes sources pour TIGCC sur http://spomky.com/cube_ti.zip)

2

segments : cherche à "bresenham".

3

c bon pour les segments ;-), je suis revenu en arrière sur le tuto et g trouvé.

pour l'optimisation je vérai plus tard car j'ai un autre petit problème: j'arrive a faire les rotations est les translations mais pas les homotéties (zoom). vous ne savez pas comment faire?

4

je viens d'utiliser extgraph pour tracer mes segments et ca va déja un peu mieux, c deja ca de gagné cool

5

> ben tu cherches dans tes cours de maths une matrice d'homothétie smile

> a ben, je viens de regarder tes sources, c vraiment 100% du heulin smile

1)bon ton probleme principal, c les rotations, pour avoir un truc mieux, faut deja ne pas passer par les floats mais par des int ou char (si c uniquement pour un cube, les char suffiront pour la precision)

en gros, pour avoir tes tableaux de cos & sin, tu fais

char Cos[360], Sin[360];

void Init_Sinus(void)
{
  int i;

  for(i=0;i<360;i++)
  {
    Sin[i]=sin(i*3.1415927 / 180)*(1<<8);
    Cos[i]=cos(i*3.1415927 / 180)*(1<<8);
  }
}


et pour recupérer, tu fais nombre_char*(1>>8)


bon, j'espere que t'as compris le principe la dessus ...

2)ensuite il faut optimiser les calculs de matrice de rotations, tu utilises ici un algo basé sur 15 muls et ca peut descendre a 9 voir même 6 avec une table précalculé de certiains rapports....


3) l'utilisation du modulo (cheeky te fait perdre du tps, il faut mieux faire:

if (xa++ > 360) xa = 0; et pareil pour le reste
(aufait, j'ai changé xa=xa+1 en xa++

6

>le problème est que justement je n'ai aucun cours sur les homothéties (DUT Génie Civiltsss) et reduire de 50% un objet en 3D dépasse mes compétences actuelles (il fut un temps où ...)

>g recopié tel quel et adapté pour que le TIGCC puisse compiler un "truc qui marche". je viens de faire 2, 3 modif et now je peux le faire bouger avec la croix (rien d'extraordinaire en faitgrin)

>les int ca marche pas g qu'un point qui s'affiche et c pareil pour les char.

sinon rien que le fait de changer le modulo ca va un peu mieux; de toute facon je ve pa faire un truc super complexe, j'ai pas le niveau, et en plus c juste histoire de comprendre
merci pour ton aide, je c d'apres ce que tu di qu'on peu optimiser tout cela mais je verrai ca + tard. je vais d'abord chercher de la doc sur les homothéties; chaque choses en son temps cool

7

> le probleme sur les virgules fixes, c que tu t'y prend mal je pense smile n'oublie pas que quand tu multiplie 2 nombre par 256 (1<<8) ben pour l'avoir en normal, il faut faire: nombre*(1>>16) et pas 8,

> pour les homothéties, y'a pleins de tutos sur internet la dessus pis afficher une matrice ici c pas cool smile http://www.google.com wink

8

pour les homothéties c bon g trouvé tout ce qu'il me faut déjàtop

par contre je sêche toujours sur ton histoire de nombre*(1>>16):
si je définis mes liste comme ceci
char Cos[360], Sin[360];

void Init_Sinus(void)
{
  int i;

  for(i=0;i<360;i++)
  {
    Sin[i]=sin(i*3.1415927 / 180)*(1<<8);
    Cos[i]=cos(i*3.1415927 / 180)*(1<<8);
  }
}


Lors de ma rotation je vais appeler matrice[0][0] = Cos[Za]*(1>>8)*Cos[Ya]*(1>>8); non?
si je mets *(1>>16) TIGCC me dit "Right shift count >= width of type"

9

oki, moi j'ai groupé les 2 (1>>8) grin

10

Bon j'ai regroupé et ca me donne ca:
  matrice[0][0] = (Cos[Za]*Cos[Ya])*(1>>16);
  matrice[1][0] = (Sin[Za]*Cos[Ya])*(1>>16);
  matrice[2][0] = (-Sin[Ya])*(1>>8);

  matrice[0][1] = (Cos[Za]*Sin[Ya]*Sin[Xa])*(1>>32) - (Sin[Za]*Cos[Xa])*(1>>16);
  matrice[1][1] = (Sin[Za]*Sin[Ya]*Sin[Xa])*(1>>32) + (Cos[Xa]*Cos[Za])*(1>>16);
  matrice[2][1] = (Sin[Xa]*Cos[Ya])*(1>>16);

  matrice[0][2] = (Cos[Za]*Sin[Ya]*Cos[Xa])*(1>>32) + (Sin[Za]*Sin[Xa])*(1>>16);
  matrice[1][2] = (Sin[Za]*Sin[Ya]*Cos[Xa])*(1>>32) - (Cos[Za]*Sin[Xa])*(1>>16);
  matrice[2][2] = (Cos[Xa]*Cos[Ya])*(1>>16);


mais g un point a l'écran et c toutsick

11

t'as pensé a la projection ?

12

heu... voilà les 2 fonctions concernées

void Rotation(int Xa, int Ya, int Za)
{
  int i;

  matrice[0][0] = (Cos[Za]*Cos[Ya])*(1>>16);
  matrice[1][0] = (Sin[Za]*Cos[Ya])*(1>>16);
  matrice[2][0] = (-Sin[Ya])*(1>>8);

  matrice[0][1] = (Cos[Za]*Sin[Ya]*Sin[Xa])*(1>>32) - (Sin[Za]*Cos[Xa])*(1>>16);
  matrice[1][1] = (Sin[Za]*Sin[Ya]*Sin[Xa])*(1>>32) + (Cos[Xa]*Cos[Za])*(1>>16);
  matrice[2][1] = (Sin[Xa]*Cos[Ya])*(1>>16);

  matrice[0][2] = (Cos[Za]*Sin[Ya]*Cos[Xa])*(1>>32) + (Sin[Za]*Sin[Xa])*(1>>16);
  matrice[1][2] = (Sin[Za]*Sin[Ya]*Cos[Xa])*(1>>32) - (Cos[Za]*Sin[Xa])*(1>>16);
  matrice[2][2] = (Cos[Xa]*Cos[Ya])*(1>>16);


  for(i=0;i<Nb_points;i++)
  {
    Point3D[i].x =   matrice[0][0]*Sommet[i].x
		   + matrice[1][0]*Sommet[i].y
		   + matrice[2][0]*Sommet[i].z;

    Point3D[i].y =   matrice[0][1]*Sommet[i].x
		   + matrice[1][1]*Sommet[i].y
		   + matrice[2][1]*Sommet[i].z;

    Point3D[i].z =   matrice[0][2]*Sommet[i].x
		   + matrice[1][2]*Sommet[i].y
		   + matrice[2][2]*Sommet[i].z;
  }

}

void Projection(void)
{
  int i;

  for(i=0;i<Nb_points;i++)
  {
    Point2D[i].x=(Point3D[i].x<<8)/(Point3D[i].z+Zoff)+Xoff;
    Point2D[i].y=(Point3D[i].y<<8)/(Point3D[i].z+Zoff)+Yoff;
  }
}


13

essaye de jouer avec tes offset pour voir roll

14

g essayé en changeant les 8 de
void Projection(void)
{
  int i;

  for(i=0;i<Nb_points;i++)
  {
    Point2D[i].x=(Point3D[i].x<<[4]8[/4])/(Point3D[i].z+Zoff)+Xoff;
    Point2D[i].y=(Point3D[i].y<<[4]8[/4])/(Point3D[i].z+Zoff)+Yoff;
  }
}

par 16 ou 32 mais sans succès (c bien ca les offset?)

15

nan, Xoff comme offset sur X smile

16

c bon mon cube est revunutoptoptop

Zoff été egal à 400 mais avec 200 tout est bon! merci beaucoup!

Juste un dernier truc et j'arrete:
je définis
// Structure contenant des points en 3D
typedef struct
{
  int x,y,z;
} point3D;

// Structure contenant des points en 2D
typedef struct
{
  int x,y;
} point2D;


// Définition des caractéristiques géométriques de l'objet
point3D Sommet[8];
point3D Point3D[8];
point2D Point2D[8];
int Nb_points = 8;


Sommet, Point3D et Point2D sont définit en variable global mais sont tous de [8] (Nb_points)
Comment les définir tjs en global mais d'une valeur que j'indiquerai par le suite (par saisie ou dans un fichier)?

17

toi aussi tu adores les pointeurs ? smile

point3D *Sommet;

... dans ton prog

Sommet = malloc(Nb_point * sizeof(point3D));
..
free(Sommet);

18

et pour liste de int on fait
int *ma_list;

...
int *ma_list = (int *)malloc(nb_elements * sizeof(int));

free(ma_list);

19

tout a fait

ou ,j'ai pas mis (point3D *) mais c pas mortel avec gcc

20

tout va bien maintenant.
j'ai remis Sin et Cos en double; ça prends plus de place mais ça ne ralenti pas trop le processus.

j'ai changé aussi pas mal de truc: maintenant l'objet à afficher ne se trouve plus dans le prog mais dans un fichier séparé avec une extension particulière.
en fait ça va me servir pour mon projet actuel en basic avec Vertel), c un éditeur graphique (2D + niveau de gris + calques) mais je vais surement l'étendre à un éditeur 2D/3D (histoire de corser "un peu" le projet)

merci quand même pour ton aide très précieusetop

21

si tu veux un conseil, retire vite tes double smile et remet un table de nombres a virgule fixe !

22

une quoi?
si je met des int ca plante, pareil pour des long
les float ne changent rien à la taille

23

s'en fout de la taille ... l'important c la rapidité, et un calcul en flottant c vachement plus lent qu'un calcule en virgule fixe ....

> passe même aux chars en fait (je suis en train de me dire que y'a un tuto en anglais la dessus sur ticalc .. 3D_tutorial, un truc comme ca dans les rubriques 89/92+)

24

je n'a rien trouvé; j'ai eu beau utiliser leur moteur de recherche, me ballader de liens en liens: rien du tout.

si tu veux me modifier ce qu'il y a à modifier y a pas de problèmes parce que je ne saisie pas tout à vrai dire (je sais qu'il faut trouver par soit même mais étant donné le peu de sources sur ce sujet...)

http://spomky.com/cube_ti2.zip pour les sources du prog et http://spomky.com/Objets.89z

25

FPS ?? c ca le plus interesant smile

26

FPS: entre 70 et 90 quand le cube est immobile; entre 10 et 14sick quand il est en mouvement

je pense comprendre pourquoi l'utilisation de *(1<<8) ne marche pas:
j'ai tapé ca sur TIGCC:
#define USE_TI89
#define OPTIMIZE_ROM_CALLS
#define MIN_AMS 100
#define SAVE_SCREEN
#include <tigcclib.h>

void _main(void)
{
  char Sin[10],Cos[10], buffer[50];
  int i;

  for(i=0;i<10;i++)
  {
    Sin[i]=sin(i*3.1415927 / 180)*(1<<8);
    Cos[i]=cos(i*3.1415927 / 180)*(1<<8);
  }

  for(i=0;i<10;i++)
  {
	  sprintf (buffer, "%d , %d , %d", Sin[i]*(1>>8), Cos[i]*(1>>8), Sin[i]*(1>>8) * Cos[i]*(1>>8));
	  ST_helpMsg (buffer);
	  ngetchx();
  }
}


et se qui s'affiche dans le Statut Barre vaut ... 0 , 0 , 0
malheureusement je ne c pa d'ou vien le problemesad et si je résouds ca je pourrai utiliser cette méthode pour mon prog et donc augmenter les FPS

27

-

28

nEUrOne a écrit :
tout a fait
ou ,j'ai pas mis (point3D *) mais c pas mortel avec gcc

C'est parce que c'est du C, pas du C++!
En C, ce transtypage n'est pas nécessaire!
IroS a écrit :
je pense comprendre pourquoi l'utilisation de *(1<<8) ne marche pas:
j'ai tapé ca sur TIGCC:
sprintf (buffer, "%d , %d , %d", Sin[[b][/b]i]*(1>>8), Cos[[b][/b]i]*(1>>8), Sin[[b][/b]i]*(1>>8) * Cos[[b][/b]i]*(1>>8));
et se qui s'affiche dans le Statut Barre vaut ... 0 , 0 , 0

Normal, 1>>8 vaut 0, donc tu calcules:
sprintf (buffer, "%d , %d , %d", Sin[i]*0, Cos[i]*0, Sin[i]*0 * Cos[i]*0);
Oups...
malheureusement je ne c pa d'ou vien le problemesad et si je résouds ca je pourrai utiliser cette méthode pour mon prog et donc augmenter les FPS

sprintf (buffer, "%d , %d , %d", Sin[i]>>8, Cos[i]>>8, (Sin[i]>>8) * (Cos[i]>>8));
avatar
Mes news pour calculatrices TI: Ti-Gen
Mes projets PC pour calculatrices TI: TIGCC, CalcForge (CalcForgeLP, Emu-TIGCC)
Mes chans IRC: #tigcc et #inspired sur irc.freequest.net (UTF-8)

Liberté, Égalité, Fraternité