问题
I writing a meter widget using canvas and need to calculate the label values for the scale. No problem except when I'm trying to re-create the scale for a VU meter. I understand it's logrithmic, but the values aren't powers of 10 on that type of meter.
see: https://en.wikipedia.org/wiki/VU_meter
The function I have is given the min and max values for the scale. For normal scales, it also is given the step between values. For example, given -20 and 30 with a step of 10, it would produce labels:
-20 -10 0 10 20 30
For a VU meter given -20 and 6, I need to produce labels:
-20 -10 -5 -3 0 3 6
And, the spacing isn't the same on the scale between those values.
I am not asking for actual code examples, but instead for ideas on how to best approach implementing this.
Should I write the function so one of the parameters is a list of labels, then plot them on a logarithmic scale? That doesn't appear to work properly because the numbers do not end up in the right places as seen in the image above of a proper VU meter.
Is there some special formula just for dB levels that isn't a simple log function?
Again, I'm not asking for code examples, just for some help understanding the best approach to use.
Thanks!
回答1:
I suppose you have a value-to pixel function. What you need to write is the inverse function of that.
When you have the inverse function, you just divide the screen area to N equal parts (in the picture you have 6 regions). One region will be X pixels in width. Now you can use your inverse function to get the value for that pixel-position.
This will not be an integer, it will be something like 3.434 or 11.34 - you need a prettyfier function which will generate the closest "pretty" number (let's say just chop off the parts after the decimal).
Now you take the pretty value and calculate the pixel position for it with your original function.
Some code:
function value2px(value, valueMin, valueMax, pxMin, pxMax) {
var valueWidth = sigLog(valueMax) - sigLog(valueMin);
var pixelWidth = pxMax - pxMin;
var ratio = pixelWidth / valueWidth;
return ratio * (sigLog(value) - sigLog(valueMin)) + pxMin;
}
function px2value(px, valueMin, valueMax, pxMin, pxMax) {
var valueWidth = sigLog(valueMax) - sigLog(valueMin);
var pixelWidth = pxMax - pxMin;
var ratio = pixelWidth / valueWidth;
return sigExp((px - pxMin) / ratio + sigLog(valueMin));
}
and the demo: http://jsfiddle.net/ambcwoLg/1/
来源:https://stackoverflow.com/questions/30597612/how-do-i-calculate-logrithmic-labels-for-a-vu-meter-scale