Hi Alessandro,
Regarding the calculation of display angles, in my case (a 103x58cm monitor at a distance of 30 cm) I expect a value in degrees of 120x88, but instead mworks is giving me 120x67. Can you please explain why the half_height_deg is calculated in this way, and not simply by repeating the formula used for half_width_deg?
The code that does that calculation predates my involvement with MWorks, so I had to think about it for a while. Here’s how this works:
If the stimulus observer’s eye is at distance d from the center of the display, then the visual angle V subtended by a circle of radius r whose center coincides with that of the display is given (in radians) by
V = 2 * atan(r / d)
which is basically the equation for half_width_deg
given above.
Now, the point of these calculations is to define a mapping from degrees of visual angle to display pixels. In order for this mapping to preserve the shapes of stimuli (e.g. so that the aspect ratio of a rectangle does not change when the coordinates of its vertices are converted from degrees to pixels), we need it to be both linear and identical in every direction. Put another way, if a given visual angle is increased by ΔV, then the corresponding change in radius Δr should be independent of both r and the direction of the radius vector. More formally, we need the derivative of r with respect to V to be constant.
Rearranging the previous equation to express r as a function of V, we get
r = d * tan(V / 2)
The derivative of this equation is not constant with respect to V. However, if V/2 is small, then we can apply the small-angle approximation, and the above equation simplifies to
r = d * (V / 2)
which does have a constant derivative.
Getting back to your question, the above equation yields the following formulas for half_width_deg
and half_height_deg
:
half_width_deg = (180 / pi) * (width / 2) / distance
half_height_deg = (180 / pi) * (height / 2) / distance
Dividing the second equation by the first and multiplying by half_width_deg
gives
half_height_deg = half_width_deg * height / width
which is exactly the equation MWorks uses to compute half_height_deg
.
Now, since we used the small-angle approximation to get to this point, the validity of these results depends on the angle V/2 being suitably small. In order to keep the relative error within 2%, V/2 must be no larger than about 14 degrees. This implies that the distance from the observer’s eye to the center of the display should be at least twice the display’s largest dimension, i.e.
distance >= 2 * max(width, height)
In the case of your setup, this relation does not hold, which is why the display dimensions calculated by MWorks differ from what you expect.
The upshot here is that, for your setup, describing positions and sizes in terms of visual angle just isn’t going to be very useful, because those coordinates can’t be mapped on to pixels in a linear fashion. Instead, you’ll need to pick a different coordinate system that does vary linearly with pixels, and then choose values for the width, height, and distance to the display that yield the bounds you want.
In the future, MWorks probably should provide built-in support for alternative coordinate systems. PsychoPy seems to offer a nice set of unit options, so we may want to follow their lead.
I hope you find this helpful. If you have additional questions, please let me know.
Chris