0
votes

Hello and pardon me if my english is a bit rusty. I'm trying to create a circle that moves along a parametric function (coordinates are stored in vectors). I have written a function for drawing the circle and I know that you can use the axis equal command in matlab in order to create a circle shape and avoid an ellipse. My problem is that when I do this the figure window becomes very wide relative to the plotted graph. Any input is appreciated.

MAIN CODE:

t = linspace(0,3);
x = 30*cos(pi/4)/2*(1-exp(-0.5*t));
y = (30*sin(pi/4)/2 + 9.81/0.5^2)*(1-exp(0.5*t)) - 9.81*t/0.5;

for i = 1:length(t)
   plot(x,y)
   axis equal
   hold on
   cirkel(x(i),y(i),1,1,'r') % argument #3 is the radius #4 is 1 for fill
   hold off                  
   pause(0.01)
end

CIRCLE CODE:

function cirkel(x,y,r,f,c)
angle = linspace(0, 2*pi, 360);
xp = x + r*cos(angle);
yp = y + r*sin(angle);
plot(x,y)
if f == 1 && nargin == 5
   fill(xp,yp,c)
end
2
It looks like this is working correctly. Axis equal changes the scale of the graph so you have equal proportions on both axes. When the range of the plot (y-axis extent) is much greater than the domain (x-axis extent), as it is with your plot, then MATLAB has to expand the x-axis to create the correct display ratio. This is all completely normal and expected behavior. If you want to keep the x-axis in the range [0,10] so you can see some graph curvature, then just plot your little "circle" as an ellipse, so that the scaling makes it look circular.gariepy

2 Answers

5
votes

When you call axis equal it makes one unit of the x axis be the same size as one unit of the y axis. You are seeing what you are because your y values span a much larger range than the x values.

One way to deal with this would be to query the aspect ratio and x/y limits of the current axes as shown in the second part of this answer. However, an easier approach is rather than using fill to plot your circle, you could instead use scatter with a circular marker which will be circular regardless of the aspect ratio of your axes.

t = linspace(0,3);
x = 30*cos(pi/4)/2*(1-exp(-0.5*t));
y = (30*sin(pi/4)/2 + 9.81/0.5^2)*(1-exp(0.5*t)) - 9.81*t/0.5;

% Plot the entire curve
hplot = plot(x, y);
hold on;

% Create a scatter plot where the area of the marker is 50. Store the handle to the plot
% in the variable hscatter so we can update the position inside of the loop
hscatter = scatter(x(1), y(1), 50, 'r', 'MarkerFaceColor', 'r');

for k = 1:length(t)
    % Update the location of the scatter plot
    set(hscatter, 'XData', x(k), ...    % Set the X Position of the circle to x(k)
                  'YData', y(k))        % Set the Y Position of the circle to y(k)

    % Refresh the plot
    drawnow
end

enter image description here

As a side note, it is best to update existing plot objects rather than creating new ones.

0
votes

If you want the small dot to appear circular, and you want to have a reasonable domain (x-axis extent), try this:

function cirkel(x,y,r,f,c)
angle = linspace(0, 2*pi, 360);
xp = x + 0.04*r*cos(angle);  %% adding scale factor of 0.04 to make it appear circular
yp = y + r*sin(angle);
plot(x,y)
if f == 1 && nargin == 5
   fill(xp,yp,c)
end

Note the addition of the scale factor in the computation of xp. If you want to automate this, you can add another parameter to cirkel(), let's call it s, that contains the scale factor. You can calculate the scale factor in your script by computing the ratio of the range to the domain (y extent divided by x extent).