Forums Développement Multimédia

Aller au contenu

Courbe en droite

CODE Actionscript

14 réponses à ce sujet

#1 dazfunkyman

    Ceinture Verte

  • Members
  • PipPipPipPip
  • 65 messages

Posté 20 December 2007 - 18:31 PM

Bonjour,
Je souhaite transformer une courbe en droite.
J'ai fait des recherches et je suis tombé sur ce tuto en as2 (ou 1) (je n'ai pas de connaissances historiques très précises sur les anciennes versions d'as)
http://www.zoneflash.net/tutoriaux/t036.php
Et en fait il charge d'un fichier XML l'ensemble des coordonnées de la courbe sur le onEnterFrame et le niveau 100 de ce fichier correspond à la courbe et le niveau 0 à la droite désirée.
Et j'aurai voulu savoir si quelqu'un a déjà utilisé une formule pour effectuer ce genre d'opération retracer une courbe pour qu'elle devienne droite. Et serait-ce plus intéressant au niveau de l'utilisation des ressources que le chargement des coordonnées à partir d'un fichier XML .Si non, comment envisageriez-vous la création du fichier XML.
Si vous ne comprenez pas mes questions j'essayerai d'être un peu plus clair.
Merci d’avance


#2 Logic

  • Honoris
  • PipPipPipPipPipPipPipPip
  • 2733 messages

Posté 20 December 2007 - 20:34 PM

Une segment est une courbe particuliere, a savoir une courbe ou la poigne po est dans l'alignement des 2 sommets p1 et p2.

Si tu as une courbe definie par p1, p2, po, obtenir le segment passant par p1 et p2, mais exprime sous forme de courbe consiste a calculer un nouveau po' conmme suit :

po'.x = p1.x + 0.5(p2.x - p1.x)
po'.y = p1x.y + 0.5(p2.y - p1.y)

En l'occurence ici j'ai choisi de placer la poigne dans l'alignement de p1 et p2 et tres precissement en plein milieu du segment.

Donc pour animer une courbe vers un segment , il suffit de calculer po' et par exemple de faire un tween sur les x et y de celui-ci pour faire une transition douce entre po et po' et retracer la curveTo a chaque fois avec la nouvelle valeur.

Modifié par Logic, 20 December 2007 - 20:36 PM.


#3 tlecoz

  • Honoris
  • PipPipPipPipPipPipPipPip
  • 3486 messages

Posté 20 December 2007 - 21:12 PM

