Welcome! Log In Create A New Profile

Advanced

Coordinate conversion

Posted by Jaewon 
Coordinate conversion
August 17, 2019 07:20PM
There are several coordinate systems used in NIMH ML for calibration and graphics.

sig is analog voltage or digital input (X & Y) fed from eye trackers or joysticks.
deg is visual degrees measured from the center of the screen. NIMH ML mostly works on this coordinate system in timing scripts.
pix is native pixel coordinates of Windows. The top-left corner is (0,0) and x & y increase as moving toward the bottom-right corner. This is the coordinate system that MGL uses.
norm is normalized coordinates in which both x & y have a value between 0 and 1. It is useful when you design layouts independent of the screen size.




The mlcalibrate class provides methods to manipulate the coordinate systems and convert xy coordinates from one system to another. There are 4 mlcalibrate objects that users can access in the timing script: EyeCal, Eye2Cal, JoyCal and Joy2Cal.
xy_deg = EyeCal.sig2deg(xy_sig, offset);  % Eye2Cal, JoyCal or Joy2Cal can be used, too.
                                          % The offset should be [0 0]. 
EyeCal.translate(xy_offset);              % Translate the system so that xy_offset becomes a new (0,0).
EyeCal.rotate(theta);                     % Rotate the coordinates system by theta (in degrees).
EyeCal.custom_calfunc(@function_handle);  % For user manipulation of calibration.
The sig2deg method is device-dependent. It works only when the calibration process is complete. There are three methods that can affect how sig2deg works. The translate method updates the calibration matrix so that the given coordinates become a new origin of the system. The rotate method turns the axes on the origin by the given angle. With the custom_calfunc method, you can plug in a custom function to manipulate the calibration. For example, if you want to move the origin to [3 3], you can write a timing script as below.
new_origin = [3 3];  % in degrees
JoyCal.custom_calfunc(@custom_joy);
...
...
...
function xy_deg = custom_joy(xy_deg)  % note that input and output are both in degrees
    n = size(xy_deg,1);
    xy_deg = xy_deg + repmat(new_origin, n, 1);
end
The difference between JoyCal.translate([3 3]) and the above code is that the former brings [3 3] to [0 0] and the latter moves [0 0] to [3 3].

Additionally the following methods are available. Except sig2pix, all methods are device-independent. In other words, the results will be the same, no matter which object you use among EyeCal, Eye2Cal, JoyCal and Joy2Cal to call them.
xy_pix = EyeCal.sig2pix(xy_sig, offset);  % this is a conjugation of sig2deg and deg2pix
xy_deg = EyeCal.pix2deg(xy_pix);
xy_pix = EyeCal.deg2pix(xy_deg);
xy_deg = EyeCal.subject2deg(xy);  % get the degree coordinates of a point on the subject screen
xy_pix = EyeCal.subject2pix(xy);
xy_deg = EyeCal.control2deg(xy);  % get the degree coordinates of a point on the control screen
xy_pix = EyeCal.control2pix(xy);
xy_deg = EyeCal.norm2deg(xy);
xy_pix = EyeCal.norm2pix(xy);
wh_deg = EyeCal.norm2size(wh);    % convert the normalized size (width & height) to visual degrees

In the scene framework, you can access Tracker's mlcalibrate object inside the adapter like the following.
classdef YourAdapter < mladapter
    properties
        Position
    end
    properties (SetAccess = protected)
        ScreenPosition
    end
    methods
        function obj = YourAdapter(varargin)
            obj = obj@mladapter(varargin{:});
        end
        function set.Position(obj,xy_deg)
            obj.Position = xy_deg;
            % If the tracker of the adapter chain is EyeTracker, obj.Tracker.CalFun indicates EyeCal.
            obj.ScreenPosition = obj.Tracker.CalFun.deg2pix(xy_deg);
        end
    end
end
Attachments:
open | download - coordinates.png (4.3 KB)

The National Institute of Mental Health (NIMH) is part of the National Institutes of Health (NIH), a component of the U.S. Department of Health and Human Services.