Well, I am very late on this challenge. In August, Mike posted some code to reproduce the Olympic rings and mentioned that I might have a more clever way to create the same plot. Here's my attempt.
Contents
Create X and Y Values for the 5 Rings
First, I'll follow Mike's parameters and code to create the initial five rings.
N = 1000; angle = linspace(pi/4,9*pi/4,N); xb = cos(angle) * 0.9; yb = sin(angle) * 0.9; xy = cos(angle) * 0.9 + 1; yy = sin(angle) * 0.9 - 1; xk = cos(angle) * 0.9 + 2; yk = sin(angle) * 0.9; xg = cos(angle) * 0.9 + 3; yg = sin(angle) * 0.9 - 1; xr = cos(angle) * 0.9 + 4; yr = sin(angle) * 0.9;
Mike's Rings
What Mike does next is to break rings into segments for plotting so the last ring plotted in any given location is the color that should be on top.
h1 = figure; hold on plot(xb(1:3*N/4),yb(1:3*N/4),'b','linewidth',5); plot(xy(N/4:N),yy(N/4:N),'y','linewidth',5) plot(xk(1:3*N/4),yk(1:3*N/4),'k','linewidth',5); plot(xy(1:N/4),yy(1:N/4),'y','linewidth',5); plot(xb(3*N/4:end),yb(3*N/4:end),'b','linewidth',5); plot(xr(1:N/2),yr(1:N/2),'r','linewidth',5); plot(xg(1:N),yg(1:N),'g','linewidth',5); plot(xk(3*N/4:N),yk(3*N/4:N),'k','linewidth',5); plot(xr(N/2:N),yr(N/2:N),'r','linewidth',5); % make the axis pretty axis equal axis off xlim([-1.2 5.2]) set(h1,'Color',[1 1 1]) hold off
My Solution
My "cleverness" is to offset the rings in the Z-plane.
First I noticed that all the top rings have an axis about which I can "tilt" them ever so slightly to get the most of the over/under behavior for the rings. Add small Z values to each ring.
thetab = -pi/4; thetak = -pi/4; thetar = -pi/4;
Now I create Z values for the rings in the upper rows by tilting them about the axes defined by the angles above (which happen to be identical).
zb = cos(angle + thetab) * 0.1; zk = cos(angle + thetak) * 0.1; zr = cos(angle + thetar) * 0.1;
Next I deal with the lower rings in a lazy way, introducing a discontinuity in Z. If I had more patience today, I could have come up with an undulation in Z that was more than a tilted plane or a step.
I find the angles where I need to depress the bottom rings relative to the top and set appropriate Z values for these to be less than 0.
mask = angle >= 2*pi; zg = zeros(size(xb)); zy = zeros(size(xb)); zg(mask) = -0.1; zy(mask) = -0.1;
Loren's Rings
Here's my rendition of the rings. My plot commands are a bit less complicated than Mike's. I do the work earlier by setting Z values. Also, because of my laziness, if you were to rotate my version of rings in 3-D, you'd see the bottom two aren't really rings, but have discontinuities.
h2 = figure; hold on plot3(xb,yb,zb,'b.','markersize',10); plot3(xy,yy,zy,'y.','markersize',10); plot3(xk,yk,zk,'k.','markersize',10); plot3(xg,yg,zg,'g.','markersize',10); plot3(xr,yr,zr,'r.','markersize',10); % make the axis pretty axis equal axis off xlim([-1.2 5.2]) set(h2,'Color',[1 1 1]) hold off
Any Other Methods?
Mike and I show 2 methods to generate interlocking rings. Do you have any other ideas for doing this? Let me know here.
Get
the MATLAB code
Published with MATLAB® 7.7



That’s great. I’m so used to thinking in 2-dimensions with my plots.
If you want to do it as an image versus a plot then you can utilize convolution since the rings are identical. Admittedly the output doesn’t look as nice as above but I think it is a nice demonstration of the conv2 function…maybe.
% first create a ‘ring’
x=sin(2*pi*(1/100)*(0:99));
y=cos(2*pi*(1/100)*(0:99));
c=zeros(32,32);
for i=1:100
c(ceil(15*x(i))+16,ceil(15*y(i))+16)=1;
end
% then create your canvas
A=zeros(128,128);
% set ring spacing
n=36;
% convolving this set of impulses with
% the ring will make the final output array
% the different values will change the colors
A(64,((0:2)*n)+20)=[1 3 5];
A(64+15,([1/2 3/2]*n)+20)=[2 4];
% use this to test the overlaps
D(64,((0:2)*n)+20)=[1 1 1];
D(64+15,([1/2 3/2]*n)+20)=[1 1];
w=conv2(D,c,’same’);
% find where the rings overlap
[s,t]=find(w==2);
f=[2 2 1 2 3 4 4 3 4 5];
% create the final output array
r=conv2(A,c,’same’);
% replace with the ‘right values from left to right
for ii=1:10
r(s(ii),t(ii))=f(ii);
end
% set the color map to a white background
% and five colors
map=[1 1 1 ; 0 0 1 ; 1 1 0 ; 0 0 0 ; 0 1 0 ; 1 0 0]
% display
imagesc(r)
colormap(map);
Mark-
Thanks so much for sharing an entirely different approach!
–Loren
Next I deal with the lower rings in a lazy way, introducing a discontinuity in Z. If I had more patience today, I could have come up with an undulation in Z that was more than a tilted plane or a step.
No need to add undulations, just alternate your axis (and I added an alternating offset) then increment the angles/offsets on each ring. (Of course they’re really ellipses in 3D but the 2D projection is circular. Actually, it looks kinda neat on Y-Z view.) (I wasn’t mathematically rigorous on what the coefficients should be for N rings, but I did try it out to 28 rings.)
N = 1000;
angle = linspace(pi/4,9*pi/4,N);
c=’bykgr’;
%c=’bykgrmcbykgrmcbykgrmcbykgrmc’;
index = 1:length(c);
UL=( ~mod(index,2) - mod(index,2) ); %negative if Upper ring, positive if Lower ring
h2 = figure(’color’,[1 1 1]);
hold on
for loop=1:length(c)
z = cos(angle + UL(loop)*pi/4) * … %alternating axes
(length(c)-loop)*0.1*-UL(loop) + … %alternating angles
.05*(length(c)-loop)*-UL(loop); %alternating depth offsets
x = cos(angle) * 0.9 + (loop-1);
y = sin(angle) * 0.9 - ~mod(loop,2);
plot3(x,y,z,[c(loop) ‘.’],’markersize’,10);
end
axis equal off
hold off
Tom-
Thanks for an interesting and elegant solution!
–Loren
I fix Loren’s code a little bit to be able to reuse x and y and with a shorter plot command ;)
%% Init parameters
R = 0.9;
scale = 1.1;
N = 100;
thickness = 10;
angle = linspace(0,2*pi,N);
%% Plot the rings
y = R * sin(angle);
x = R * cos(angle);
plot(x,y,’b',x + scale * R,y - scale * R,’k',x + 2 * scale * R,y,’r',…
x + 3 * scale * R, y - scale * R,’g',x + 4 * scale * R,y,’k',…
‘LineWidth’,thickness);
%% Make axis look better
axis off;
set(gca,’XLim’,[-1.2 5.2]);
set(gcf,’Color’,[1 1 1]);
I fix Loren’s code a little bit to be able to reuse x and y and with a shorter plot command ;)
You missed the important part of the exercise in that the rings have to be interlocking :D