We start with mouse variables and arctangent, which allows us to derive an angle from any 2 points. The first point will be the center of the meter, and the 2nd will be the click coordinates. We'll write a formula that causes the bottom left to approach 0, and the bottom right to approach 1.
Using percentage mouse variables will free us from worrying about the dimensions of the meter in question. The percentage is an integer ranging from 0-100. Arctangent takes the ratio of Y-axis change to X-axis change, so we get that relative to the center by subtracting 50% from both mouse variables. Atan() gives results ranging from -pi/2 to pi/2 on the right half of the circle, and inverted (rotational symmetry) on the left side. Adding pi/2 to the result will shift the range to 0 to pi. Then we add pi if click is on the right side to get an angle that ranges from 0 to 2pi. Divide the result by 2pi to get a value that ranges from 0 to 1.
After reordering some operations for efficiency, we get:
Code: Select all
!SetVariable Num (Atan(($MouseY:%$-50)/($MouseX:%$-50))/6.2832+0.25+(Sgn($MouseX:%$-50)+1)*0.25)
Ideally, there should slightly larger click areas solely for setting 0 or 1. We'll accomodate that by changing the formula to range from slightly less than 0 to slightly greater than 1. Specifically, I'm going to carve out the bottom 1/8th of the circle for those areas.
Code: Select all
!SetVariable Num (Atan(($MouseY:%$-50)/($MouseX:%$-50))/5.49779+0.21875+(Sgn($MouseX:%$-50)+1)*0.28125)
Conveniently, Lua's math.atan2 takes care of divide-by-zero. It also gives angles for the full circle by checking the signs of parameters. The result ranges from -pi to pi.
Code: Select all
math.atan2(mouseX-50, 50-mouseY) / 5.49779 + 0.5
Then to use it for volume, I multiply the constants by 100. I also precalculate 1/5.49779 because multiplication is more efficient than division for computers.
TL;DR
100 * (1 / (2pi * 7/8)) ≈ 18.18914
Replace 7/8 with any fraction to make semi-circle dials, etc.
Code: Select all
[Dial]
Meter=Roundline
LeftMouseUpAction=!CommandMeasure mScript SetVolume($MouseX:%$,$MouseY:%$)
function SetVolume(mouseX, mouseY)
SKIN:Bang('!CommandMeasure mVolume "SetVolume '..(math.atan2(mouseX-50, 50-mouseY) * 18.18914 + 50)..'"')
end
Changelog:
- Added center mute button from smurfier's RoundKnob.
- Detect mute state.