Retrieve 3D location from clicked pixel / datatip position

I attached a copy of my code (I did not includes the images). My question is how would I retrieve the CIE Lab color coordinates pointed to by the mouse and the datatip on the 3D graph? Not sure which function to use best? I guess I have to setup a mouseclick callback function but I don't know whether I can access the datatip properties from that function? This screen capture shows what I'm trying to do :
On the right is the RGB image displayed in its own figure and the left is the 'loRes' corresponding data, in CIE Lab. When I click on an the existing points, in the scatter3 graph, with the mouse, I get a DataTip "baloon" showing the CIE Lab value pointed to by the mouse. Those are the values that I'm trying to retrieve and use as an index on the right figure, to be able to show the xy location with a marker? All I'm trying to accomplish is to allow students to select a point in the 3D space on the left and show them what the corresponding RGB color is.
I have tons of ideas but far too little Matlab knowledge...
Any help is appreciated.

6 Comments

DataTip documentation "Callbacks" says : ButtonDownFcn > Use this property to to execute code when you click the object. OK. So, first declare a figurehandle associated with the 3D figure ButtonDownFn. Then set the body of the callback function, with arguments :
set(figure3Dscatter,'ButtonDownFcn',@Image3DClickCallback);
function Image3DClickCallback (objectHandle, eventData)
Which properties am I looking for?
end
I'll continue looking online for sample code...
I execute my code with the new function callback and placed a breakpoint inside to be able to peek at the data, and this is what I get when I place the mouse on the eventData :
Is it the IntersectionPoint I'm after? I can see the [38 -81 27] vector makes total sens as it would represent an estimate of the CIE Lab 3D coordinates, which are b=38 a= -78 and L= 24 according to the datatip capture :
It's a good approximation and I'm sure I would not be too far off the real 3D location. But would there be a way to workaround the scatter 'default' behavior? You see, when the scatter initially displays, there is datatip, somewhere (is it the last point in the XYZ array?) that automatically comes up. I don't know how to disable that behavior (I already asked the question here, in the past, but did not get any direct reply). At any rate, what follows is that, 1) I click once on the round black 'dot', and as soon I do that, the datatip disappears? Then 2) I click a second time on what I think is the same round black dot, to trigger the ButtonDownFn callback. Then 3) I am taken to the callback function in the code, and all I see I have access to are what I captured above in the first yellow image. I still wonder whether it's possible to access the last state -- I guess -- of the Datatip? So that I get as close as possible to an exact match of an exiting 3D point.
I experimented with passing the DataTip handle as argument to the ButtonDownFcn this way :
set(handleScatter3D,'ButtonDownFcn',{@scatter3DClickCallback, handleDataTip});
end
function scatter3DClickCallback (objectHandle, eventData, handleDataTip)
% Roger = get(event_obj.Target, 'type')
Roger = get(eventData.Target, 'type')
% groot, axes handle, figure handle, any graphic object
dataTips = findall(groot, 'type', 'datatip');
dummy = 5
end
When I place a breakpoint on the first line of the callback function, and hover the mouse over the 'handleDataTip' in the argument list, I get this :
Which means "no cigar"? So by the time I clicked once to hide the datatip initially, when I click a second time at about the same 3D location, the datatip no longer exists? So I have to look for the answer somewhere else...
Update....
I modified the code this way :
set(handleScatter3D,'ButtonDownFcn',@scatter3DClickCallback);
end
function scatter3DClickCallback (objectHandle, eventData)
Selected3D_point = eventData.IntersectionPoint; % 37 -81 28
end
I can get the 3D location this way but having the ButtonDownFcn hardwired to this callback function completely disables "3D interactivity"? Once the figure displays, I can no longer rotate the view at all? The scatter no longer responds to mouse commands? Oh boy!
I guess I have to use a different method than using the figure's own 'ButtonDownFcn' for the purpose of "trapping" the cusror location?
How about responding to a right-mouse button click?
I'll look around...
My latest 'attempt' involves this code :
DataCursorMode1 = datacursormode(fig_3D);
set(DataCursorMode1,'Enable','on','UpdateFcn',@displayCoordinates)
end
function txt = displayCoordinates(~, info)
txt = {sprintf('CIE L: %.0f', info.Position(3)), sprintf('CIE a: %.0f', info.Position(1)), sprintf('CIE b: %.0f', info.Position(2))};
end
At least, using this 'solution', I'm in control of the order in which the values are displayed in the datatip :
Trouble is that, now, I lose all 'default' interactivity : no more Rotate3D functionality until I click on the Rotate3D button, and then I'm automatically "out" of the datacursor mode? I have to alternate between the 'interaction mode' and 'datacursor mode', it's not possible to have the two modes simultaneously active. I understand "why", this is so. Yes, I noticed that, when the mouse hovers empty areas of the graph, that the cursor turns back into a normal mouse pointer?

Sign in to comment.

 Accepted Answer

Not a "perfect" answer but I think it's 'workable'.
First, I added a pusbutton to the figure. Then I use this code, to obtain the display coordinates :
DataCursorMode1 = datacursormode(fig_3D);
set(DataCursorMode1,'Enable','on','UpdateFcn',@displayCoordinates)
Then in the callback function, I use this code :
function txt = displayCoordinates(~, info)
global clickedCIE_L clickedCIE_a clickedCIE_b;
clickedCIE_L = info.Position(3);
clickedCIE_a = info.Position(1);
clickedCIE_b = info.Position(2);
txt = {sprintf('CIE L: %.0f', info.Position(3)), sprintf('CIE a: %.0f', info.Position(1)), sprintf('CIE b: %.0f', info.Position(2))};
end
I know, "global variables"... but, have a heart. My projects will never be used for rocket launching...
This solution is not ideal but, as it stands, there is no way, with my level of (ahem!) Matlab 'mastery' to be able to intercept the datatips value when clicked with the mouse otherwise.
And I have to accept that I cannot be simultaneously in both datacursor mode and rotate3D mode. So it's a pain but, I'm satisfied that this is workable.

More Answers (0)

Categories

Products

Release

R2020b

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!