Newsgroup: it.comp.lang.visual-basic
Titolo: [?] Knob Rotazione

Ciao a tutti
Sto realizzando un'activex di un Knob (la classica manopola stile volume
della radio) ma ho un problema sulla rotazione del riferimento di questo
Knob.
Utilizzando le funzioni trigonometriche riesco a far ruotare in senso orario
ed anti orario il mio riferimento sull'iimagine del Knob.
Tutto funziona bene se la rotazione in un senso o nell'altro è completa (es.
da 0 a 360 in senso orario eviceversa in senso antiorario N.B. per prova ho
creato due command button che incrementano o decrementano l'angolo di 10
gradi alla volta ), il problema sorge se, per esempio, ruoto in senso orario
di 90 gradi e poi torno indietro, il punto non segue più la rotazione
correttamente perciò il punto d'origine non è più lo stesso.
E' forse un problema di arrotondamenti ?
Ho già cercato con Google ma non ho trovato nulla.
Di seguito il codice incriminato
Public m_Raggio As Double
Public m_X As Double
Public m_Y As Double
Public m_Alfa As Integer
Public m_Pi As Double
Private Sub Form_Load()
    m_Alfa = 0
    m_Raggio = 89.6
    m_Pi = 3.14159265
    Shape1.Left = 3895
    Shape1.Top = 4835
End Sub
' Button rotazione in senso orario
Private Sub Command1_Click()
    m_Alfa = m_Alfa + 10
    If m_Alfa > 360 Then
        m_Alfa = 360
        Exit Sub
    Else
        Call Polare_Piu
    End If
End Sub
'Button rotazione in senso antiorario
Private Sub Command2_Click()
    m_Alfa = m_Alfa - 10
    If m_Alfa < 0 Then
        m_Alfa = 0
        Exit Sub
    Else
        Call Polare_Men
    End If
End Sub
'Rotazione in senso orario
Function Polare_Piu()
    m_Coseno = Cos(m_Pi * m_Alfa / 180)
    m_Seno = Sin(m_Pi * m_Alfa / 180)
    m_X = Shape1.Left - m_Raggio * m_Coseno
    m_Y = Shape1.Top - m_Raggio * m_Seno
    Shape1.Left = m_X
    Shape1.Top = m_Y
End Function
'Rotazione in senso antiorario
Function Polare_Men()
    m_Coseno = Cos(m_Pi * m_Alfa / 180)
    m_Seno = Sin(m_Pi * m_Alfa / 180)
    m_X = Shape1.Left + m_Raggio * m_Coseno
    m_Y = Shape1.Top + m_Raggio * m_Seno
    Shape1.Left = m_X
    Shape1.Top = m_Y
End Function
Grazie a tutti
JKLJKL :-/

 correttamente perciň il punto d'origine non č piů lo stesso.
Dopo essermi ristudiato trigonometria mi sono fatto tra le altre questa
funzioncina per calcolare la rotazione di un punto:
Const pi_ = 3.14159265358979
Public Sub axvPointOnEllipse(ByVal OrgX As Long, ByVal OrgY As Long, ByVal
RadiusX As Long, ByVal RadiusY As Long, ByVal Angle As Long, DestX As Long,
DestY As Long)
    Dim R As Double
    R = pi_ / 180# ' degree to radiants
    DestX = OrgX - (Sin(Angle * R) * RadiusX)
    DestY = OrgY - (Sin((90 - Angle) * R) * RadiusY)
End Sub
Ciao

 Ciao
Ciao Zanna
Grazie per la risposta Domenicale (vedo che siamo in molti a lavorare anche
di Domenica !), ma il problema sussiste anche con la tua funzione.
Fai questa prova (se hai voglia e tempo) creati un pulsante di incremento di
10 gradi, uno di decremento di altrettanti 10 gradi e una seconda funzione
dove OrgX e OrgY vengono sommate.
Se fai ruotare su di una circonferenza in senso orario un'oggetto qualsiasi
( io ho usato una shape cerchio di diametro 60 twips) di pochi gradi e poi
di altrettanti in senso antiorario e ripeti l'operazione un po' di volte
vedrai che l'oggetto non tornerà nella posizione origine ma sarà spostato di
molto.
Come DestX, DestY e OrgX,OrgY ho usato il Left ed il Top della Shape che
voglio far ruotare.
Dov'è l'errore ?
JKLJKL :-/

 Dov'č l'errore ?
Proprio negli arrotondamenti!
Per di piů le coordinate schermo sono interi, quindi l'approssimazione
sballa di molto, e l'errore cresce in modo esponenziale man mano che vai
avanti.
La mia funzione in effetti non va usata come fai tu.
Devi definire un punto fermo di riferimento e ruotare sempre quello di x
gradi.
Se fai cosě vedrai che funziona perfettamente.
Ciao

 Ciao
Grazie molte, il dubbio c'era ma non ne ero sicuro.
Quando finisco il controllo lo metto a disposizione del NG sul sito
ufficiale
Grazie ancora.
JKLJKL ;-)

 Ciao
Scusa per l'intempestivo entusiasmo sigh! Ma penso di non aver capito cosa
intendi.
Le coordinate dello schermo sono comunque degli interi perciò l'errore di
posizionamento continua ad esistere.

 Ciao
Scusa per l'intempestivo entusiasmo sigh! Ma penso di non aver capito cosa


 posizionamento continua ad esistere.
No se usi sempre lo stesso punto come riferimento.
Poniamo che tu abbia il centro del tuo controllo nel punto 100, 100.
Vuoi avere il tuo "pallino" a una distanza di 50 (poniamo che si stia
parlando di una circonferenza, quindi raggiox e raggioy si equivalgono).
Basta richiamare la funzione così:
axvPointOnEllipse(100, 100, 50, 50, Angolo, x, y)
Poi l'arrotondamento su x e y risultanti è inevitabile dato che diventeranno
interi, ma se provi a fare un loop su Angle ti accorgi che verrà tracciato
un cerchio perfetto con centro 100, 100 e raggio 50.
Ciao