views:

402

answers:

2

If I get coordinates via

coords = get(0,'PointerLocation');

How can I convert them into points gotten via ginput?

i.e, I would like to get the same values from

coords = get(0,'PointerLocation');
coords=someConversion(coords);

As I would have gotten by calling

coords=ginput(1);

And clicking inside the figure in the same spot as the mouse was in the previous bit of code.

A: 

You can get the figure's position using getpixelposition(gcf) and then subtract the first 2 elements (x,y of the lower-left corner) from the PointerLocation to get the relative figure location.

For more complex transformation (e.g., relative to some internal panel or axes) you may possibly need to recursively fetch the relative positions of the sub-components. Look at pixelposition.m or moveptr.m for some examples.

Yair Altman
+4  A: 

Here's an example of how you can do this conversion...

Let's say you have a figure, and that figure contains an axes object with handle hAxes. Using the function GINPUT would allow you to select points within the axes. To get an equivalent set of points from get(0,'PointerLocation'), which gives coordinates in relation to the screen, you have to account for the figure position, axes position, axes width/height, and axes limits.

Doing this is tricky because you want to have the position measures in the same units. If you want to compute everything in units of pixels, this means you'd have to set the 'Units' properties of the objects to 'pixels', get the positions, then set the 'Units' properties back to what they previously were. I usually make my own function get_in_units to do this part:

function value = get_in_units(hObject,propName,unitType)

  oldUnits = get(hObject,'Units');  %# Get the current units for hObject
  set(hObject,'Units',unitType);    %# Set the units to unitType
  value = get(hObject,propName);    %# Get the propName property of hObject
  set(hObject,'Units',oldUnits);    %# Restore the previous units

end

Using the above function, you can make another function get_coords which gets the screen coordinates and converts them to axes coordinates:

function coords = get_coords(hAxes)

  %# Get the screen coordinates:
  coords = get_in_units(0,'PointerLocation','pixels');

  %# Get the figure position, axes position, and axes limits:
  hFigure = get(hAxes,'Parent');
  figurePos = get_in_units(hFigure,'Position','pixels');
  axesPos = get_in_units(hAxes,'Position','pixels');
  axesLimits = [get(hAxes,'XLim').' get(hAxes,'YLim').'];

  %# Compute an offset and scaling for coords:
  offset = figurePos(1:2)+axesPos(1:2);
  axesScale = diff(axesLimits)./axesPos(3:4);

  %# Apply the offsets and scaling:
  coords = (coords-offset).*axesScale+axesLimits(1,:);

end

The resulting coords should be close to those you would get from using GINPUT. Note that if the axes object is nested within any uipanel objects in the figure, you will have to account for the panel positions as well.


Example:

To illustrate the behavior of the above code, here's a neat little example. After creating the above functions, create this third function:

function axes_coord_motion_fcn(src,event,hAxes)

  coords = get_coords(hAxes);            %# Get the axes coordinates
  plot(hAxes,coords(1),coords(2),'r*');  %# Plot a red asterisk

end

Then run the following code:

hFigure = figure;  %# Create a figure window
hAxes = axes;      %# Create an axes in that figure
axis([0 1 0 1]);   %# Fix the axes limits to span from 0 to 1 for x and y
hold on;           %# Add new plots to the existing axes
set(hFigure,'WindowButtonMotionFcn',...  %# Set the WindowButtonMotionFcn so
    {@axes_coord_motion_fcn,hAxes});     %#   that the given function is called
                                         %#   for every mouse movement

And when you move the mouse pointer over the figure axes, you should see a trail of red asterisks being plotted behind it, like so:

alt text

gnovice