100 lines
3.6 KiB
Matlab
100 lines
3.6 KiB
Matlab
function selectPhaseDiagramPoints(PhaseDiagramMatrix, NumberOfAtoms, ScatteringLengths, savePath)
|
|
% Interactive point selector for phase diagram.
|
|
% - Single click to select a point (plotted in red)
|
|
% - Double click to remove nearest point
|
|
% - Save points to a MAT file using savePath
|
|
|
|
xlen = length(NumberOfAtoms);
|
|
ylen = length(ScatteringLengths);
|
|
|
|
selectedIndices = [];
|
|
selectedValues = [];
|
|
plottedPoints = []; % handles of plotted markers
|
|
|
|
% Create figure and axes
|
|
fig = figure('Name', 'Interactive Phase Diagram', 'Position', [100, 100, 1600, 900]);
|
|
ax = axes(fig);
|
|
imagesc(ax, PhaseDiagramMatrix);
|
|
set(ax, 'YDir', 'normal');
|
|
colormap(ax, parula);
|
|
colorbar(ax);
|
|
axis(ax, 'equal', 'tight');
|
|
hold(ax, 'on'); % This is crucial!
|
|
|
|
% Style
|
|
set(ax, 'FontSize', 16, 'Box', 'On', 'Linewidth', 2);
|
|
xticks(ax, 1:xlen);
|
|
yticks(ax, 1:ylen);
|
|
xticklabels(ax, string(NumberOfAtoms));
|
|
yticklabels(ax, string(ScatteringLengths));
|
|
xlabel(ax, 'Number of Atoms', 'FontSize', 16);
|
|
ylabel(ax, 'Scattering Length (\times a_o)', 'FontSize', 16);
|
|
grid(ax, 'on');
|
|
|
|
% Save Button
|
|
uicontrol('Style', 'pushbutton', ...
|
|
'String', 'Save Points', ...
|
|
'FontSize', 12, ...
|
|
'Position', [20 20 120 40], ...
|
|
'Callback', @savePoints);
|
|
|
|
% Set callback on axes, not on image
|
|
fig.WindowButtonDownFcn = @handleClick;
|
|
|
|
selectedIndices = zeros(0, 2); % ← ensure it's Nx2, not just []
|
|
selectedValues = zeros(0, 2);
|
|
plottedPoints = gobjects(0); % empty graphics array
|
|
|
|
|
|
function handleClick(~, ~)
|
|
try
|
|
clickType = get(fig, 'SelectionType');
|
|
cp = get(ax, 'CurrentPoint');
|
|
xClick = round(cp(1, 1));
|
|
yClick = round(cp(1, 2));
|
|
|
|
if xClick < 1 || xClick > xlen || yClick < 1 || yClick > ylen
|
|
return;
|
|
end
|
|
|
|
if strcmp(clickType, 'normal') % Single click = add point
|
|
alreadySelected = any(ismember(selectedIndices, [xClick, yClick], 'rows'));
|
|
if ~alreadySelected
|
|
selectedIndices(end+1, :) = [xClick, yClick];
|
|
selectedValues(end+1, :) = [NumberOfAtoms(xClick), ScatteringLengths(yClick)];
|
|
h = plot(ax, xClick, yClick, 'r*', 'MarkerSize', 10, 'LineWidth', 1.5);
|
|
plottedPoints(end+1) = h;
|
|
fprintf('Selected: N = %.2f, a = %.2f\n', NumberOfAtoms(xClick), ScatteringLengths(yClick));
|
|
end
|
|
|
|
elseif strcmp(clickType, 'open') % Double click = remove point
|
|
if isempty(selectedIndices), return; end
|
|
dists = vecnorm(selectedIndices - [xClick, yClick], 2, 2);
|
|
[minDist, idx] = min(dists);
|
|
if minDist <= 1
|
|
fprintf('Removed: N = %.2f, a = %.2f\n', selectedValues(idx,1), selectedValues(idx,2));
|
|
delete(plottedPoints(idx));
|
|
selectedIndices(idx, :) = [];
|
|
selectedValues(idx, :) = [];
|
|
plottedPoints(idx) = [];
|
|
end
|
|
end
|
|
|
|
catch ME
|
|
fprintf('Error in handleClick:\n%s\n', getReport(ME, 'extended'));
|
|
end
|
|
end
|
|
|
|
|
|
function savePoints(~, ~)
|
|
if isempty(selectedValues)
|
|
warndlg('No points selected.', 'Save Warning');
|
|
return;
|
|
end
|
|
SelectedPoints.indices = selectedIndices;
|
|
SelectedPoints.values = selectedValues;
|
|
save(savePath, 'SelectedPoints');
|
|
msgbox(sprintf('Saved %d points to:\n%s', size(selectedValues,1), savePath), 'Saved');
|
|
end
|
|
end
|