Plot equally spaced markers along a spiral - matlab

I want to move a red star marker along the spiral trajectory with an equal distance of 5 units between the red star points on its circumference like in the below image.
vertspacing = 10;
horzspacing = 10;
thetamax = 10*pi;
% Calculation of (x,y) - underlying archimedean spiral.
b = vertspacing/2/pi;
theta = 0:0.01:thetamax;
x = b*theta.*cos(theta)+50;
y = b*theta.*sin(theta)+50;
% Calculation of equidistant (xi,yi) points on spiral.
smax = 0.5*b*thetamax.*thetamax;
s = 0:horzspacing:smax;
thetai = sqrt(2*s/b);
xi = b*thetai.*cos(thetai);
yi = b*thetai.*sin(thetai);
plot(x,y,'b-');
hold on
I want to get a figure that looks like the following:
This is my code for the circle trajectory:
% Initialization steps.
format long g;
format compact;
fontSize = 20;
r1 = 50;
r2 = 35;
r3= 20;
xc = 50;
yc = 50;
% Since arclength = radius * (angle in radians),
% (angle in radians) = arclength / radius = 5 / radius.
deltaAngle1 = 5 / r1;
deltaAngle2 = 5 / r2;
deltaAngle3 = 5 / r3;
theta1 = 0 : deltaAngle1 : (2 * pi);
theta2 = 0 : deltaAngle2 : (2 * pi);
theta3 = 0 : deltaAngle3 : (2 * pi);
x1 = r1*cos(theta1) + xc;
y1 = r1*sin(theta1) + yc;
x2 = r2*cos(theta2) + xc;
y2 = r2*sin(theta2) + yc;
x3 = r3*cos(theta3) + xc;
y3 = r3*sin(theta3) + yc;
plot(x1,y1,'color',[1 0.5 0])
hold on
plot(x2,y2,'color',[1 0.5 0])
hold on
plot(x3,y3,'color',[1 0.5 0])
hold on
% Connecting Line:
plot([70 100], [50 50],'color',[1 0.5 0])
% Set up figure properties:
% Enlarge figure to full screen.
set(gcf, 'Units', 'Normalized', 'OuterPosition', [0, 0, 1, 1]);
drawnow;
axis square;
for i = 1 : length(theta1)
plot(x1(i),y1(i),'r*')
pause(0.1)
end
for i = 1 : length(theta2)
plot(x2(i),y2(i),'r*')
pause(0.1)
end
for i = 1 : length(theta3)
plot(x3(i),y3(i),'r*')
pause(0.1)
end

