First, in order to determine the location of the needle, we need to think of the range of the needle. For our needle, we used a swing of 90°, represented by the shaded red area. This is π/2 radians (for you non-math types, a full circle is 2π radians). This span starts 135° counter-clockwise from the standard 0 location. So to determine the needle position, we simple scale the needle position (in this case, 0-100) to radians 0 to π/2.
is the position of the needle, 0 to 100
From there, the X and Y positions are pretty simple:
is the length of the needle
We now have the coordinates for the top of the needle, but not the bottom. If the entire needle is drawn, those coordinates are simple. Y is the bottom of the chart, and X is the middle. But I wasn't going for simple and decided to hide the bottom of the needle.
What we have turns our to be a geometry problem--similar triangles. Proportionally, the two triangles the same. We know the coordinates of point A, point B and the Y-coordinate of point C. What we don't know is the X-coordinate of point C.
Now we have the full coordinates for the needle. For division marks, we can simply recycle the equation used to determine the top of the needle's location and run it twice. For the top, we extended the needle length by some amount (5 pixels in the example case) and for the bottom, decrease the needle length by the same amount. This will result in top and bottom coordinates for the divisions.
I thought about trying to come up with some sort of automatic scaling so that the chart would determine a needle length needed to fit the full 90° to the window. But I didn't like what I came up with. Instead, I simply made the needle length 3 times with height of the meter window.
Here are the results: