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

Composants FMX Delphi Discussion :

FMX.PathData, rotation d'un élément


Sujet :

Composants FMX Delphi

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Rédacteur/Modérateur

    Avatar de SergioMaster
    Homme Profil pro
    Développeur informatique retraité
    Inscrit en
    Janvier 2007
    Messages
    15 628
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 69
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2007
    Messages : 15 628
    Billets dans le blog
    65
    Par défaut FMX.PathData, rotation d'un élément
    Bonjour,

    plus ou moins promis voilà le problème de la rotation d'un élément plus ou moins résolu, mais il va falloir m'expliquer ce que j'ai fini par trouver après moult tests

    dans le projet (réduit) joint dans le zip je dessine cette fameuse hermine bretonne dont le fichier SVG est le suivant
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    <?xml version="1.0" encoding="UTF-8"?>
    <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="1350" height="900">
    	<rect width="1350" height="900" fill="#aaa"/>
     
    	<path d="M 300,167.5 l -9,-13.5 l 9,-22.5 l 9,22.5 z" fill="#000"/>
    	<path d="M 300,167.5 l -9,-13.5 l 9,-22.5 l 9,22.5 z" fill="#000" transform="rotate(-90 300,167.5)"/>
    	<path d="M 300,167.5 l -9,-13.5 l 9,-22.5 l 9,22.5 z" fill="#000" transform="rotate(90 300,167.5)"/>
            <path d="M 300,167.5 l 40.5,99 l -31.5,-13.5 l -9,18 l -9,-18 l -31.5,13.5 z" fill="#000"/>
     
     </svg>
    Par tâtonnements successifs j'ai bien fini par l'obtenir en utilisant le code suivant

    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
     
    // je ne m'occupe pas du rectangle blanc
    procedure TForm80.btnHermineClick(Sender: TObject);
    var s : String;
        n : single;
        aP,al,ar : Tpath;  // ap triangle haut, al triangle gauche, ar triangle droit
        M : TMatrix;
     
    begin
     ap:=Tpath.Create(Self);
     al:=Tpath.Create(Self);
     ar:=Tpath.Create(Self);
     try
     
      aP.Data.Data:='M 300,167.5 l -9,-13.5 l 9,-22.5 l 9,22.5 z';
      al.Data.Data:=ap.Data.Data;
      ar.Data.Data:=ap.Data.Data;
     
      Path1.Fill.Color:=Talphacolors.Black;
      Path1.Data.Data:='M 300,167.5 l 40.5,99 l -31.5,-13.5 l -9,18 l -9,-18 l -31.5,13.5 z';
     
      Path1.Data.AddPath(ap.data);
     
        m:=Tmatrix.CreateTranslation(-300,-167.5);
        al.data.applymatrix(m);
        M := TMatrix.CreateRotation(30);   // angle normalement 90  
        al.data.applymatrix(m);
        M:=TMatrix.CreateTranslation(300,167.5);
        al.data.applymatrix(m);
        Path1.Data.AddPath(al.data);
     
     
        m:=Tmatrix.CreateTranslation(-300,-167.5);
        ar.data.applymatrix(m);
        M := TMatrix.CreateRotation(-30);    // // angle normalement -90  
        ar.data.applymatrix(m);
        M:=TMatrix.CreateTranslation(300,167.5);
        ar.data.applymatrix(m);
        Path1.Data.AddPath(ar.data);
      finally
       ap.free;
       al.Free;
       ar.Free;
     end;
    end;
    Comme vous le constatez, j'applique trois étapes, un premier déplacement , négatif des coordonnées indiquées transform="rotate(-90 300,167.5)"
    procède ensuite à une rotation mais avec la valeur 30 !
    Puis refait un déplacement aux coordonnées

    N.B. Le code est simplifiable en multipliant les matrices
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
        M:=Tmatrix.CreateTranslation(-300,-167.5);
        M := M * TMatrix.CreateRotation(30);   // angle normalement 90  
        M := M* TMatrix.CreateTranslation(300,167.5);
        // ou encore
       //    M:=TMatrix.CreateTranslation(-300,-167.5) * TMatrix.CreateRotation(30) * TMatrix.CreateTranslation(300,167.5); 
        al.data.applymatrix(M);
        Path1.Data.AddPath(al.data);
    simplifiant le "mystère" à l'explication de la transformation de 90° en 30 (expression en ?)
    Ma trigonométrie est loin ...

    [Edit] en fait je crois que convertir l'angle en radian est la solution
    Fichiers attachés Fichiers attachés

  2. #2
    Rédacteur/Modérateur

    Avatar de SergioMaster
    Homme Profil pro
    Développeur informatique retraité
    Inscrit en
    Janvier 2007
    Messages
    15 628
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 69
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2007
    Messages : 15 628
    Billets dans le blog
    65
    Par défaut
    C'était bien des radians qui étaient attendu dans la fonction CreateRotation
    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
    procedure TForm80.btnHermineClick(Sender: TObject);
    var aP,al,ar : Tpath;
        M : TMatrix;
     
    begin
     ap:=Tpath.Create(Self);
     al:=Tpath.Create(Self);
     ar:=Tpath.Create(Self);
     try
     
        aP.Data.Data:='M 300,167.5 l -9,-13.5 l 9,-22.5 l 9,22.5 z';
        al.Data.Data:=ap.Data.Data;
        ar.Data.Data:=ap.Data.Data;
     
        Path1.Fill.Color:=Talphacolors.Black;
        Path1.Data.Data:='M 300,167.5 l 40.5,99 l -31.5,-13.5 l -9,18 l -9,-18 l -31.5,13.5 z';
     
        Path1.Data.AddPath(ap.data);
     
        m:=Tmatrix.CreateTranslation(-300,-167.5)*TMatrix.CreateRotation(DegToRad(90))*TMatrix.CreateTranslation(300,167.5);
        al.data.applymatrix(m);
        Path1.Data.AddPath(al.data);
     
     
        m:=Tmatrix.CreateTranslation(-300,-167.5)*TMatrix.CreateRotation(DegToRad(-90))*TMatrix.CreateTranslation(300,167.5);
        ar.data.applymatrix(m);
        Path1.Data.AddPath(ar.data);
      finally
       ap.free;
       al.Free;
       ar.Free;
     end;
     
    end;
    Tout cela me donne déjà les idées nécessaires pour gérer les groupes (<g> </g>) des fichiers SVG

  3. #3
    Expert confirmé
    Avatar de anapurna
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2002
    Messages
    3 491
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Mai 2002
    Messages : 3 491
    Par défaut
    salut

    est tu sur que les translation soit nécessaire ?
    cela me parait bizarre d’être obligé de faire 2 translation qui s'annule ?

    j'ai cru voir deux propriété intéressante : RotationCenter et RotationAngle
    ne pense tu pas que c'est celle-ci qui devrais être utilisé

  4. #4
    Rédacteur/Modérateur

    Avatar de SergioMaster
    Homme Profil pro
    Développeur informatique retraité
    Inscrit en
    Janvier 2007
    Messages
    15 628
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 69
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2007
    Messages : 15 628
    Billets dans le blog
    65
    Par défaut
    Citation Envoyé par anapurna Voir le message
    est tu sur que les translation soit nécessaire ?
    cela me parait bizarre d’être obligé de faire 2 translations qui s'annule ?
    C'est bien pour cela que j'ai posté, cela me paraissait bizarre mais sans ça, voilà ce que cela donne
    Nom : Capture.PNG
