Olympic Rings7

Posted by Loren Shure,

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.

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));
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

Mike replied on : 1 of 7

That’s great. I’m so used to thinking in 2-dimensions with my plots.

mark replied on : 2 of 7

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

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);

Loren replied on : 3 of 7

Mark-

Thanks so much for sharing an entirely different approach!

–Loren

Tom Elmer replied on : 4 of 7

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

Loren replied on : 5 of 7

Tom-

Thanks for an interesting and elegant solution!

–Loren

Hung Dang replied on : 6 of 7

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]);

Tom Elmer replied on : 7 of 7

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

These postings are the author's and don't necessarily represent the opinions of MathWorks.