Forums Développement Multimédia

Aller au contenu

optimisation du code

CODE Actionscript

4 réponses à ce sujet

#1 antoine.labbe

    Ceinture Orange

  • Members
  • PipPipPip
  • 39 messages

Posté 09 October 2007 - 10:47 AM

Bonjour,

Dans le cadre d'un projet de dessin de graphes (très grands) je recherche la bonne solution technique pour mon implémentation. Enfin là bonne, tout est relatif, disons plutot la plus optimisée étant donné les calculs massifs que je dois réaliser.

J'explique un peu mon modèle objet avant de rentrer dans les détails, voici un petit schéma UML pour représenter mon actuelle implémentation (en pièce jointe). Le formalisme uml n'est pas le bon, mais vous comprendrez le principe (y'avait pas toutes les relations dans mon logiciel de dessin...).

L'algo implémenté est de type masse-ressort, ultra gourmand en temps de calcul. Vous comprendrez donc mon souci d'optimisation, surtout pour l'affichage (l'algo je peux pas vraiment l'optimiser plus que ca, c'est sa compléxité qui est limitante).


La question que je me pose est la suivante, dans le cadre du dessin du graphe :

Toutes les k itérations de mon algo, j'affiche mon graphe (cad les noeuds et les liaisons avec leurs nouvelles coordonnées).

Actuellement, chaque noeud et chaque liaison ont une propriété drawing de type Sprite.
L'appel de la méthode draw() dans la classe Graph, appelle pour tous les noeuds/liaisons, leur méthode draw() qui dessine le symbole de l'objet et l'ajoute à la display list d'un objet conteneur de type Sprite. Enfin ca marche pas encore mais c'est ce que j'essayais de faire.

Mon probmème est le suivant : à chaque nouvel affichage, il faut aller modifier les coordonnées du noeud/liaison (voir meme autre chose en fonction de l'interaction de l'utilisateur). Pour l'instant, je comptais vider la display list de mon objet qui contenait tous ces symboles, et ré dessiner mes symboles aux nouvelles coordonnées. Mais je me dis que c'est affreusement lourd (vu la masse de noeuds et de liaisons)... D'autant plus que j'aimerai bien implémenter plus tard, une interpolation entre 2 frames d'affichage (il faudrait donc que les objets graphiques soient constants dans le temps).

Quelle solution me conseillez vous ?

Disons que pour l'instant a l'initialisation, je fais des addChild() massif dans mon conteneur d'objets graphiques, à chaque itération je vide les graphiques je redessine. Enfin ca ne marche pas, mais c'est ce que je comptais faire. Est ce que ca vous semble optimisé, ou peu mieux faire ?

merci pour vos participations.

Miniature(s) jointe(s)

  • Image attachée: class_uml.png


#2 d4r0k1n

    Ceinture Jaune

  • Members
  • PipPip
  • 19 messages

Posté 09 October 2007 - 11:06 AM

Bon je t'avouerais que ce n'est pas évident de comprendre d'un coup ce que tu souhaites faire ou les contraintes de ton prog.
Tu ne peux pas plutôt après une modification :

- Uniquement déplacer les noeuds précédemment afficher.

- Déduire les noueuds qui ne sont plus visibles (en dehors de la zone de l'écran) et les virer de la displayList.

- Déduire les nouveaux noeuds (si il y en a) et les ajouter à ta displayList.


Ou sinon si par exemple le nombre de noeuds sur l'axe des abscices ne change pas, tu gardes juste un tableau sur tout tes noeuds affichés et recalcul juste leur position en Y après chaque modification...

Bon j'ai tenté une réponse (comme j'aimerai bien que l'on tente une réponse sur mon post 'Memoire et problemes' ^^ même si je ne suis pas sûr d'avoir bien cerné ton problème...

#3 antoine.labbe

    Ceinture Orange

  • Members
  • PipPipPip
  • 39 messages

Posté 09 October 2007 - 11:38 AM

alors quelques petites précisions :

oui il faut que je déplace les noeuds/liaisons précédement affichés.
pour l'histoire de la visibilité, ils le sont tous (donc ya pas de souci)
pour les nouveaux noeuds c'est bon aussi (c'est du graphe dynamique).

Mais la question est plutot :
pour redessiner un objet qui se trouve dans la display list, il faut mieux le supprimer et en remettre un nouveau, ou on peut le modifier ?

Action Script


public function addToDisplay(doc:DisplayObjectContainer) {
doc.addChild(drawing);
}
public function draw() {
drawing.graphics.clear();
drawing.graphics.lineStyle(1);
drawing.graphics.drawCircle(pos.getX(),pos.getY(),5);
drawing.graphics.endFill();
}

ce que je fais moi, c'est au départ j'ajoute mon objet drawing à la display list via addToDisplay(), ensuite toutes les k itérations j'appel la méthode draw(), mais ca marche pas (enfin sauf à la premier itération)... est ce qu'il faut le remettre dans la display list ? ca serait un peu crade non ?

Modifié par taraxe, 09 October 2007 - 11:39 AM.


#4 d4r0k1n

    Ceinture Jaune

  • Members
  • PipPip
  • 19 messages

Posté 09 October 2007 - 12:43 PM

Comment ça ca ne marche pas ? Si tu redessines la même chose au même endroit tu ne dois pas voir de différence, c'est normal...
Après si entre chaque itération, il n'y a que 'pos' de modifié, oui cela devrait 'bouger'...
Si il n'y a que ça qui change, autant juste déplacer 'drawing'.

Action Script


drawing.x = pos.getX();
drawing.y = pos.getY();

??

#5 antoine.labbe

    Ceinture Orange

  • Members
  • PipPipPip
  • 39 messages

Posté 10 October 2007 - 06:58 AM

oui pour le noeud, mais pour les liaisons il faut les redessiner... c'est vrai que c'est déjà ca de gagné.
Enfin pour l'instant rien ne marche, je vous explique un peu ce qui se passe, j'ai le dessin sur la premiere itération puis plus rien... :

dans la classe GraphViewer (qui étend MovieClip):



Action Script


private function graphLoadingCompleted(evt:Event):void {
myGraph.addToDisplay(this);
...
}


public function computeView(evnt:Event):void {
itcount++;
if (itcount % drawPeriod == 0) myGraph.draw();
myComp.computeGraph();
}



ensuite dans la classe Graph :

Action Script


public function draw():void {
for each (var edge:Edge in edgeList) {
edge.draw();
}
for each (var node:Node in nodeList) {
node.draw();
}
}

public function addToDisplay(doc:DisplayObjectContainer):void {
for each (var edge:Edge in edgeList) {
edge.addToDisplay(doc);
}
for each (var node:Node in nodeList) {
node.addToDisplay(doc);
}
}

puis dans Node et Edge :

Action Script


public function draw():void {
drawing.graphics.clear();
drawing.graphics.lineStyle(1);
drawing.graphics.moveTo(fromNode.getPos().getX(),fromNode.getPos().getY());
drawing.graphics.lineTo(toNode.getPos().getX(),toNode.getPos().getY());
drawing.graphics.endFill();
}

public function addToDisplay(doc:DisplayObjectContainer):void {
doc.addChild(drawing);
}


j'avoue ne pas bien comprendre pourquoi j'ai que la premiere frame.
meme si je redessine les "drawing" a chaque fois, il devraient apparaitre.

Peut etre que c'est parce que je les ajoute à la display list avant de les dessiner ?

avez vous des pistes?
merci




1 utilisateur(s) li(sen)t ce sujet

0 membre(s), 1 invité(s), 0 utilisateur(s) anonyme(s)