Affichages : 784
Taille : 2,9 Ko

    j'ai cru voir deux propriétés intéressantes : RotationCenter et RotationAngle
    ne penses-tu pas que c'est celle-ci qui devrais être utilisé
    Je ne fais pas "tourner" le composant TPath mais les Datas contenues (TPath.data) donc non rotationcenter et rotationangle ne s'applique pas, elles s'appliqueraient si je voulais faire tourner l'image entière
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    procedure TForm80.btnRotationPathClick(Sender: TObject);
    begin
    Path1.RotationAngle:=90;
    // par défaut 
    // Path1.RotationCenter.x:=0.5;
    // Path1.RotationCenter.Y:=0.5;
    end;

  5. #5
    Expert confirmé
    Avatar de anapurna
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2002
    Messages
    3 491
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Mai 2002
    Messages : 3 491
    Par défaut
    salut

    je voyais plus un truc de ce genre là
    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
     
    procedure TForm80.RotationPath(Apath : Tpath;Origine : Tpoint;Angle : Double);
    begin
      Apath.RotationCenter.x:=Origine.x;
      Apath.RotationCenter.Y:=Origine.y;
      Apath.RotationAngle:=DegToRad(Angle);
    // par défaut 
    end;
     
    procedure TForm80.btnHermineClick(Sender: TObject);
    var aP,al,ar : Tpath;
    begin
     ap:=Tpath.Create(Self);
     al:=Tpath.Create(Self);
     ar:=Tpath.Create(Self);
     try
     
        aP.Data.Data:='M 300,167.5 l -9,-13.5 l 9,-22.5 l 9,22.5 z';
        al.Data.Data:=ap.Data.Data;
        ar.Data.Data:=ap.Data.Data;
     
        Path1.Fill.Color:=Talphacolors.Black;
        Path1.Data.Data:='M 300,167.5 l 40.5,99 l -31.5,-13.5 l -9,18 l -9,-18 l -31.5,13.5 z';
        Path1.Data.AddPath(ap.data);
     
        RotationPath(al,Tpoint(300,167.5),90);
        Path1.Data.AddPath(al.data);
     
        RotationPath(ar,Tpoint(300,167.5),-90);
        Path1.Data.AddPath(ar.data);
      finally
       ap.free;
       al.Free;
       ar.Free;
     end;
    end;
    mais bon j'ai pas testé

  6. #6
    Membre émérite
    Avatar de Cirec
    Profil pro
    Inscrit en
    Octobre 2010
    Messages
    467
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2010
    Messages : 467
    Par défaut
    Bonjour,

    j'ai testé de mon coté et j'ai fait ceci:
    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
      Path1.Fill.Color:=Talphacolors.Black;
      Path1.Data.Data:='M 300,167.5 l 40.5,99 l -31.5,-13.5 l -9,18 l -9,-18 l -31.5,13.5 z';
     
      Path1.Data.AddPath(ap.data);
     
        M := TMatrix.CreateTranslation(300, 167.5);
        M := M.Inverse * TMatrix.CreateRotation(DegToRad(90)) * M;
     
        al.data.applymatrix(m);
        Path1.Data.AddPath(al.data);
     
        ar.data.applymatrix(M.Inverse);
        Path1.Data.AddPath(ar.data);
      finally
       ap.free;
       al.Free;
       ar.Free;
     end;
    qui donne le même résultat

    Cordialement,

    @+

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. FMX.PathData, encore un bug rigolo
    Par SergioMaster dans le forum Composants FMX
    Réponses: 8
    Dernier message: 16/12/2019, 07h59
  2. Réponses: 0
    Dernier message: 29/10/2015, 11h53
  3. [XE8-FMX] Position.X de 4 éléments
    Par Aooka dans le forum Débuter
    Réponses: 7
    Dernier message: 14/10/2015, 20h27
  4. Réponses: 1
    Dernier message: 11/10/2011, 21h34
  5. Rotation d'un JPanel ou de ses éléments
    Par kirby_blue dans le forum Agents de placement/Fenêtres
    Réponses: 2
    Dernier message: 06/08/2008, 03h12

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