Ou sinon, tu place l'ancre au niveau du premier point, ca marche aussi et le code fait moins mal aux yeux icon_biggrin.gif
(mais bon, c'est vrai que tant qu'a faire, autant avoir l'ancre au centre...)

Action Script


function courbeDroite(graphic:Graphic,pt1:Point,pt2:Point):void{
graphic.moveTo(pt1.x,pt1.y);
graphic.curveTo(pt1.x,pt1.y,pt2.x,pt2.y);
}



#4 Logic

  • Honoris
  • PipPipPipPipPipPipPipPip
  • 2733 messages

Posté 20 December 2007 - 22:47 PM

En fait ya pas une solution meilleure que l'autre. Ca donnera des résultats différents au moment de l'animation car le chemin interpolé que suivra l'ancre/poignée sera different selon ou tu places ta position finale.

Remplacer le 0.5 dans mes 2 formules ci-dessus par une autre valeur comprise entre 0 et 1 permet d'obtenir toutes les solutions pour tracer le segment. D'ailleurs en prenant la valeur 1, on retrouve la solution de tlecoz wink.gif

Voila, a tester.

Modifié par Logic, 20 December 2007 - 22:50 PM.


#5 patrick mantout

    Ceinture Noire

  • Members
  • PipPipPipPipPipPipPip
  • 345 messages

Posté 21 December 2007 - 03:27 AM

Transformer une courbe en suite de droites, cela peut être beaucoup plus complexe.
La méthode que vous expliquez ici, consiste à interpolez entre X départ et X fin avec un pas constant
f(Xdépart) = Y1
f(Xdépart + 0.01) = Y2
f(Xdépart + 0.02) = Y3
....
Pour du calcul primaire, cela est suffisant

Mais il y a plusieurs problèmes
Par exemple, si on se sert de la courbe pour faire une animation, on passe du point (X1, Y1) au point (X2, Y2) au point (X3, Y3) au point ....
Mais la longueur de chacun des segments (pt1, pt2) , (pt2, pt3), (pt3, pt4), .... est différente.
En effet le delta X est toujours le même, mais le delta Y est forcément différente (sinon c'est que l'on interpole une droite)
Donc on va avoir une animation saccadée, bref une horreur.

2eme problème
Si la courbe change énormément de rayon de courbure, il faut changer le pas de l'interpolation en fonction de l'erreur constatée pour chaque segment.
Quand la courbe est presque "droite", le segment va presque "coller" à la courbe et la distance entre la valeur réelle et la valeur interpolée sera très faible donc on est content.
Si maintenant, la courbe, a un rayon de courbure très faible, (si la courbe fait une boucle par exemple) l'erreur peut être très grande.
Une des méthodes pour calculer l'erreur consiste à tracer une normale (c.a.d une perpendiculaire) qui part du milieu du segment de droite que l'on regarde et qui va rejoindre la courbe.
La longueur de ce petit segment est la marge d'erreur. Si l'erreur est trop grande, on diminue le Delta X

Voilà




#6 Logic

  • Honoris
  • PipPipPipPipPipPipPipPip
  • 2733 messages

Posté 21 December 2007 - 06:18 AM

Moi ce que j'explique c'est la base de chez base. Comment animer une bezier quadratique pour qu'elle se "tende". Autrement dit, quand on a une bezier quadratique (p1, p2, po), comment faire varier po pour que la bezier devienne un segment. Ma technique donne la valeur cible po' qui donne le segment (p1, p2, po'), ensuite l'interpolation pour passer de po à po' peut etre complètement arbitraire, (n'importe quelle tween fonctionnera).

Ensuite on peut essayer des cas plus complexes. Supposons donc qu'on a une courbe C plus complexe, c'est à dire un ensemble de k+1 beziers bz0, bz1...,bzk "connectées" les unes aux autres. Plus formellement, ca veut dire que:

bz0.p2 = bz1.p1
bz1.p2 = bz2.p1
...
bzk-1.p2 = bzk.p1
(donc bzn.p2 = bzn+1.p1 pour n variant de 0 à k-1)

Notons que ma definition de la connexion est faible, dans le sens ou on accepte que les tangentes des beziers ne soient pas forcement de la meme pente d'une bezier a l'autre (plus vulgairement, on accepte des cassures), mais pour la suite ca n'aura pas d'incidence car plus nos énoncés sont faibles, plus nos résultats seront généraux.

Donc si on essaie d'appliquer naivement la démarche que j'ai expliqué plus haut à C, ca consistera à l'appliquer sur chacune des beziers composant C, c'est à dire animer les bz0.po, bz1.po, ... bzk.po vers les bz0.po', bz1.po', ... bzk.po' comme indiqué. La au final va se retrouver avec une suite de segments qui donnera l'impression d'une ligne brisée, sauf cas exceptionnel ou les bz0.p1, bz0.p2, bz1.p1, bz1.p2, ... , bzk.p1, pzk.p2 sont bien alignés.

Pour remédier à ce problème, et bien justement on peut faire en sorte d'animer aussi les bz0.p1, bz0.p2, bz1.p1, bz1.p2, ... , bzk.p1, pzk.p2 pour qu'ils deviennent alignés. Pour faire dans le simple, on va se donner comme mission de trouver des points cibles bz0.p2', bz1.p2', ... , pzk-1.p2' de facon a ce qu'ils soient alignés et découpant le segment (bz0.p1, bzk.p2) en sous segments de longueurs égales (on ne touche donc pas aux extrémités de C, seules les points intermédiaires seront animés et on reutilise le fait de départ que bzn.p2 = bzn+1.p1). Donc pour calculer ces points cibles, procéder comme suit :

bzn.p2'.x = n * (bzk.p2.x - bz0.p1.x) / k
bzn.p2'.y = n * (bzk.p2.y - bz0.p1.y) / k

Ensuite si on tween des bzn.p2 vers les bzn.p2' (sans oublier que bzn.p2' = bzn+1.p1' pour n variant de 0 à k-1), nos points vont alors s'aligner bien gentillement. Reste donc à faire en parallèle les tweens des bzn.po vers les bzn.po'. Sauf qu'il y a changement dans la donne car les valeurs cibles bzn.po' sont censées etre tweené pour des valeurs bzn.p1, bzn.p2 qui sont constantes ! Donc la, il faut en fait à chaque itération du tween de bzn.p2 vers les bzn.p2', recalculer des nouveaux bzn.po' qui vont prendre en compte les modifications des points.

Voila, ca c'est une démarche qui vaut ce qu'elle vaut et elle a le mérite de donner quelque bases. Au niveau des défauts, je dirai que le principal provient de la gestion des courbes dans Flash par des beziers quadratic : il est extremement difficile d'animer des courbes complexes (des courbes composées de plusieurs plusieurs beziers connectées) de facon à ce qu'elle soient sans brisure. On retrouve donc le probleme ici dans ma démarche. L'animation va donner lieu à des brisures dans la courbe et ca sera pas joli du tout. Il doit etre possible de contraindre plus fortement les calculs des bzn.po' pour obtenir une continuité d'ordre 2 (donc éviter les cassures) puisque moi j'ai choisi arbitraiement la valeur 0.5 quand je fais po'.x = p1.x + 0.5(p2.x - p1.x) alors qu'en fait toute valeur entre 0 et 1 est permise. Mais là ca me parait monstrueux à calculer, ca n'en vaut pas la chandelle et il vaut mieux à mon avis se doter d'une véritable gestion des beziers cubiques qui elles sont beaucoup plus flexibles (2 poignées de controle) et permettent d'animer des courbes sans cassure beaucoup beacoup plus facilement.

Voilà, je trouve le sujet intéressant, mais ça risque de partir assez loin, donc faudrait peut etre recentrer le débat.

Donc Dazfunkyman, as-tu déjà décidé d'une facon dont tes courbes vont être représentées ? Approximation par des segments de droite ? Une bezier quadratic ? Une bezier cubique ? Une courbe complexe composé de plusieurs quadratiques connectées ? Une courbe complexe composé de plusieurs cibiques connectées ?

Modifié par Logic, 21 December 2007 - 06:23 AM.


#7 Logic

  • Honoris
  • PipPipPipPipPipPipPipPip
  • 2733 messages

Posté 21 December 2007 - 06:29 AM

Citation (patrick mantout @ Dec 21 2007, 02:27 AM) Voir le message
Transformer une courbe en suite de droites, cela peut être beaucoup plus complexe.


Donc oui ca peut etre tres complexe je suis d'accord avec toi. Mais cette complexité dépend pour beaucoup de la façon dont les courbes sont représentées. Donc si tu le veux bien, laissons dazfunkyman nous dire de quelle façon ces courbes sont implémentées, ça nous donnera un fil directeur.

Ou sinon dazfunkyboy, si t'as pas encore commencé l'implémentation, dis le-nous et on devrait arriver à dégoter la façon de procéder qui soit la plus souple.

#8 dazfunkyman

    Ceinture Verte

  • Members
  • PipPipPipPip
  • 65 messages

Posté 21 December 2007 - 08:56 AM

Citation (Logic @ Dec 21 2007, 06:29 AM) Voir le message
Donc oui ca peut etre tres complexe je suis d'accord avec toi. Mais cette complexité dépend pour beaucoup de la façon dont les courbes sont représentées. Donc si tu le veux bien, laissons dazfunkyman nous dire de quelle façon ces courbes sont implémentées, ça nous donnera un fil directeur.

Ou sinon dazfunkyboy, si t'as pas encore commencé l'implémentation, dis le-nous et on devrait arriver à dégoter la façon de procéder qui soit la plus souple.


ok merci les gars!
Je vais en cours ce matin donc j'ai pas le temps de répondre de suite mais j'analyse plus en profondeur vos réponses tal heure et je vous montre la courbe que je souhaite modifier.


#9 dazfunkyman

    Ceinture Verte

  • Members
  • PipPipPipPip
  • 65 messages

Posté 21 December 2007 - 17:24 PM

Je vous ai mis la photo qsur laquelle je souhaite effectuer cette opération.
Plus en détails les 6 dégradés de droite (du blanc au noir) sont les "courbes que je souhaite redresser dans le but de faire disparaitre l'image de gauche (voir courbes.jpg)(Ce serait en fait un menu extensible qui se retracterai sur la gauche de l'écran en ne laissant que les 4 rectangles du blanc au noir.(voir droites.jpg)
Et en fait, vu qu'il y a 6 courbes (6 dégradés) je sais pas si le calcul pour les retracer ne serait pas trop lourd en processus?

Miniature(s) jointe(s)

  • Image attachée: courbes.JPG
  • Image attachée: droites.JPG


#10 dazfunkyman

    Ceinture Verte

  • Members
  • PipPipPipPip
  • 65 messages

Posté 21 December 2007 - 20:03 PM

Me lacher pas icon_cry.gif . Je pars en vacances pendant 4 jours et j'aurai certainement pas de connection internet.

Modifié par dazfunkyman, 21 December 2007 - 20:03 PM.


#11 dada

  • Honoris
  • PipPipPipPipPipPipPipPip
  • 8510 messages

Posté 21 December 2007 - 20:06 PM

Salut,

commence par essayer d'appliquer la proposition de Logic avec la méthode curveTo de la classe Graphics. wink.gif Vois ce que çà donne, si tu as des problèmes, etc, pour faire avancer la chose. smile.gif

#12 dazfunkyman

    Ceinture Verte

  • Members
  • PipPipPipPip
  • 65 messages

Posté 21 December 2007 - 20:24 PM

Citation (dada @ Dec 21 2007, 08:06 PM) Voir le message
Salut,

commence par essayer d'appliquer la proposition de Logic avec la méthode curveTo de la classe Graphics. wink.gif Vois ce que çà donne, si tu as des problèmes, etc, pour faire avancer la chose. smile.gif


Ok merci j'avais pas tout compris dans les propositions qui m'étaient faites.
Je pensais que Logic attendait que je montre la forme des courbes pour ensuite m'aiguiller vers la méthode la mieux adaptée pour réaliser leur redressement.
Vu que je suis pas trés cultivé en géometrie j'ai telecharger de la doc pour m'y mettre pendant les vacances de noel.
Je reposterai donc lorsque j'aurai un premier résultat (si j'y arrive)
Merci à bientôt gourou.gif


