Как можно использовать ezplot в MATLAB для эффективного рисования неявных кривых и поверхностей?

Мне нужно нарисовать двухмерный эллипс, используя его общую форму (x-c)'A(x-c)=1

Я хотел бы знать, как сделать это эффективно в MATLAB, используя ezplot.


person twerdster    schedule 17.08.2012    source источник


Ответы (2)


Этот ответ применим практически к любой проблеме, которую можно сформулировать как неявную поверхность/кривую в MATLAB. Я собираюсь продемонстрировать это на эллипсе.

Краткая версия:

A = [5 4; 4 5]    
c = [1; 2]    
elFunc = @(A11,A22,A12,A21,c1,c2,x,y) (c1-x).*(A11*(c1-x)+A21*(c2-y))+(c2-y).*(A12*(c1-x)+A22*(c2-y))-1    
ezplot(@(x,y) elFunc(A(1,1),A(2,2),A(1,2),A(2,1),c(1),c(2),x,y), [0 2 0 4])

Длинная версия:

Эллипс можно неявно записать в его наиболее общей форме (для любого измерения) как

(x-c)'A(x-c) = 1 or (x-c)'A(x-c)-1 = 0

где x, c находятся в R ^ n, а A - матрица размера nxn.

Чтобы привести это в форму, которую может использовать MATLAB, мы можем использовать символьный набор инструментов. Для двумерного эллипса пишем:

syms A11 A12 A21 A22 c1 c2 x y real
impl = ([x y]-[c1 c2])*[A11 A12; A21 A22]*([x;y]-[c1;c2])-1

Это дает следующий результат:

(c1 - x)*(A11*(c1 - x) + A21*(c2 - y)) + (c2 - y)*(A12*(c1 - x) + A22*(c2 - y)) - 1

Нам больше не нужен символьный набор инструментов, поэтому мы просто копируем строку, векторизуем ее, добавляя версию оператора точки, и превращаем ее в функцию.

elFunc = @(A11,A22,A12,A21,c1,c2,x,y) (c1-x).*(A11*(c1-x)+A21*(c2-y))+(c2-y).*(A12*(c1-x)+A22*(c2-y))-1

Теперь мы можем использовать ezplot, чтобы нарисовать нашу кривую. ezplot предполагает, что когда вы даете ему дескриптор функции, он должен решить для func = 0, поэтому наша кривая уже описана elFunc в неявном формате. Все, что нам осталось сделать, это определить область, в которой мы хотим, чтобы ezplot попытался нарисовать кривую. Следующий пример демонстрирует результат:

A = [5 4; 4 5]    
    c = [1; 2]    
    elFunc = @(A11,A22,A12,A21,c1,c2,x,y) (c1-x).*(A11*(c1-x)+A21*(c2-y))+(c2-y).*(A12*(c1-x)+A22*(c2-y))-1    
    ezplot(@(x,y) elFunc(A(1,1),A(2,2),A(1,2),A(2,1),c(1),c(2),x,y), [0 2 0 4])

Эллипс, построенный ezplot в MATLAB

person twerdster    schedule 17.08.2012

Этот ответ точно такой же, как ответ @twerdster, за исключением того, что обозначения немного больше Matlabby:

A = [5 4; 4 5];
c = [1 2];

elFunc = @(x,y) sum(([x(:)-c(1) y(:)-c(2)] * A) .* [x(:)-c(1) y(:)-c(2)], 2) - 1;
ezplot(elFunc, [0 2 0 4])

И последнее замечание: как уже видно из обоих наших ответов, ezplot предназначен для вещей, которые просты в сюжете. Эллипс уже на грани того, чтобы быть достаточно «простым» для анонимных функций и ezplot.

В общем, я бы посоветовал вам избегать использования ezplot для чего-то более сложного, чем ezplot(@(x)sin(x).*cos(2*x)) или около того. Гораздо плодотворнее практиковаться и свободно говорить на function, plot(), surf() и друзьях.

person Rody Oldenhuis    schedule 17.08.2012
comment
Это действительно больше Matlabby :) - person twerdster; 17.08.2012
comment
+1 за указание на то, что ezplot не следует использовать для сложных (то есть реальных) целей построения графика. - person Egon; 17.08.2012