2016-04-07 6 views
1

Решение размещены ниже функции для построения бар 3 с отдельными х, у значений и отдельной значения ширины и высотыBar3 участок с отдельным х, у, значения высоты и ширины

bar3 (х, у, г, xWidth, yWidth)

в настоящее время мы работаем над проектом, который позволит визуализировать площадь под функцией 3D, ф (х, у). Целью этого является демонстрация того, как бары разрезают трехмерную поверхность. Косвенно визуализировать желаемый интеграл.

Мы хотим, чтобы штанги совпали с интервалами поверхности сетки. Ниже представлена ​​грубая демонстрация идеи.

example of idea

bar3 только имеет вход для X-значения bar3 (х, г), где, как прибой имеет вход для обоих х и у прибоя (х, у, г)

К сожалению, это то, что мы получаем. - это потому, что bar3 не могу быть с точки х и у

gui

КОД:

clc; 
cla; 
d=eval(get(handles.edtOuterUpperB,'string')); 
c=eval(get(handles.edtOuterLowerB,'string')); 
b=eval(get(handles.edtInnerUpperB,'string')); 
a=eval(get(handles.edtInnerLowerB,'string')); 

n=eval(get(handles.edtInnerInterval,'string')); 
m=eval(get(handles.edtOuterInterval,'string')); 

h=(b-a)/n; 
k=(d-c)/m; 

[x,y] = meshgrid(a:h:b, c:k:d); 
f=eval(get(handles.edtFunc,'string')); 
surf(x,y,f); 

hold on 
bar3(f,1); 

ответ

0

Мы нашли пользователь вклад функции scatterbar3, которая делает то, что мы хотим, по-другому, чем то, что использует bar3: http://www.mathworks.com/matlabcentral/fileexchange/1420-scatterbar3

Там была однако небольшая икотой, что мы пришлось исправить:

держаться на

scatterbar3 (x, y, f, h);

Рассеиватель3 не имеет отдельных входов для ширины и высоты стержней, поэтому большие промежутки возникают, когда интервалы не равны друг другу. Продемонстрировано ниже.

GUI-error

Таким образом, мы редактировали функцию scatterbar3 для того, чтобы принять и ширину и высоту стержней в качестве входных сигналов:

Под редакцией функции scatterbar3:

function scatterbar3(X,Y,Z,widthx,widthy) 

[r,c]=size(Z); 
for j=1:r, 
    for k=1:c, 
     if ~isnan(Z(j,k)) 
      drawbar(X(j,k),Y(j,k),Z(j,k),widthx/2,widthy/2) 
     end 
    end 
end 

zlim=[min(Z(:)) max(Z(:))]; 
if zlim(1)>0,zlim(1)=0;end 
if zlim(2)<0,zlim(2)=0;end 
axis([min(X(:))-widthx max(X(:))+widthx min(Y(:))-widthy max(Y(:))+widthy zlim]) 
caxis([min(Z(:)) max(Z(:))]) 

function drawbar(x,y,z,widthx,widthy) 

h(1)=patch([-widthx -widthx widthx widthx]+x,[-widthy widthy widthy -widthy]+y,[0 0 0 0],'b'); 
h(2)=patch(widthx.*[-1 -1 1 1]+x,widthy.*[-1 -1 -1 -1]+y,z.*[0 1 1 0],'b'); 
h(3)=patch(widthx.*[-1 -1 -1 -1]+x,widthy.*[-1 -1 1 1]+y,z.*[0 1 1 0],'b'); 
h(4)=patch([-widthx -widthx widthx widthx]+x,[-widthy widthy widthy -widthy]+y,[z z z z],'b'); 
h(5)=patch(widthx.*[-1 -1 1 1]+x,widthy.*[1 1 1 1]+y,z.*[0 1 1 0],'b'); 
h(6)=patch(widthx.*[1 1 1 1]+x,widthy.*[-1 -1 1 1]+y,z.*[0 1 1 0],'b'); 
set(h,'facecolor','flat','FaceVertexCData',z) 

Наконец, рабочий раствор в действии:

держать на

scatterbar3 (х, у, е, з, к);

working GUI 1

working GUI 2

0

Если вы внимательно посмотрите, вы увидите, что XData и YData разные от сетки до графика 3D-графика. Это связано с тем, что ваша сетка использует «реальные» значения x и y, в то время как график штрихов использует индексы для значений x и y.

Чтобы исправить это, вы захотите изменить тот или иной. Для вашего случая проще всего изменить поверхность. Фактически вы можете просто пропустить входы x и y, а индексированные значения x и y будут использоваться вместо этого по умолчанию при создании поверхности.

surf(f); 

Из документации для surf:

surf(Z) создает трехмерную затененной поверхности из компонентов г в матрице Z, используя x = 1:n и y = 1:m, где [m,n] = size(Z). Высота, Z, является однозначной функцией, определенной по геометрически прямоугольной сетке. Z указывает данные о цвете, а также высоту поверхности, поэтому цвет пропорционален высоте поверхности.

Update

Если вы хотите сохранить неиндексированное значение по осям х и у, вы хотите, чтобы преобразовать bar3 участок вместо этого. К сожалению, MATLAB дает возможность указать ось оси b не ось y.Вы можете взять один из двух подходов.

Изменение XData

Вы можете получить XData свойство полученных штриховых объектов и изменять их данные, которые вы хотите.

x = a:h:b; 
y = c:k:d; 

%// Anonymous function to scale things for us 
scaler = @(vals)x(1) + ((vals-1) * (x(end) - x(1))/(numel(x) - 1)); 

%// Create the bar plot 
bars = bar3(y, f); 

%// Change the XData 
xdata = get(bars, 'XData'); 
xdata = cellfun(scaler, xdata, 'uni', 0); 
set(bars, {'XData'}, xdata); 
set(gca, 'xtick', x) 

%// Now plot the surface 
surf(x,y,f); 

И просто чтобы показать, что это делает:

x = linspace(0.5, 1.5, 5); 
y = linspace(2.5, 4.5, 4); 

f = rand(4,5); 

scaler = @(vals)x(1) + ((vals-1) * (x(end) - x(1))/(numel(x) - 1)); 
bars = bar3(y, f); 


set(bars, {'XData'}, cellfun(scaler, get(bars, 'XData'), 'uni', 0)) 
set(gca, 'xtick', x) 
axis tight 

enter image description here

Изменение XTickLabels

Вместо изменения фактических данных о , можно просто изменить значения, отображаемые как wh вы хотите, чтобы они были скорее, чем индексированные значения.

x = a:h:b; 
y = c:k:d; 
labels = arrayfun(@(x)sprintf('%.2f', x), x, 'uni', 0); 
bar3(y, f); 
set(gca, 'xtick', 1:numel(x), 'xticklabels', labels); 
hold on 

%// Make sure to use the INDEX values for the x variable 
surf(1:numel(x), y, f); 

enter image description here

+0

Спасибо за вас вклад, к сожалению, потому что мы графики двойного интеграла мы должны иметь й и у интервалов с различными границами и расстоянием. Это можно увидеть в нашем графическом интерфейсе.Таким образом, мы будем требовать, чтобы функция bar3 использовала «реальные» значения x и y. Это возможно? – Msegling

+0

@Msegling Я обновил ответ двумя подходами, чтобы дать вам то, что вам нужно. – Suever

+0

Большое вам спасибо за ваш вклад, это определенно помогло в конечном решении. Посмотрите, что мы придумали, сообщите нам, есть ли что-нибудь, что мы могли бы приспособить. – Msegling

Смежные вопросы