#13 Logic

  • Honoris
  • PipPipPipPipPipPipPipPip
  • 2733 messages

Posté 21 December 2007 - 21:45 PM

Alors.

Animer ce genre de courbe avec des curveTo, c'est un coup a devenir chauve. Car les beziers quadratic c'est de la grosse daube pour faire ca.

D'un autre coté, je me demande si le faire sur le timeline ne suffirait pas pour ton projet. Avec une interpolation de forme en utilisant les repere de forme, c'est faisable et ca me semble la solution la plus simple puisque que tu n'as qu'une seule animtion finalement (plus une autre qui se contente de la jouer en sens inverse).

Le code pour ca, c'est la grosse artillerie, le genre qui te permet de manipuler les courbes dans tous les sens. Je ne pense pas que tu ais besoin de ca.

Modifié par Logic, 21 December 2007 - 21:48 PM.


#14 Logic

  • Honoris
  • PipPipPipPipPipPipPipPip
  • 2733 messages

Posté 21 December 2007 - 22:11 PM

D'un autre coté il y a meme encore plus simple que de faire une interpo de forme avec repere.

Imagine un movieclip qui contient la partie toute noire de ton dégradé. Dans ce clip il y a donc une simple forme vectorielle en forme de rectangle dans lequel on a creusé une vague. Ce clip tu le places en frame 1 et 10 frame plus loin, tu lui mets un scale en x à valeur 0. Tu place une interpo de mouvement entre les 2 images et la ooooooooh miracle, tu vois ton clip qui s'ecrase, donc ta courbe qui s'aplatit. Tu prevois un autre clip rempli d'un simple rectangle, tu les colles et tu fais le raccord pendant l'animation et là t'as ton anim. Pour faire le degradé, tu dupliques tout ca et tu applique une couleur. Temps estimé de travail : une petite heure avec les reglages.

