MATLAB Language
Dibujo
Buscar..
Círculos
La opción más fácil para dibujar un círculo es, obviamente, la función de rectangle
.
%// radius
r = 2;
%// center
c = [3 3];
pos = [c-r 2*r 2*r];
rectangle('Position',pos,'Curvature',[1 1])
axis equal
¡Pero la curvatura del rectángulo se debe establecer en 1 !
El vector de position
define el rectángulo, los dos primeros valores x
e y
son la esquina inferior izquierda del rectángulo. Los dos últimos valores definen el ancho y la altura del rectángulo.
pos = [ [x y] width height ]
La esquina inferior izquierda del círculo, sí, este círculo tiene esquinas, aunque imaginarias, es el centro c = [3 3]
menos el radio r = 2
que es [xy] = [1 1]
. El ancho y la altura son iguales al diámetro del círculo, entonces el width = 2*r; height = width;
En caso de que la suavidad de la solución anterior no sea suficiente, no hay manera de evitar el uso de la forma obvia de dibujar un círculo real mediante el uso de funciones trigonométricas .
%// number of points
n = 1000;
%// running variable
t = linspace(0,2*pi,n);
x = c(1) + r*sin(t);
y = c(2) + r*cos(t);
%// draw line
line(x,y)
%// or draw polygon if you want to fill it with color
%// fill(x,y,[1,1,1])
axis equal
Flechas
En primer lugar, uno puede usar el quiver
, en el que no tiene que lidiar con unidades de figuras no normalizadas mediante el uso de annotation
drawArrow = @(x,y) quiver( x(1),y(1),x(2)-x(1),y(2)-y(1),0 )
x1 = [10 30];
y1 = [10 30];
drawArrow(x1,y1); hold on
x2 = [25 15];
y2 = [15 25];
drawArrow(x2,y2)
Importante es el quinto argumento de quiver
: 0 que deshabilita una escala por defecto, ya que esta función se usa generalmente para trazar campos vectoriales. (o use el par de valores de propiedad 'AutoScale','off'
)
También se pueden agregar características adicionales:
drawArrow = @(x,y,varargin) quiver( x(1),y(1),x(2)-x(1),y(2)-y(1),0, varargin{:} )
drawArrow(x1,y1); hold on
drawArrow(x2,y2,'linewidth',3,'color','r')
Si se desean diferentes puntas de flecha, es necesario usar anotaciones (esta respuesta puede ser útil. ¿Cómo cambio el estilo de la punta de flecha en el diagrama de carcaj? ).
El tamaño de la punta de flecha se puede ajustar con la propiedad 'MaxHeadSize'
. No es consistente por desgracia. Los límites de los ejes deben establecerse después.
x1 = [10 30];
y1 = [10 30];
drawArrow(x1,y1,{'MaxHeadSize',0.8,'Color','b','LineWidth',3}); hold on
x2 = [25 15];
y2 = [15 25];
drawArrow(x2,y2,{'MaxHeadSize',10,'Color','r','LineWidth',3}); hold on
xlim([1, 100])
ylim([1, 100])
Hay otro tweak para cabezas de flecha ajustables:
function [ h ] = drawArrow( x,y,xlimits,ylimits,props )
xlim(xlimits)
ylim(ylimits)
h = annotation('arrow');
set(h,'parent', gca, ...
'position', [x(1),y(1),x(2)-x(1),y(2)-y(1)], ...
'HeadLength', 10, 'HeadWidth', 10, 'HeadStyle', 'cback1', ...
props{:} );
end
que puede llamar desde su script de la siguiente manera:
drawArrow(x1,y1,[1, 100],[1, 100],{'Color','b','LineWidth',3}); hold on
drawArrow(x2,y2,[1, 100],[1, 100],{'Color','r','LineWidth',3}); hold on
Elipse
Para trazar una elipse puedes usar su ecuación . Una elipse tiene un eje mayor y otro menor. También queremos poder trazar la elipse en diferentes puntos centrales. Por lo tanto escribimos una función cuyas entradas y salidas son:
Inputs:
r1,r2: major and minor axis respectively
C: center of the ellipse (cx,cy)
Output:
[x,y]: points on the circumference of the ellipse
Puede usar la siguiente función para obtener los puntos en una elipse y luego trazar esos puntos.
function [x,y] = getEllipse(r1,r2,C)
beta = linspace(0,2*pi,100);
x = r1*cos(beta) - r2*sin(beta);
y = r1*cos(beta) + r2*sin(beta);
x = x + C(1,1);
y = y + C(1,2);
end
Ejemplo:
[x,y] = getEllipse(1,0.3,[2 3]);
plot(x,y);
Polígono (s)
Cree vectores para contener las ubicaciones x e y de los vértices, alimente estos en el patch
.
Polígono único
X=rand(1,4); Y=rand(1,4);
h=patch(X,Y,'red');
Poligonos multiples
Los vértices de cada polígono ocupan una columna de cada uno de X
, Y
X=rand(4,3); Y=rand(4,3);
for i=2:3
X(:,i)=X(:,i)+(i-1); % create horizontal offsets for visibility
end
h=patch(X,Y,'red');
Parcela pseudo 4D
Una matriz (mxn)
puede estar representada por una superficie usando surf ;
El color de la superficie se establece automáticamente como función de los valores en la matriz (mxn)
. Si no se especifica el mapa de colores , se aplica el predeterminado.
Se puede agregar una barra de colores para mostrar el mapa de colores actual e indicar la asignación de valores de datos en el mapa de colores.
En el siguiente ejemplo, la matriz z (mxn)
es generada por la función:
z=x.*y.*sin(x).*cos(y);
en el intervalo [-pi,pi]
. Los valores de x
e y
se pueden generar mediante la función meshgrid y la superficie se representa de la siguiente manera:
% Create a Figure
figure
% Generate the `x` and `y` values in the interval `[-pi,pi]`
[x,y] = meshgrid([-pi:.2:pi],[-pi:.2:pi]);
% Evaluate the function over the selected interval
z=x.*y.*sin(x).*cos(y);
% Use surf to plot the surface
S=surf(x,y,z);
xlabel('X Axis');
ylabel('Y Axis');
zlabel('Z Axis');
grid minor
colormap('hot')
colorbar
Figura 1
Ahora podría darse el caso de que información adicional esté vinculada a los valores de la matriz z
y se almacene en otra matriz (mxn)
Es posible agregar esta información adicional en el gráfico modificando la forma en que se colorea la superficie.
Esto permitirá tener un poco de gráfico 4D: a la representación 3D de la superficie generada por la primera matriz (mxn)
, la cuarta dimensión estará representada por los datos contenidos en la segunda matriz (mxn)
.
Es posible crear dicha trama llamando a surf
con 4 entradas:
surf(x,y,z,C)
donde el parámetro C
es la segunda matriz (que debe ser del mismo tamaño de z
) y se utiliza para definir el color de la superficie.
En el siguiente ejemplo, la matriz C
es generada por la función:
C=10*sin(0.5*(x.^2.+y.^2))*33;
sobre el intervalo [-pi,pi]
La superficie generada por C
es
Figura 2
Ahora podemos llamar surf
con cuatro entradas:
figure
surf(x,y,z,C)
% shading interp
xlabel('X Axis');
ylabel('Y Axis');
zlabel('Z Axis');
grid minor
colormap('hot')
colorbar
figura 3
Comparando la Figura 1 y la Figura 3, podemos notar que:
- la forma de la superficie corresponde a los valores
z
(la primera matriz(mxn)
) - el color de la superficie (y su rango, dado por la barra de colores) corresponde a los valores
C
(la primera matriz(mxn)
)
Figura 4
Por supuesto, es posible intercambiar z
y C
en la gráfica para tener la forma de la superficie dada por la matriz C
y el color dado por la matriz z
:
figure
surf(x,y,C,z)
% shading interp
xlabel('X Axis');
ylabel('Y Axis');
zlabel('Z Axis');
grid minor
colormap('hot')
colorbar
y comparar la Figura 2 con la Figura 4
Dibujo rapido
Hay tres formas principales de hacer una trama o animaciones secuenciales: plot(x,y)
, set(h , 'XData' , y, 'YData' , y)
y animatedline
. Si desea que su animación sea fluida, necesita un dibujo eficiente y los tres métodos no son equivalentes.
% Plot a sin with increasing phase shift in 500 steps
x = linspace(0 , 2*pi , 100);
figure
tic
for thetha = linspace(0 , 10*pi , 500)
y = sin(x + thetha);
plot(x,y)
drawnow
end
toc
Obtengo 5.278172 seconds
. La función de trazado básicamente elimina y recrea el objeto de línea cada vez. Una forma más eficiente de actualizar un gráfico es usar las propiedades XData
y YData
del objeto Line
.
tic
h = []; % Handle of line object
for thetha = linspace(0 , 10*pi , 500)
y = sin(x + thetha);
if isempty(h)
% If Line still does not exist, create it
h = plot(x,y);
else
% If Line exists, update it
set(h , 'YData' , y)
end
drawnow
end
toc
Ahora tengo 2.741996 seconds
, ¡mucho mejor!
animatedline
es una función relativamente nueva, introducida en 2014b. Veamos cómo le va:
tic
h = animatedline;
for thetha = linspace(0 , 10*pi , 500)
y = sin(x + thetha);
clearpoints(h)
addpoints(h , x , y)
drawnow
end
toc
3.360569 seconds
, no tan bueno como actualizar una gráfica existente, pero aún mejor que la plot(x,y)
.
Por supuesto, si tiene que trazar una sola línea, como en este ejemplo, los tres métodos son casi equivalentes y dan animaciones suaves. Pero si tiene trazados más complejos, la actualización de los objetos de Line
existentes hará una diferencia.