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

5 visualizaciones (últimos 30 días)
David Pesetsky
David Pesetsky el 1 de Ag. de 2015
Respondida: Sameed Quais el 23 de Dic. de 2019
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]);

Respuesta aceptada

Geoff Hayes
Geoff Hayes el 2 de Ag. de 2015
Editada: Geoff Hayes el 2 de Ag. de 2015
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 comentarios
Geoff Hayes
Geoff Hayes el 5 de Ag. de 2015
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 el 5 de Ag. de 2015
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

Iniciar sesión para comentar.

Más respuestas (1)

Sameed Quais
Sameed Quais el 23 de Dic. de 2019
Can anyone of you explain this same question to be solved by using guide instead of using the above call back program?

Categorías

Más información sobre Creating and Concatenating Matrices en Help Center y File Exchange.

Etiquetas

Community Treasure Hunt

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

Start Hunting!

Translated by