Move a scatter3 3D point around using a GUI slider?

조회 수: 5 (최근 30일)
David Pesetsky
David Pesetsky 2015년 8월 1일
답변: Sameed Quais 2019년 12월 23일
Hello,
I placed a 3D point near a surface using scatter3 (in Matlab2012a), and would like to add a slider that can move that point around. I see an example for 2015a that uses updateSystem, but I don't seem to have that: http://www.mathworks.com/help/control/ug/build-app-with-interactive-plot-updates.html
I believe it should be do-able in 2012a...
Here's the code I have so far that makes the surface, and plots a few scatter3 points. It's the point with s= that I would like to move around. I managed only to place 2 sliders so far on the GUI. The plan is to hook slider b up to r, and slider b1 up to x. Hopefully then scatter3 point s moves around.
echo OFF ALL;
f = figure;
[X,Y,Z] = sphere(200);
Z(Z < 0.0) = NaN;
X(X < 0.0) = NaN;
Y(Y < 0.0) = NaN;
quarterSphere = surf(X,Y,Z);
set(quarterSphere,'FaceColor',[0 0 0],'FaceAlpha',0.3,'EdgeColor',[0 0 0],'EdgeAlpha',0.1);
hold on;
% sample calc to place a point on the 1/4 sphere, in any location
r = 0.99; % radius in a plane to get y for a given x, where x <= r
x = 0.1; % x distance within r circle
if x > r
% h = msgbox('x must be <= r');
error('x must be <= r');
end
y=sqrt(r^2-x^2);
z=sqrt(1-x^2-y^2);
s = scatter3(x,y,z,50,[1 0 0],'filled');
scatter3(.5,.5,.5,50,[0 0 0],'filled'); % NPI
scatter3(.6,.8,.2,50,[0 1 0],'filled'); % high Vavg, low CTI
scatter3(.6,.2,.8,50,[0 1 0],'filled'); % low Vavg, high CTI
scatter3(.8,.6,.2,50,[1 1 0],'filled'); % high density, low CTI
scatter3(.2,.6,.8,50,[1 1 0],'filled'); % low density, high CTI
scatter3(.8,.2,.6,50,[0 1 1],'filled'); % high density, low Vavg
scatter3(.2,.8,.6,50,[0 1 1],'filled'); % low density, high Vavg
hold off;
xlabel('density');
ylabel('Vavg');
zlabel('CTI');
view([1 0 0]);
axis square;
b = uicontrol('Parent',f,'Style','slider','units','normalized','Position',[0,.005,.5,.01],'value',x, 'min',0, 'max',1);
blabel = uicontrol('Parent',f,'Style','text','string','r','units','normalized','Position',[0.25,.015,.02,.03]);
b1 = uicontrol('Parent',f,'Style','slider','units','normalized','Position',[.5,.005,.5,.01],'value',x, 'min',0, 'max',1);
b1label = uicontrol('Parent',f,'Style','text','string','x','units','normalized','Position',[0.75,.015,.02,.03]);

채택된 답변

Geoff Hayes
Geoff Hayes 2015년 8월 2일
편집: Geoff Hayes 2015년 8월 2일
David - you need to assign a callback to each of your sliders. Try the following - wrap all of your above code in a function block so that you can nest a local function within it. Something like
function myFunction
echo OFF ALL;
f = figure;
[X,Y,Z] = sphere(200);
Z(Z < 0.0) = NaN;
X(X < 0.0) = NaN;
Y(Y < 0.0) = NaN;
% etc.
end
Now assign a callback to each of your sliders as
b = uicontrol('Parent',f,'Style','slider','units','normalized',...
'Position', [0,.005,.5,.01],'value',r, 'min',0, 'max',1, ...
'Callback', {@update3DPointS});
blabel = uicontrol('Parent',f,'Style','text','string','r',...
'units','normalized','Position',[0.25,.015,.02,.03]);
b1 = uicontrol('Parent',f,'Style','slider','units','normalized',...
'Position', [.5,.005,.5,.01],'value',x, 'min',0, 'max',1, ...
'Callback', {@update3DPointS});
b1label = uicontrol('Parent',f,'Style','text','string','x','units', ...
'normalized','Position',[0.75,.015,.02,.03]);
Now nest your callback within the main function block as
function update3DPointS(~,~)
r = get(b,'Value');
x = get(b1, 'Value');
y=sqrt(r^2-x^2);
z=sqrt(1-x^2-y^2);
set(s,'XData',x,'YData',y,'ZData',z);
end
Now run your code and see what happens. Whenever you press one of the arrows at either end of either slider, then the red dot will update its position. See the attached code for an example.
  댓글 수: 6
Geoff Hayes
Geoff Hayes 2015년 8월 5일
David - you probably want to have either a minimum value that r can be (maybe zero doesn't make sense) or a maximum that x can be so that it can't go to zero.
David Pesetsky
David Pesetsky 2015년 8월 5일
Yep. That works perfectly now.
function update3DPointS(~,~)
r = get(b,'Value');
x = get(b1, 'Value');
if r == 0
r = 0.0001;
set(b, 'Value', r);
end
if x > r
set(b1, 'Value', r);
end
set(b1, 'max', r);
y=sqrt(r^2-x^2);
z=sqrt(1-x^2-y^2);
set(s,'XData',x,'YData',y,'ZData',z);
end

댓글을 달려면 로그인하십시오.

추가 답변 (1개)

Sameed Quais
Sameed Quais 2019년 12월 23일
Can anyone of you explain this same question to be solved by using guide instead of using the above call back program?

카테고리

Help CenterFile Exchange에서 Creating and Concatenating Matrices에 대해 자세히 알아보기

Community Treasure Hunt

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

Start Hunting!

Translated by