Rotation autour du centre

Résolu
cs_cheyenne Messages postés 693 Date d'inscription samedi 18 mai 2002 Statut Membre Dernière intervention 17 avril 2017 - 6 déc. 2012 à 00:55
cs_cheyenne Messages postés 693 Date d'inscription samedi 18 mai 2002 Statut Membre Dernière intervention 17 avril 2017 - 6 déc. 2012 à 13:06
Bonjour,

Dans le code ci-dessous mon carré ne veut pas tourner degré par degré. Quand il tourne c'est dans le sens antihoraire et je n'ai pas trouvé comment le faire tourner dans les 2 sens, oui, je sais, c'est la honte !!!
Le but est de faire un jeu de Tangram, toutes les pièces ainsi que l'interface sont prêtes, il ne me manque juste la bonne formule.


Mettre juste un HScroll sur la feuille.

Option Explicit: Option Base 1

Private Declare Function Polygon Lib "gdi32" ( _
        ByVal hdc As Long, tPoints As POINTAPI, ByVal nPoints As Long) As Long

Private Type POINTAPI
   x  As Long
   y  As Long
End Type

Dim coord(4)   As POINTAPI
Dim poly(4)    As POINTAPI

Const SIZE     As Integer = 100
Const SIZEd2   As Integer = SIZE / 2

Private Sub Form_Activate()
   Dim x As Integer
   Dim y As Integer
      
   x = ScaleWidth / 2
   y = ScaleWidth / 2
   
   coord(1).x x:         coord(1).y y
   coord(2).x x + SIZE:  coord(2).y y
   coord(3).x x + SIZE:  coord(3).y y + SIZE
   coord(4).x x:         coord(4).y y + SIZE
   
   Call ROTATION
End Sub

Private Sub ROTATION()
   Dim i As Integer
   Dim a As Integer
   Dim x As Integer
   Dim y As Integer
   Dim xc As Integer
   Dim yc As Integer
   Dim xr As Integer
   Dim yr As Integer
   Dim co As Single
   Dim si As Single

   xc = ScaleWidth / 2
   yc = ScaleHeight / 2

   a = HScroll1.Value * (Atn(1) * 4) / 180
   co = Cos(a)
   si = Sin(a)
   Me.Cls

   For i = 1 To 4
      x = coord(i).x
      y = coord(i).y

      xr = co * (x - xc - SIZEd2) - si * (y - yc - SIZEd2)
      yr = si * (x - xc - SIZEd2) + co * (y - yc - SIZEd2)
      
      poly(i).x = xr + xc
      poly(i).y = yr + yc
   Next i

   Call Polygon(Me.hdc, poly(1), 4)
End Sub

Private Sub HScroll1_Scroll()
   Call HScroll1_Change
End Sub

Private Sub HScroll1_Change()
   Me.Caption = HScroll1.Value
   Call ROTATION
End Sub

Private Sub Form_Load()
   With HScroll1
      .Min = 0
      .Max = 359
      .SmallChange = 1
      .LargeChange = 10
      .Value = 0
   End With
End Sub


Mes remerciements aux matheux qui voudront bien m'aider.

Cheyenne

4 réponses

cs_Jack Messages postés 14006 Date d'inscription samedi 29 décembre 2001 Statut Modérateur Dernière intervention 28 août 2015 79
6 déc. 2012 à 09:58
Salut

Première chose qui me saute aux yeux : Le type Integer
Ce type n'accepte que des chiffres entiers compris entre -32768 et +32767.
Hors mis les min/max, ce genre de calculs nécessitent surement des virgules, non ?
Notamment pour le calcul de 'a' qui semble être l'angle en radians, donc -Pi à +Pi.
HScroll1.Value peut prendre des valeurs de ... ?
A priori, je dirais de -180 à +180 ??
Est-ce bien le cas ?

Pendant que tu y es à revoir chaque type de données, profites-en pour donner des noms plus parlant à tes variables - Tu t'y retrouveras plus facilement ET nous aussi.

Vala
Jack, MVP VB
NB : Je ne répondrai pas aux messages privés

Le savoir est la seule matière qui s'accroit quand on la partage (Socrate)
3
ucfoutu Messages postés 18038 Date d'inscription lundi 7 décembre 2009 Statut Modérateur Dernière intervention 11 avril 2018 211
6 déc. 2012 à 10:59
Bonjour,
J'ajouterais personnellement que le moyen le plus simple n'est pas de faire tourner un polygone, mais de le redessiner (lignes entre ses sommets à faire tourner, eux).
Je vais donc te proposer ce petit exemple/test :

Sur un Form : un timer Timer1 et ce code
Option Explicit
Private Const diametre As Integer = 100
Private cy As Integer
Private cx As Integer
Private ancY As Single
Private ancx As Single
Private angle As Double
Private sens As Integer

Private Sub Form_Activate()
    Me.ScaleMode = vbPixels
    Me.AutoRedraw = True
    cx = Me.ScaleWidth / 2
    cy = Me.ScaleHeight / 2
    Me.Circle (cx, cy), diametre, vbWhite
    sens 1 '>> le sens de rotation est  définir là : 1 ou - 1 
    Timer1.Interval = 100
End Sub

Private Sub Timer1_Timer()
  Dim pi As Double, toto As Double
  pi = 4 * Atn(1)
  toto = (angle / 180) * pi
  Me.Line (cx, cy)-(ancx, ancY), Me.BackColor
  ancY = cy + Sin(toto - (0.5 * pi)) * diametre
  ancx = cx + Cos(toto - (0.5 * pi)) * diametre
  Me.Line (cx, cy)-(ancx, ancY)
  angle = angle + sens
End Sub


Tu y as le calcul mathématique.
Que fait cet exemple ? Ben ===>> il fait tourner UN point (défini par les coordonnées ancx,ancy
Tu peux oublier tant le cercle, que le rayon, qui ne sont ici visibles que pour que tu comprennes.
Et toi, alors ? ===>> idem pour chacun des 4 sommets de ton carré, à joindre ensuite entre eux par Line

________________________
Réponse exacte ? => "REPONSE ACCEPTEE" facilitera les recherches.
Pas d'aide en ligne installée ? => ne comptez pas sur moi pour simplement répéter son contenu. Je n'interviendrai que si nécessité de la compléter.
0
cs_cheyenne Messages postés 693 Date d'inscription samedi 18 mai 2002 Statut Membre Dernière intervention 17 avril 2017 2
6 déc. 2012 à 13:02
Bonjour jack,

Merci, c'est bien le type de la variable de l'angle qui n'est pas le bon. Je l'ai mis par erreur en Integer au lieu de Single.

Juste en changeant le type, j'obtiens bien la rotation. J'ai changé les valeurs du HScroll1 de -360 à 360 car avec -180,180 je n'obtiens qu'un demi-tour. Pour le carré, ce n'est pas grave, mais les pièces comprennent des triangles et un parallélogramme.

Pour les noms, je suis d'accord avec toi, mais il me semblait que xr et yr étaient explicites, pour Xrotation et Yrotation tout comme xc et yc pour le centre. Mais le lecteur du post n'est "pas dans ma tête" !

Cheyenne
0
cs_cheyenne Messages postés 693 Date d'inscription samedi 18 mai 2002 Statut Membre Dernière intervention 17 avril 2017 2
6 déc. 2012 à 13:06
Bonjour ucfoutu,

Merci pour l'exemple mais j'ai déjà fait des pendules. C'est le même principe !

Ce qui m'intéressait était de savoir si la formule de rotation tait la bonne.

Cheyenne
0
Rejoignez-nous