Grand prince que je suis icon_mrgreen.gif , tu trouveras un fla ci-joint wink.gif

C'est donc tres simple, alors qu'à la vue de ton premier post je m'attendais a des anims dynamiques furieuses et interactives.

Fichier(s) joint(s)


Modifié par Logic, 21 December 2007 - 22:13 PM.


#15 dazfunkyman

    Ceinture Verte

  • Members
  • PipPipPipPip
  • 65 messages

Posté 23 December 2007 - 11:52 AM

Citation (Logic @ Dec 21 2007, 10:11 PM) Voir le message
D'un autre coté il y a meme encore plus simple que de faire une interpo de forme avec repere.

Imagine un movieclip qui contient la partie toute noire de ton dégradé. Dans ce clip il y a donc une simple forme vectorielle en forme de rectangle dans lequel on a creusé une vague. Ce clip tu le places en frame 1 et 10 frame plus loin, tu lui mets un scale en x à valeur 0. Tu place une interpo de mouvement entre les 2 images et la ooooooooh miracle, tu vois ton clip qui s'ecrase, donc ta courbe qui s'aplatit. Tu prevois un autre clip rempli d'un simple rectangle, tu les colles et tu fais le raccord pendant l'animation et là t'as ton anim. Pour faire le degradé, tu dupliques tout ca et tu applique une couleur. Temps estimé de travail : une petite heure avec les reglages.

Grand prince que je suis icon_mrgreen.gif , tu trouveras un fla ci-joint wink.gif

C'est donc tres simple, alors qu'à la vue de ton premier post je m'attendais a des anims dynamiques furieuses et interactives.

Merci beaucoup de ton aide.
C'est vrai que je commence à m'arracher les cheveux, mais heureusement que j'ai trouver une connection internet dans le coin et que j'ai lu ton message.
En fait je voulais le faire avec l'api pour pouvoir modifier mes vagues par la suite sans avoir à tout redessiner mais comme tu viens de me le montrer ca prend pas t'en de temps que ca.
Donc je vais m'orienter sur ta dernière solution pour le moment et si j'ai plus de besoin par la suite je penserai à l'api.
Aller joyeux noel

Modifié par dazfunkyman, 23 December 2007 - 11:53 AM.




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

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