IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Algorithmes et structures de données Discussion :

Rotation erreur de calcul


Sujet :

Algorithmes et structures de données

  1. #1
    Membre actif Avatar de Speed41
    Homme Profil pro
    Inscrit en
    Novembre 2002
    Messages
    718
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 56
    Localisation : France

    Informations forums :
    Inscription : Novembre 2002
    Messages : 718
    Points : 210
    Points
    210
    Par défaut Rotation erreur de calcul
    J'ai une petite procedure (que je fais générer par une autre appli.) qui permet de dessinier une forme sur un Canvas à l'endrois désiré de la taille désiré. Et je voudrais pouvoir le faire tourner autour d'un point qui n'est pas obligatoirement le centre

    Programmation sous Delphi 7

    Voici le code exemple que j'utilise

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    procedure TForm1.angleChange(Sender: TObject); 
    var a      : real; 
    begin 
      a:=pi/180*angle.Position; 
      image1.Picture:=nil; 
      Nom_procedure(image1.Canvas,image1.width div 4,image1.Height div 4, image1.width div 10, image1.Height div 10,a); 
    end; 
     
    Procedure TForm1.Nom_procedure(caneva :Tcanvas; OrigineX, OrigineY, Largeur, hauteur : integer; Angle : real); 
    Var rx, ry, dx, dy : real; 
        x0, y0         : integer; 
    function lepoint(x, y : integer) : Tpoint; // calcul des coordonées du point après rotation 
             var R, acos   : real; 
             Begin 
               x:=trunc((x-dx)*rx)+OrigineX; 
                                            y:=trunc((y-dy)*ry)+OrigineY; 
                                            R:=sqrt(sqr(x-x0)+sqr(y-y0)); 
               acos:=arccos((x-x0) / R); 
     
               x:=X0+trunc(R*cos(acos+angle)); 
               if y>y0 then 
                  y:=y0+trunc(R*sin((-1*acos)+angle)) 
                       else 
                  y:=y0-trunc(R*sin(acos+angle)); 
     
               image1.Canvas.Brush.Style:=bsclear; 
               image1.Canvas.Ellipse(trunc(x0-R),trunc(y0-r),trunc(x0+r),trunc(y0+r)); 
               image1.Canvas.Brush.Style:=bssolid; 
               result:=point(x, y); 
             end; 
    Begin 
      x0:=155; 
      y0:=84; 
      with caneva do 
           begin 
             rx:=1;// proportion de la forme par rapport à sa taille d'origine 
             ry:=1;// proportion de la forme par rapport à sa taille d'origine 
             Dx:=0;// coordonnées du début du traçage sur la canvas 
             Dy:=0; 
             x0:=trunc((x0-dx)*rx)+OrigineX;      // centre de rotation, coordonées recalculées 
             y0:=trunc((y0-dy)*ry)+OrigineY;      // 
    //-=-=-=-=-=-=-=-=-=-=- 
             pen.Color:=clblue; 
             Polygon([lepoint(137,16),lepoint(133,119),lepoint(237,115)]); 
             pen.Color:=clred; 
             moveto(origineX,OrigineY); 
             lineto(x0,y0); 
             pen.Color:=clblack; 
             moveto(origineX,OrigineY); 
             lineto(trunc((137-dx)*rx)+OrigineX,trunc((16-dy)*ry)+OrigineY); 
             moveto(origineX,OrigineY); 
             lineto(trunc((133-dx)*rx)+OrigineX,trunc((119-dy)*ry)+OrigineY); 
             moveto(origineX,OrigineY); 
             lineto(trunc((237-dx)*rx)+OrigineX,trunc((115-dy)*ry)+OrigineY); 
           end; 
    end;

    Le problème est que tous les points se trouvant avec une ordonnée inférieur à l'ordonné de point de rotation sont placé symétriquement au dessus du centre de rotation et la ça me va pas.

    Je suis sur que c'est une petite erreur de calcul mais je sèche.

    merci de vos conseilles

  2. #2
    Membre habitué Avatar de PINGOUIN_GEANT
    Profil pro
    Inscrit en
    Juin 2004
    Messages
    149
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2004
    Messages : 149
    Points : 155
    Points
    155
    Par défaut
    qu'as-tu comme renseignements pour caractériser ta rotation ?
    car une rotaton s'écrit
    Y=AX+B (dans le plan affine)
    donc tu peux éviter de passer par des Arccos et des sin (à mon avis c'est là le problème)

  3. #3
    Membre expérimenté
    Avatar de Juju_41
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Février 2003
    Messages
    974
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués

    Informations forums :
    Inscription : Février 2003
    Messages : 974
    Points : 1 557
    Points
    1 557
    Par défaut
    Citation Envoyé par PINGOUIN_GEANT
    car une rotaton s'écrit
    Y=AX+B (dans le plan affine)
    donc tu peux éviter de passer par des Arccos et des sin (à mon avis c'est là le problème)
    Heuuu ... pourrais-tu m'expliquer comment faire une rotation avec une équation de droite ?

  4. #4
    Inactif   Avatar de Médiat
    Inscrit en
    Décembre 2003
    Messages
    1 946
    Détails du profil
    Informations forums :
    Inscription : Décembre 2003
    Messages : 1 946
    Points : 2 227
    Points
    2 227
    Par défaut
    Citation Envoyé par Juju_41
    Heuuu ... pourrais-tu m'expliquer comment faire une rotation avec une équation de droite ?
    Heuuu... les matrices peut-être ?

  5. #5
    Membre régulier
    Homme Profil pro
    Retraité
    Inscrit en
    Mars 2004
    Messages
    142
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 75
    Localisation : France, Seine et Marne (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Mars 2004
    Messages : 142
    Points : 119
    Points
    119
    Par défaut Re: Rotation erreur de calcul
    Citation Envoyé par Speed41
    Je suis sur que c'est une petite erreur de calcul mais je sèche.
    Bon, il semble que tu veuilles faire tourner un point M(x,y) autour d’un point M0(X0,Y0). Le fait d’appeler x,y à la fois les coordonnées initiales d’un point et aussi les coordonnées après une homothétie et une translation ne facilite pas les choses, mais bon : j’appelle x,y les coordonnées de ton point avant rotation (mais après ton homothétie-translation), x0,y0 les coordonnées après rotation.

    Si j’ai bien compris, tu évalues avec arccos l’angle acos que fait ton vecteur MM0 avec l’axe des x, puis tu ajoutes "angle" et ensuite tu recalcules les nouvelles coordonnées avec l’angle "acos+angle" ; plus exactement, c'est ce que tu voulais faire car en fait il semble que tu utilises l'angle "angle-acos" dans certains cas également. Tout cela est beaucoup trop compliqué. Se tromper sur l’utilisation de arccos est tellement facile que je ne suis pas étonné : tout le monde se trompe à un moment ou à un autre. Il vaut mieux prendre ce risque seulement lorsque l’on ne peut pas faire autrement. Or, ici on peut faire autrement.

    Si j’appelle c et s respectivement les cosinus et sinus de l’angle « angle », les formules donnant les nouvelles coordonnées après rotation Nx et Ny sont :

    Nx = x0 + [ c * (x-x0) - s * (y-y0) ]
    Ny = y0 + [ s * (x-x0) + c * (y-y0) ]

    Il n’y a aucun test à faire du type « if (y<y0) », aucun arccos à calculer ni aucun cos ni aucun sin (sauf c et s qui eux ne dépendent que de l’angle de rotation « angle » et qui donc ne seront calculés qu’une seule fois). Ca ira beaucoup plus vite et en plus ça va le faire !

    Bon courage

  6. #6
    Membre habitué Avatar de PINGOUIN_GEANT
    Profil pro
    Inscrit en
    Juin 2004
    Messages
    149
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2004
    Messages : 149
    Points : 155
    Points
    155
    Par défaut
    Citation Envoyé par pgibone
    Citation Envoyé par Juju_41
    Heuuu ... pourrais-tu m'expliquer comment faire une rotation avec une équation de droite ?
    Heuuu... les matrices peut-être ?
    effectivement c'est une notation matricielle
    et bravo à Ceugniet qui a tout bien explicité dans le cas 2D

  7. #7
    Rédacteur/Modérateur
    Avatar de Trap D
    Profil pro
    Inscrit en
    Septembre 2003
    Messages
    4 942
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2003
    Messages : 4 942
    Points : 6 498
    Points
    6 498
    Par défaut
    Une notation plus correcte aurait peut-être été : Y = A(X-B)+B, mais c'est histoire de chipoter

  8. #8
    Membre habitué Avatar de PINGOUIN_GEANT
    Profil pro
    Inscrit en
    Juin 2004
    Messages
    149
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2004
    Messages : 149
    Points : 155
    Points
    155
    Par défaut
    Citation Envoyé par Trap D
    Une notation plus correcte aurait peut-être été : Y = A(X-B)+B, mais c'est histoire de chipoter
    ce n'est pas mon avis, en outre tu fais plus de calculs

  9. #9
    Rédacteur/Modérateur
    Avatar de Trap D
    Profil pro
    Inscrit en
    Septembre 2003
    Messages
    4 942
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2003
    Messages : 4 942
    Points : 6 498
    Points
    6 498
    Par défaut
    Il me semble que que ça correspond exactement à ce que ceugniet a écrit
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    Nx = x0 + [ c * (x-x0) - s * (y-y0) ]
    Ny = y0 + [ s * (x-x0) + c * (y-y0) ]
    ou X est la matrice colonne (x y) et B (x0 y0)
    Mais c'est vrai que, sur la forme, tu as raison mais pour les calculs j'en suis moins sûr, ceci dit tout celà est très loin pour moi.

  10. #10
    Membre habitué Avatar de PINGOUIN_GEANT
    Profil pro
    Inscrit en
    Juin 2004
    Messages
    149
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2004
    Messages : 149
    Points : 155
    Points
    155
    Par défaut
    tu remarqueras que si tu développes la forme tu peux écrire sous la forme AX+B mais B différent de (x0,y0)

    avec une forme A(X-B)+B tu fais des soustractions en trop à chaque fois alors qu'avec AX+B tu les as faits au début une bonne fois pour toute.

  11. #11
    Rédacteur/Modérateur
    Avatar de Trap D
    Profil pro
    Inscrit en
    Septembre 2003
    Messages
    4 942
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2003
    Messages : 4 942
    Points : 6 498
    Points
    6 498
    Par défaut

Discussions similaires

  1. type "short" erreur de calcul, pourquoi ?
    Par Link_GZ dans le forum C
    Réponses: 4
    Dernier message: 04/05/2007, 13h15
  2. [2.0] Erreur de calcul numérique de .net o_O
    Par Smeuuh dans le forum Framework .NET
    Réponses: 8
    Dernier message: 11/11/2006, 17h04
  3. [Tableaux] erreur de calcul
    Par dleu dans le forum Langage
    Réponses: 18
    Dernier message: 08/12/2005, 13h28
  4. erreur sur calcul
    Par Sendo dans le forum Access
    Réponses: 2
    Dernier message: 29/09/2005, 09h46
  5. C++Builder fait une erreur de calcul
    Par gandf dans le forum C++Builder
    Réponses: 7
    Dernier message: 03/01/2004, 22h27

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo