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

5 Ansichten (letzte 30 Tage)
David Pesetsky
David Pesetsky am 1 Aug. 2015
Beantwortet: Sameed Quais am 23 Dez. 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]);

Akzeptierte Antwort

Geoff Hayes
Geoff Hayes am 2 Aug. 2015
Bearbeitet: Geoff Hayes am 2 Aug. 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 Kommentare
Geoff Hayes
Geoff Hayes am 5 Aug. 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 am 5 Aug. 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

Melden Sie sich an, um zu kommentieren.

Weitere Antworten (1)

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

Kategorien

Mehr zu Creating and Concatenating Matrices finden Sie in Help Center und File Exchange

Community Treasure Hunt

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

Start Hunting!

Translated by