Creating a rotating knob - troubling question

I have need for a simple rotating knob.
This will be a picture of knob photo and a small dot rotating over the picture so the user gets the impression the knob is rotating.

Putting the small dot at a certain angle isn’t difficult: Adding this in a Canvas works fine.

dim x,y as double
dim r as double = 20
  
dim circleCenterX as integer = 100
dim circleCenterY as integer = 100
 
 x  =  circleCenterX + (r*cos(angle)) 
 y  =  circleCenterY + (r*sin(angle))
 
  g.DrawString "x",circleCenterX,circleCenterY
  g.DrawString "O", x, y

Now the difficulty part.
The user should be able to drag the knob dot by dragging over the canvas aka rotating knob.

And know comes the question:
What code should I put in the MouseDrag event?

I tried a lot but fail doing so. The Angle value should be from 0 to 360
So when X raises, Angle should raise to max. 360, when X lowers, Angle should raise to max. 0

Seems easy, but it isn’t. :slight_smile:

here is one I once used for Midi Control
You change it for your needs.

Knob

Add these properties to a Window

diffAngle As double
pix As PixmapShape

Then add a Canvas with these events

[code]Function MouseDown(X As Integer, Y As Integer) As Boolean
dim angle As double = ATan2(Y-50, X-50)
diffAngle = angle - pix.Rotation
return true
End Function

Sub MouseDrag(X As Integer, Y As Integer)
dim angle As double = ATan2(Y-50, X-50)
pix.Rotation = angle - diffAngle
me.Invalidate
End Sub

Sub Paint(g As Graphics, areas() As REALbasic.Rect)

if pix = nil then
dim pic As new Picture(100, 100)
pic.Graphics.FillRoundRect(40, 0, 20, 100, 20, 20)
pix = new PixmapShape(pic)
pix.X = 50
pix.Y = 50
end

g.DrawObject(pix)

End Sub
[/code]

I hope it’s self explanatory :slight_smile:

Thank you Will and Axel. :slight_smile:

It was ATan I couldn’t figure out. :slight_smile:

What is the PixmapShape ?
Never knew about this. :slight_smile:

Although Wills code work fine it very difficult to attach a value to it. The angle value has erratic values depending where you click to start rotating.
So linking this with a value that has a range of 0 to 360 is not possible (I think).

Are you aware that the .rotation property is in radians, not degrees?

Yes, of course. pix.Rotation*180/PI converts it to degrees. But thats not the issue. :slight_smile:

The problem is that you cannot get a fixed value - it jumps erratically and it depends where you click to start rotating the knob.
So making sure 1 turn is 0 to 360 is not possible - I tried about anything.

Will make a small example and post a download link so maybe someone can find a solution for this.

Here is the download link:
http://www.filedropper.com/turnknob

Does it do what you expect it to if you replace the two instances of ATan2(Y-50, X-50) with ATan2(Y-64, X-64) ?

I’m guessing that the value of 50 was left over from a previous version of your code in which the oval was 100 X 100, rather than 128 X 128???

Yes, already tried that.
I still trying to get this to work, unfortunately I don’t think it is possible with the current code.
Any help is appreciated. :slight_smile:

I thought pixmapshape would roll it’s rotation value inside the range 0-2pi, but obviously it’s not. So you can do that like this

[code]Sub MouseDrag(X As Integer, Y As Integer)
angle = ATan2(Y-64, X-64) // <- subtract the center of rotation
pix.Rotation = angle - diffAngle

const tau = 6.28318530717959 //2*pi

dim units As integer = Floor(pix.Rotation / tau)

if units <> 0 then pix.Rotation = pix.Rotation - units * tau

Label1.Text = str(pix.Rotation*180/3.1415)
me.Invalidate
End Sub[/code]

units is the block of 2pi the value is in. If it’s not 0 (range 0-2pi) then the value is shifted by the number of units out of range it is.

This ‘fixes’ the Rotation value of pix but mathematically there’s no difference; you could let it go wherever and only fix the value for display. Well, I guess it depends what you’re doing. If you want to restrict the knob to only 1 turn then extra code is needed.

Like Peter said you want to subtract the point of rotation in atan2.

Also note that this is y-down orientation where angle increases clockwise. Standard math is y-up where angle increases counter-clockwise.

Yep, that fixed the issue. Thanks to all who participated in this thread. Appreciated !

[quote=190205:@Christoph De Vocht]What is the PixmapShape ?
Never knew about this. :)[/quote]

http://documentation.xojo.com/index.php/PixmapShape