I can't think of a way to compute distance along a spiral, so I'm approximating it with circles, in hopes that it will still be useful.
My solution relies on the InterX function from FEX, to find the intersection of circles with the spiral. I am providing an animation so it is easier to understand.
The code (tested on R2017a):
function [x,y,xi,yi] = q44916610(doPlot)
%% Input handling:
if nargin < 1 || isempty(doPlot)
doPlot = false;
end
%% Initialization:
origin = [50,50];
vertspacing = 10;
thetamax = 5*(2*pi);
%% Calculation of (x,y) - underlying archimedean spiral.
b = vertspacing/(2*pi);
theta = 0:0.01:thetamax;
x = b*theta.*cos(theta) + origin(1);
y = b*theta.*sin(theta) + origin(2);
%% Calculation of equidistant (xi,yi) points on spiral.
DST = 5; cRes = 360;
numPts = ceil(vertspacing*thetamax); % Preallocation
[xi,yi] = deal(NaN(numPts,1));
if doPlot && isHG2() % Plots are only enabled if the MATLAB version is new enough.
figure(); plot(x,y,'b-'); hold on; axis equal; grid on; grid minor;
hAx = gca; hAx.XLim = [-5 105]; hAx.YLim = [-5 105];
hP = plot(xi,yi,'r*');
else
hP = struct('XData',xi,'YData',yi);
end
hP.XData(1) = origin(1); hP.YData(1) = origin(2);
for ind = 2:numPts
P = InterX([x;y], makeCircle([hP.XData(ind-1),hP.YData(ind-1)],DST/2,cRes));
[~,I] = max(abs(P(1,:)-origin(1)+1i*(P(2,:)-origin(2))));
if doPlot, pause(0.1); end
hP.XData(ind) = P(1,I); hP.YData(ind) = P(2,I);
if doPlot, pause(0.1); delete(hAx.Children(1)); end
end
xi = hP.XData(~isnan(hP.XData)); yi = hP.YData(~isnan(hP.YData));
%% Nested function(s):
function [XY] = makeCircle(cnt, R, nPts)
P = (cnt(1)+1i*cnt(2))+R*exp(linspace(0,1,nPts)*pi*2i);
if doPlot, plot(P,'Color',lines(1)); end
XY = [real(P); imag(P)];
end
end
%% Local function(s):
function tf = isHG2()
try
tf = ~verLessThan('MATLAB', '8.4');
catch
tf = false;
end
end
function P = InterX(L1,varargin)
% DOCUMENTATION REMOVED. For a full version go to:
% https://www.mathworks.com/matlabcentral/fileexchange/22441-curve-intersections
narginchk(1,2);
if nargin == 1
L2 = L1; hF = #lt; %...Avoid the inclusion of common points
else
L2 = varargin{1}; hF = #le;
end
%...Preliminary stuff
x1 = L1(1,:)'; x2 = L2(1,:);
y1 = L1(2,:)'; y2 = L2(2,:);
dx1 = diff(x1); dy1 = diff(y1);
dx2 = diff(x2); dy2 = diff(y2);
%...Determine 'signed distances'
S1 = dx1.*y1(1:end-1) - dy1.*x1(1:end-1);
S2 = dx2.*y2(1:end-1) - dy2.*x2(1:end-1);
C1 = feval(hF,D(bsxfun(#times,dx1,y2)-bsxfun(#times,dy1,x2),S1),0);
C2 = feval(hF,D((bsxfun(#times,y1,dx2)-bsxfun(#times,x1,dy2))',S2'),0)';
%...Obtain the segments where an intersection is expected
[i,j] = find(C1 & C2);
if isempty(i), P = zeros(2,0); return; end
%...Transpose and prepare for output
i=i'; dx2=dx2'; dy2=dy2'; S2 = S2';
L = dy2(j).*dx1(i) - dy1(i).*dx2(j);
i = i(L~=0); j=j(L~=0); L=L(L~=0); %...Avoid divisions by 0
%...Solve system of eqs to get the common points
P = unique([dx2(j).*S1(i) - dx1(i).*S2(j), ...
dy2(j).*S1(i) - dy1(i).*S2(j)]./[L L],'rows')';
function u = D(x,y)
u = bsxfun(#minus,x(:,1:end-1),y).*bsxfun(#minus,x(:,2:end),y);
end
end
Result:
Note that in the animation above, the diameter of the circle (and hence the distance between the red points) is 10 and not 5.

Related

Closing the figure window causes a new figure window to open

This is a analog clock. It runs perfectly. But once I close the clock, another figure opens up, and only the clock hands show. This makes it difficult to stop the program. How can I stop the program?
x=0;y=0;r=10;
hold on;
theta = 0:pi/60:2*pi;
xc = r * cos(theta);
yc = r * sin(theta);
h = plot(xc,yc,'r','linewidth',4);
axis off
r=9; i=1;
set(gca,'FontWeight','bold');
for theta = pi/6: pi/6: 2*pi
y1 = r * cos(theta);
x1 = r * sin(theta);
plot([x1/9*8 x1/9*7],[y1/9*8 y1/9*7],'color',[0 0 1])
text(x1/9*9.5,y1/9*9.5,num2str(i),'color',[0 0 1]);
i=i+1;
end
for theta=pi/30 : pi/30 : 2*pi
y1 = 10 * cos(theta);
x1 = 10 * sin(theta);
plot([x1/9*8 x1/9*7],[y1/9*8 y1/9*7],'color',[0 0 0])
end
while(1)
tic
c = clock;
c = c(1,4:6);
minute =c(1,2); sec=c(1,3);
if (c(1,1)>12)
hr = c(1,1)-12;
else
hr = c(1,1);
end
min1 = ceil(minute/12);
theta = (hr*pi)/6 + (min1*pi)/30;
f=figure(1); hold on;
y1 = 3 * cos(theta); Yhr = [0 y1];
x1 = 3 * sin(theta); Xhr = [0 x1];
hrhnd=plot(Xhr,Yhr);hold on;
theta1 = (minute*pi)/30;
y2 = 4.5 * cos(theta1); Ymin = [0 y2];
x2 = 4.5 * sin(theta1); Xmin = [0 x2];
minhnd=plot(Xmin,Ymin);
theta2 = (sec*pi)/30;
y3 = 5 * cos(theta2); Ysec = [0 y3];
x3 = 5 * sin(theta2); Xsec = [0 x3];
sechnd=plot(Xsec,Ysec);
z=toc;
pause(1-z);
delete(sechnd);
delete(minhnd);
delete(hrhnd);
end
The simplest way to stop the script when you close the window is to have the script test inside its loop if the window still exists.
We start the script by creating a figure window and recording its handle:
fig = figure;
Next, in the loop, we check to see if the window still exists using ishandle:
while(ishandle(fig))
...
end
The full program:
x=0;y=0;r=10;
fig = figure; %!!! NEW LINE
hold on;
theta = 0:pi/60:2*pi;
xc = r * cos(theta);
yc = r * sin(theta);
h = plot(xc,yc,'r','linewidth',4);
axis off
r=9; i=1;
set(gca,'FontWeight','bold');
for theta = pi/6: pi/6: 2*pi
y1 = r * cos(theta);
x1 = r * sin(theta);
plot([x1/9*8 x1/9*7],[y1/9*8 y1/9*7],'color',[0 0 1])
text(x1/9*9.5,y1/9*9.5,num2str(i),'color',[0 0 1]);
i=i+1;
end
for theta=pi/30 : pi/30 : 2*pi
y1 = 10 * cos(theta);
x1 = 10 * sin(theta);
plot([x1/9*8 x1/9*7],[y1/9*8 y1/9*7],'color',[0 0 0])
end
while(ishandle(fig)) %!!! UPDATED LINE
tic
c = clock;
c = c(1,4:6);
minute =c(1,2); sec=c(1,3);
if (c(1,1)>12)
hr = c(1,1)-12;
else
hr = c(1,1);
end
min1 = ceil(minute/12);
theta = (hr*pi)/6 + (min1*pi)/30;
f=figure(1); hold on;
y1 = 3 * cos(theta); Yhr = [0 y1];
x1 = 3 * sin(theta); Xhr = [0 x1];
hrhnd=plot(Xhr,Yhr);hold on;
theta1 = (minute*pi)/30;
y2 = 4.5 * cos(theta1); Ymin = [0 y2];
x2 = 4.5 * sin(theta1); Xmin = [0 x2];
minhnd=plot(Xmin,Ymin);
theta2 = (sec*pi)/30;
y3 = 5 * cos(theta2); Ysec = [0 y3];
x3 = 5 * sin(theta2); Xsec = [0 x3];
sechnd=plot(Xsec,Ysec);
z=toc;
pause(1-z);
delete(sechnd);
delete(minhnd);
delete(hrhnd);
end
You could improve your program by not deleting and re-drawing the hands, but updating their position. You'd do hrhnd=plot(Xhr,Yhr); before the loop, to draw the hand in its initial position, and then set(hrhnd,'XData',Xhr,'YData', Yhr) to update its position.
You could also do axis equal after drawing the clock face, to ensure it is round.
Note that you only need to give hold on once at the top, it is not needed after every plot command.

Line with NumericRuler-properties in Matlab

I want to create a relative axis in Matlab like the $\Delta I$-rulers in the following plot.
Before I start writing up a function that constructs it manually, I would like to know if there's way of creating an object with the NumericRuler-properties (like the default axes of a figure())
So I ended up using the link provided by Sardar Usama's comment as inspiration and wrote a function to create an axes-object relative to the values of a "parent"-axes:
function ax = create_value_axes(hAx, pos)
%% ax = create_value_axes(hAx, pos)
%
% Create axes at the value points of hAx.
%
% pos(1) = x-position
% pos(2) = y-position
% pos(3) = x-width
% pos(4) = y-width
%
% Get "parent" position and value limits
hAx_pos = hAx.Position;
hAx_xlm = hAx.XLim;
hAx_ylm = hAx.YLim;
% Get relative position increment pr value increment
x_step = hAx_pos(3) / (hAx_xlm(2) - hAx_xlm(1));
y_step = hAx_pos(4) / (hAx_ylm(2) - hAx_ylm(1));
% Set position
subaxes_abs_pos(1) = (pos(1)-hAx_xlm(1)) * x_step + hAx_pos(1);
subaxes_abs_pos(2) = (pos(2)-hAx_ylm(1)) * y_step + hAx_pos(2);
subaxes_abs_pos(3) = pos(3) * x_step;
subaxes_abs_pos(4) = pos(4) * y_step;
% Create axes
ax = axes('Position', subaxes_abs_pos);
% Remove background
ax.Color = 'none';
end
Sidenote: I found that I didn't need plotboxpos to get the correct positions of the "parent"-axes, using Matlab r2019b on macOS Mojave 10.14.6
Anyway, this is what I end up with:
Using the code:
% Just some random data
mockup_data_ild = [-10 -7 -4 0 4 7 10];
mockup_data_itd_45 = [-40 -20 -10 0 10 20 40];
mockup_data_itd_60 = [-30 -15 -5 0 5 15 30];
% Create figure
figure('Color', 'w')
x_axis_offset = [0 30];
hold on
% Plot 45 dB result
p1 = plot_markers(x_axis_offset(1) + mockup_data_ild, mockup_data_itd_45, ii);
% Plot 60 dB results
p2 = plot_markers(x_axis_offset(2) + mockup_data_ild, mockup_data_itd_60, ii);
p2.Color = p1.Color;
p2.HandleVisibility = 'off';
hold off
% Set axes properties
ax = gca;
ax.XAxis.TickValues = [x_axis_offset(1) x_axis_offset(2)];
ax.XAxis.TickLabels = {'45 dB' '60 dB'};
ax.XAxis.Limits = [x_axis_offset(1)-15 x_axis_offset(2)+15];
ax.XAxisLocation = 'top';
ax.YAxis.Limits = [-80 100];
ax.YAxis.Label.String = 'Interaural Time Difference, \Deltat, in samples';
ax.YGrid = 'on';
% Create 45 dB axis
ax2 = create_DeltaI_axis(ax, x_axis_offset(1));
% Create 60 dB axis
ax3 = create_DeltaI_axis(ax, x_axis_offset(2));
% Create legend
leg = legend(ax, {'P1'});
leg.Location = 'northwest';
%% Helpers
function ax = create_DeltaI_axis(hAx, x_pos)
y_pos = -70;
y_height = 170;
range = 20;
ax = create_value_axes(hAx, [x_pos-range/2 y_pos range y_height]);
ax.XAxis.TickValues = [0 .25 .5 .75 1];
ax.XAxis.TickLabels = {'-10'
'-5'
'0'
'5'
'10'};
ax.XAxis.Label.String = '\DeltaI';
ax.XGrid = 'on';
ax.XMinorGrid = 'on';
ax.YAxis.Visible = 'off';
end
function p = plot_markers(x, y, ii)
markers = {'square','^', 'v', 'o', 'd'};
p = plot(x, y);
p.LineWidth = 1.5;
p.LineStyle = 'none';
p.Marker = markers{ii};
end

Matlab: Orbits of Planetary Bodies

The below code is something that I am cooking up. I am plotting the orbits of the Sun, Mercury, Earth and the Moon. I have gotten this far into the project but the orbit of Mercury is terrifyingly wrong. This is seen by typing "SunEarthMoon(2,50)" at the command prompt and viewing the bottom left plot. The logic behind the project is utilizing Newton's Second Law toggled with the command "ode45" to find the positions of the bodies during a given time interval. I've been staring at this for far too long. Can anyone help to fix the orbit of Mercury?
function [] = SunEarthMoon(years,framerate)
%% Clean Up
close all
clc
%% Initializaion
x_earth = 147300000000; % [m]
x_mercury = 57.91e9; % [m]
v_earth = 30257; % [m/s]
v_mercury = 47362; % [m/s]
r_sat = 384748000; % earth surface [m]
r_earth = 6367000; % earth radius [m]
v_sat = 1023; % relative velocity from earth [m/s]
a = 5.145; % Angle to vertical (y) axis
b = 90; % Angle to horizontal (x) axis in xz plane
x_earth_o = [x_earth; 0; 0];
x_sun_o = [0; 0; 0];
x_mercury_o = [x_mercury; 0; 0];
x_sat_o = [x_earth+r_sat+r_earth; 0; 0];
v_earth_o = [0; v_earth; 0];
v_sun_o = [0; 0; 0];
v_mercury_o = [0; v_mercury; 0];
v_sat_o = v_sat*[cos(pi/180*b)*sin(pi/180*a); cos(pi/180*a); sin(pi/180*b)*sin(pi/180*a)] + v_earth_o;
interval = years*[0 31536000];
%% Error Control
h = [0.01 36000];
tol = 100000;
Options.AbsTol = tol;
Options.MaxStep = h(2);
Options.InitialStep = h(1);
%% Analysis
ao = [x_earth_o; v_earth_o; x_sun_o; v_sun_o; x_sat_o; v_sat_o; x_mercury_o; v_mercury_o];
[t, x] = ode45(#earthfinal,interval,ao,Options);
for i = 1:length(t)
R1(i) = (x(i,13)-x(i,1));
R2(i) = (x(i,14)-x(i,2));
R3(i) = (x(i,15)-x(i,3));
R(i) = sqrt(R1(i)^2+R2(i)^2+R3(i)^2);
end
T_index_earth = find([1; x(:,4)].*[x(:,4);1]<=0);
T_index_moon = find([1; R2(:)].*[R2(:); 1]<=0);
for i = 4:length(T_index_earth)
T_earth_semi(i-3) = (t(T_index_earth(i)-1)-t(T_index_earth(i-2)-1))/24/60/60;
end
T_earth = mean(T_earth_semi);
for i = 4:length(T_index_moon)
T_moon_semi(i-3) = (t(T_index_moon(i)-1)-t(T_index_moon(i-2)-1))/24/60/60;
end
T_moon = mean(T_moon_semi);
D_earth = 0;
for i = 2:(T_index_earth(4)-1)
D_earth = D_earth + sqrt((x(i,1)-x(i-1,1))^2+(x(i,2)-x(i-1,2))^2+(x(i,3)-x(i-1,3))^2);
end
D_moon = 0;
for i = 2:(T_index_moon(4)-1)
D_moon = D_moon + sqrt((R1(i)-R1(i-1))^2+(R2(i)-R2(i-1))^2+(R3(i)-R3(i-1))^2);
end
%% Plots
q = framerate;
scrsz = get(0,'ScreenSize');
figure('position', [0.05*scrsz(3) 0.05*scrsz(4) 0.75*scrsz(3) 0.85*scrsz(4)])
set(gcf,'name','Sun, Earth, and Moon Orbits')
for i = 1:length(t)/q
subplot(2,2,1)
plot3(x(1:i*q,1),x(1:i*q,2),x(1:i*q,3),'g',x(1:i*q,7),x(1:i*q,8),x(1:i*q,9),'r',x(1:i*q,13),x(1:i*q,14),x(1:i*q,15),'b',x(1:i*q,19),x(1:i*q,20),x(1:i*q,21),'black')
axis(1.1*[min(x(:,1)) max(x(:,1)) min(x(:,2)) max(x(:,2)) 2*min(x(:,15)) 2*max(x(:,15))])
xlabel('Universal X Coordinate (m)')
ylabel('Universal Y Coordinate (m)')
zlabel('Universal Z Coordinate (m)')
title('Relative Orbits')
legend('Earth','Sun','Moon')
hold on
plot3(x(i*q,1),x(i*q,2),x(i*q,3),'g-o',x(i*q,7),x(i*q,8),x(i*q,9),'r-o',x(i*q,13),x(i*q,14),x(i*q,15),'b-o',x(i*q,19),x(i*q,20),x(i*q,21),'black-o')
hold off
subplot(2,2,2)
plot3(R1(1:i*q),R2(1:i*q),R3(1:i*q),'b',zeros(1,i*q),zeros(1,i*q),zeros(1,i*q),'g')
axis(1.5*[min(R1) max(R1) min(R2) max(R2) min(R3) max(R3)])
xlabel('Universal X Coordinate (m)')
ylabel('Universal Y Coordinate (m)')
zlabel('Universal Z Coordinate (m)')
title('Relative Moon Orbit About Earth')
hold on
plot3(R1(i*q),R2(i*q),R3(i*q),'b-o',0,0,0,'g-o')
text(0,1.45*max(R2),1.40*max(R3),sprintf('Orbital Period, T = %3.5g days',T_moon))
text(0,1.45*max(R2),1.15*max(R3),sprintf('Orbital Circumference, D = %3.5g gigameters',D_moon*1e-9))
hold off
subplot(2,2,3)
plot(x(1:i*q,1),x(1:i*q,2),'g',x(1:i*q,7),x(1:i*q,8),'r', x(1:i*q,19),x(1:i*q,20),'black')
axis(1.5*[min(x(:,1)) max(x(:,1)) min(x(:,2)) max(x(:,2))])
xlabel('Universal X Coordinate (m)')
ylabel('Universal Y Coordinate (m)')
title('Relative Earth Orbit About Sun')
hold on
plot(x(i*q,1),x(i*q,2),'g-o',x(i*q,7),x(i*q,8),'r-o',x(i*q,19),x(i*q,20),'black-o')
text(1.45*min(x(:,1)),1.40*max(x(:,2)),sprintf('Orbital Period, T = %3.5g days',T_earth))
text(1.45*min(x(:,1)),1.25*max(x(:,2)),sprintf('Orbital Circumference, D = %3.5g gigameters',D_earth*1e-9))
text(1.45*min(x(:,1)),1.40*min(x(:,2)),sprintf('Time, t = %3.3g days',round(t(q*i)/24/60/60)))
hold off
subplot(2,2,4)
plot(t(1:i*q)/(60*60*24),R(1:i*q)/1000,'b')
axis([t(1)/24/60/60 t(end)/24/60/60 0.999*min(R)/1000 1.001*max(R)/1000])
xlabel('Time,t (days)')
ylabel('Orbit Radius, R (km)')
title('Moon-Earth Distance')
hold on
plot(t(i*q)/(60*60*24),R(i*q)/1000,'b-o')
hold off
drawnow
end
end
%% Differential Equation Function
function [udot]= earthfinal(t,u)
m_earth = 5.9742e24; % [kg]
m_mercury = 3.285e23; % [kg]
m_sun = 1.98892e30; % [kg]
m_sat = 11110; % [kg]
G = 6.67300e-11; %[(m)^3(kg)^-1(s)^-2];
d_earth_sun = sqrt((u( 7,1)-u(1,1))^2+(u( 8,1)-u(2,1))^2+(u( 9,1)-u(3,1))^2);
d_earth_sat = sqrt((u(13,1)-u(1,1))^2+(u(14,1)-u(2,1))^2+(u(15,1)-u(3,1))^2);
d_sun_sat = sqrt((u(13,1)-u(7,1))^2+(u(14,1)-u(8,1))^2+(u(15,1)-u(9,1))^2);
d_mercury_sun = sqrt((u(7,1) -u(19,1))^2 + (u(8,1) - u(20,1))^2 + (u(9,1)-u(21,1))^2);
d_mercury_earth = sqrt((u(1,1) -u(19,1))^2 + (u(2,1) - u(20,1))^2 + (u(3,1)-u(21,1))^2);
d_mercury_sat = sqrt((u(13,1) -u(19,1))^2 + (u(14,1) - u(20,1))^2 + (u(15,1)-u(21,1))^2);
% Earth motion
udot( 1,1) = u(4,1);
udot( 2,1) = u(5,1);
udot( 3,1) = u(6,1);
udot( 4,1) = m_sun*G*(u(7,1)-u(1,1))/d_earth_sun^3 + m_sat*G*(u(13,1)-u(1,1))/d_earth_sat^3 + m_mercury*G*(u(19,1)-u(1,1))/d_mercury_earth^3;
udot( 5,1) = m_sun*G*(u(8,1)-u(2,1))/d_earth_sun^3 + m_sat*G*(u(14,1)-u(2,1))/d_earth_sat^3 + m_mercury*G*(u(20,1)-u(2,1))/d_mercury_earth^3;
udot( 6,1) = m_sun*G*(u(9,1)-u(3,1))/d_earth_sun^3 + m_sat*G*(u(15,1)-u(3,1))/d_earth_sat^3 + m_mercury*G*(u(21,1)-u(3,1))/d_mercury_earth^3;
% Sun Motion
udot( 7,1) = u(10,1);
udot( 8,1) = u(11,1);
udot( 9,1) = u(12,1);
udot(10,1) = m_earth*G*(u(1,1)-u(7,1))/d_earth_sun^3 + m_sat*G*(u(13,1)-u(7,1))/d_sun_sat^3 + m_mercury*G*(u(19,1)-u(7,1))/d_mercury_sun^3;
udot(11,1) = m_earth*G*(u(2,1)-u(8,1))/d_earth_sun^3 + m_sat*G*(u(14,1)-u(8,1))/d_sun_sat^3 + m_mercury*G*(u(20,1)-u(8,1))/d_mercury_sun^3;
udot(12,1) = m_earth*G*(u(3,1)-u(9,1))/d_earth_sun^3 + m_sat*G*(u(15,1)-u(9,1))/d_sun_sat^3 + m_mercury*G*(u(21,1)-u(9,1))/d_mercury_sun^3;
% Satellite Motion
udot(13,1) = u(16,1);
udot(14,1) = u(17,1);
udot(15,1) = u(18,1);
udot(16,1) = m_earth*G*(u(1,1)-u(13,1))/d_earth_sat^3 + m_sun*G*(u(7,1)-u(13,1))/d_sun_sat^3 + m_mercury*G*(u(19,1)-u(13,1))/d_mercury_sat^3;
udot(17,1) = m_earth*G*(u(2,1)-u(14,1))/d_earth_sat^3 + m_sun*G*(u(8,1)-u(14,1))/d_sun_sat^3 + m_mercury*G*(u(20,1)-u(14,1))/d_mercury_sat^3;
udot(18,1) = m_earth*G*(u(3,1)-u(15,1))/d_earth_sat^3 + m_sun*G*(u(9,1)-u(15,1))/d_sun_sat^3 + m_mercury*G*(u(21,1)-u(15,1))/d_mercury_sat^3;
% Mercury Motion
udot(19,1) = u(22,1);
udot(20,1) = u(23,1);
udot(21,1) = u(24,1);
udot(22,1) = m_sun*G*(u(7,1)-u(19,1))/d_mercury_sun^3 + m_earth*G*(u(1,1)-u(19,1))/d_mercury_earth^3 + m_sat*G*(u(13,1)-u(19,1))/d_mercury_sat^3;
udot(23,1) = m_sun*G*(u(8,1)-u(20,1))/d_mercury_sun^3 + m_earth*G*(u(2,1)-u(20,1))/d_mercury_earth^3 + m_sat*G*(u(14,1)-u(20,1))/d_mercury_sat^3;
udot(24,1) = m_sun*G*(u(9,1)-u(21,1))/d_mercury_sun^3 + m_earth*G*(u(3,1)-u(21,1))/d_mercury_earth^3 + m_sat*G*(u(15,1)-u(21,1))/d_mercury_sat^3;
end

How to find Orientation of axis of contour in matlab?

I want to find Orientation, MajorAxisLengthand MinorAxisLength of contour which is plotted with below code.
clear
[x1 , x2] = meshgrid(linspace(-10,10,100),linspace(-10,10,100));
mu = [1,3];
sigm = [2,0;0,2];
xx_size = length(mu);
tem_matrix = ones(size(x1));
x_mesh= cell(1,xx_size);
for i = 1 : xx_size
x_mesh{i} = tem_matrix * mu(i);
end
x_mesh= {x1,x2};
temp_mesh = [];
for i = 1 : xx_size
temp_mesh = [temp_mesh x_mesh{i}(:)];
end
Z = mvnpdf(temp_mesh,mu,sigm);
z_plat = reshape(Z,size(x1));
figure;contour(x1, x2, z_plat,3, 'LineWidth', 2,'color','m');
% regionprops(z_plat,'Centroid','Orientation','MajorAxisLength','MinorAxisLength');
In my opinion, I may have to use regionprops command but I don't know how to do this. I want to find direction of axis of contour and plot something like this
How can I do this task? Thanks very much for your help
Rather than trying to process the graphical output of contour, I would instead recommend using contourc to compute the ContourMatrix and then use the x/y points to estimate the major and minor axes lengths as well as the orientation (for this I used this file exchange submission)
That would look something like the following. Note that I have modified the inputs to contourc as the first two inputs should be the vector form and not the output of meshgrid.
% Compute the three contours for your data
contourmatrix = contourc(linspace(-10,10,100), linspace(-10,10,100), z_plat, 3);
% Create a "pointer" to keep track of where we are in the output
start = 1;
count = 1;
% Now loop through each contour
while start < size(contourmatrix, 2)
value = contourmatrix(1, start);
nPoints = contourmatrix(2, start);
contour_points = contourmatrix(:, start + (1:nPoints));
% Now fit an ellipse using the file exchange
ellipsedata(count) = fit_ellipse(contour_points(1,:), contour_points(2,:));
% Increment the start pointer
start = start + nPoints + 1;
count = count + 1;
end
orientations = [ellipsedata.phi];
% 0 0 0
major_length = [ellipsedata.long_axis];
% 4.7175 3.3380 2.1539
minor_length = [ellipsedata.short_axis];
% 4.7172 3.3378 2.1532
As you can see, the contours are actually basically circles and therefore the orientation is zero and the major and minor axis lengths are almost equal. The reason that they look like ellipses in your post is because your x and y axes are scaled differently. To fix this, you can call axis equal
figure;contour(x1, x2, z_plat,3, 'LineWidth', 2,'color','m');
axis equal
Thank you #Suever. It help me to do my idea.
I add some line to code:
clear
[X1 , X2] = meshgrid(linspace(-10,10,100),linspace(-10,10,100));
mu = [-1,0];
a = [3,2;1,4];
a = a * a';
sigm = a;
xx_size = length(mu);
tem_matrix = ones(size(X1));
x_mesh= cell(1,xx_size);
for i = 1 : xx_size
x_mesh{i} = tem_matrix * mu(i);
end
x_mesh= {X1,X2};
temp_mesh = [];
for i = 1 : xx_size
temp_mesh = [temp_mesh x_mesh{i}(:)];
end
Z = mvnpdf(temp_mesh,mu,sigm);
z_plat = reshape(Z,size(X1));
figure;contour(X1, X2, z_plat,3, 'LineWidth', 2,'color','m');
hold on;
% Compute the three contours for your data
contourmatrix = contourc(linspace(-10,10,100), linspace(-10,10,100), z_plat, 3);
% Create a "pointer" to keep track of where we are in the output
start = 1;
count = 1;
% Now loop through each contour
while start < size(contourmatrix, 2)
value = contourmatrix(1, start);
nPoints = contourmatrix(2, start);
contour_points = contourmatrix(:, start + (1:nPoints));
% Now fit an ellipse using the file exchange
ellipsedata(count) = fit_ellipse(contour_points(1,:), contour_points(2,:));
% Increment the start pointer
start = start + nPoints + 1;
count = count + 1;
end
orientations = [ellipsedata.phi];
major_length = [ellipsedata.long_axis];
minor_length = [ellipsedata.short_axis];
tet = orientations(1);
x1 = mu(1);
y1 = mu(2);
a = sin(tet) * sqrt(major_length(1));
b = cos(tet) * sqrt(major_length(1));
x2 = x1 + a;
y2 = y1 + b;
line([x1, x2], [y1, y2],'linewidth',2);
tet = ( pi/2 + orientations(1) );
a = sin(tet) * sqrt(minor_length(1));
b = cos(tet) * sqrt(minor_length(1));
x2 = x1 + a;
y2 = y1 + b;
line([x1, x2], [y1, y2],'linewidth',2);

Color-pass filter by Hue

Why doesn't color filter below find green peppers?
The code:
function [ outhsv ] = ColorFilter( hsv, h, s )
%COLORFILTER Summary of this function goes here
% Detailed explanation goes here
if nargin < 2
h = [];
end
if nargin < 3
s = [];
end
if size(h,2)==1
h = padarray(h, [0 1], 1/100, 'post');
end
if size(s,2)==1
s = padarray(s, [0 1], 1/100, 'post');
end
if isempty(h)
v_of_h = ones(size(hsv,1), size(hsv,2));
else
v_of_h = WeightFunction( hsv(:,:,1), h(:,1), h(:,2));
end
if isempty(s)
v_of_s = ones(size(hsv,1), size(hsv,2));
else
v_of_s = WeightFunctionOnce( hsv(:,:,2), s(:,1), s(:,2));
end
outhsv = hsv;
outhsv(:,:,3) = hsv(:,:,3) .* v_of_h .* v_of_s;
function y = WeightFunction( x, mu, sigma )
%y = WeightFunctionOnce(x,mu,sigma) + WeightFunctionOnce(x-1,mu,sigma);
y = 1 - (1-WeightFunctionOnce(x,mu,sigma)) .* (1-WeightFunctionOnce(x-1,mu,sigma));
function y = WeightFunctionOnce( x, mu, sigma )
if nargin<2
mu=0;
elseif nargin<3
sigma=1./100.;
end
if any(size(mu) ~= size(sigma))
error('mu and sigma should be of the same size');
end
y = zeros([size(x) numel(mu)]);
for i=1:numel(mu)
y(:,:,i) = exp(-((x - mu(i)) .^ 2 ./ (2 .* sigma(i) .^ 2)));
end
%y = sum(y,3)/size(y,3);
y = 1-prod(1-y,3);
Display code:
hue = 120;
h = [hue/360 0.05];
s = [];
rgb1 = imread('huescale.png');
%rgb1 = imread('peppers.png');
hsv1 = rgb2hsv(rgb1);
hsv2 = ColorFilter(hsv1, h, s);
rgb2 = hsv2rgb(hsv2);
bitmask = hsv1(:,:,1)>(h(1)-h(2)) & hsv1(:,:,1)<(h(1)+h(2));
figure;
subplot(3,1,1); imshow(rgb1);
subplot(3,1,2); imshow(rgb2);
subplot(3,1,3); imshow(bitmask);
result on scale
(works)
result on peppers:
(does not)
Why?
If you looked closer at the H values, those green peppers are kind of yellowish, so you might want to widen the rule a bit.
I would suggest something in between 0.15 and 0.5. You can also combine with saturation channel, say only consider portions of images that are vibrant, i.e., we want to get rid of the onions. Try the following codes to get a preview.
hsv_dat = rgb2hsv(imread('peppers.png'));
imagesc(hsv_dat(:,:,1) > 0.15 & hsv_dat(:,:,1) < 0.5 & hsv_dat(:,:,2) > 0.3)
colormap(gray)
You should get