47
$\begingroup$

How can I draw the 5 interlocking Olympic rings with Mathematica?

Olympic rings

(SVG version)


Edit

Hard choice, but some pretty cool answers here. I didn't have 3D answers in mind when I posted the question, but without a doubt, they look much better than the 2D. Very subjective choice for the selected answer, but I do like @cormullion's answer.

$\endgroup$
9
  • 1
    $\begingroup$ FWIW... my prof's back on Wednesday - I'll ask him if we can include calculations on Olympicene in my project :) But on the question, mind giving a try yourself? Make sure you get the colors right ;) $\endgroup$
    – CHM
    Commented Jul 30, 2012 at 23:29
  • 2
    $\begingroup$ Sorry, too easy ... Import["https://i.sstatic.net/fJthQ.png"] $\endgroup$ Commented Jul 31, 2012 at 0:20
  • $\begingroup$ @belisarius now vectorize it :) $\endgroup$
    – rm -rf
    Commented Jul 31, 2012 at 0:22
  • 3
    $\begingroup$ That's not vector graphics $\endgroup$
    – rm -rf
    Commented Jul 31, 2012 at 1:17
  • 4
    $\begingroup$ "You are under arrest." — International Olympic Committee $\endgroup$ Commented Jul 31, 2012 at 14:57

7 Answers 7

23
$\begingroup$

I thought I'd better have a go at these 'sports-related celebratory circular hollow loops', despite the risk, but I couldn't get the rings to overlap properly - the brain starts to hurt after a while. Looking for shiny rings, but black doesn't shine very well...

ring = ParametricPlot3D[{Cos[t] (8 + Cos[u]), Sin[t] (8 + Cos[u]), 
     Sin[u]/8}, {t, 0, 2 Pi}, {u, 0, 2 Pi}, Mesh -> None][[1]];
col = {Blue, Yellow, Black, Green, Red};
pts = {{0, 2, 0}, {2, 0, 0}, {4, 2, 0}, {6, 0, 0}, {8, 2, 0}};
rotations = {{.1, 0, 0}, {0, 0.1, 0}, {-0.2, 0.2, 0}, {.1, 0.5, 
    0.5}, {0.1, -0.2, 0}};
Graphics3D[{
  Specularity[White, 30],
  Table[{col[[i]],
    Translate[
     Rotate[
      ring ,
      Pi/16, 
      rotations[[i]]],
      3 pts[[i]]]}, {i, 1, 5}]}, Boxed -> False, Background -> Gray, 
 ViewAngle -> 0.4, ViewPoint -> {0, 0, 3}, 
 ViewVertical -> {0, 1.5, 6}]

olympic rings

Edit: Better do it properly, I suppose:

ring = ParametricPlot3D[{Cos[t] (8 + Cos[u]), Sin[t] (8 + Cos[u]), 
     Sin[u]/8}, {t, 0, 2 Pi}, {u, 0, 2 Pi}, Mesh -> None][[1]];
col = {Blue, Yellow, Black, Darker[Green], Red};
pts = {{0, 1.5, 0}, {2, 0, 0}, {4, 1.5, 0}, {6, 0, 0}, {8, 1.5, 0}};
rotations = {{0, 0, 1}, {-.3, .5, 1}, {-0.1, -3, 1}, {-1, 1, 
    1}, {-1, -4, 1}};
Graphics3D[{
  Specularity[White, 20],
  Table[{col[[i]],
    Translate[
     Rotate[
      ring ,
      0.1, 
      rotations[[i]]],
     5 pts[[i]]]}, {i, 1, 5}]}, Boxed -> False, Background -> Gray, 
 ViewAngle -> 0.5, ViewPoint -> {0, 0, 3}, ViewVertical -> {0, 1, 6}]

rings better linked

$\endgroup$
8
  • $\begingroup$ Aargh - just looked at the others more closely and I seem to have tried too hard to link the rings together... Idiot! $\endgroup$
    – cormullion
    Commented Jul 31, 2012 at 15:24
  • $\begingroup$ You could use Glow[] on your colors, you know... $\endgroup$ Commented Aug 1, 2012 at 3:13
  • $\begingroup$ @J.M. I had a look, but it didn't do what I was expecting, which was like the neon lit effect in Illustrator. $\endgroup$
    – cormullion
    Commented Aug 1, 2012 at 16:30
  • $\begingroup$ Hmm, good point. Glow[] tends to make things look flat, but if you wanted your colors to be a bit more textured, then your route is best. $\endgroup$ Commented Aug 1, 2012 at 17:01
  • $\begingroup$ Is there a syntax error in your second version with the less-blended colors? entering exactly is returning something about missing closing brackets, and then it doesn't produce any output. $\endgroup$ Commented Aug 1, 2012 at 17:24
69
$\begingroup$

A rather crude way of accomplishing this is just to draw multiple shapes layered such that the rings interlock.

ringSegment[mid_, deg_, color_] := {
  Thickness[0.05],CapForm["Butt"], White, Circle[mid, 1, deg], Thickness[0.03],
  RGBColor @@ (color/255), Circle[mid, 1, deg + {-0.1, 0.1}]}

olblue   = {0, 129, 188};
olyellow = {255, 177, 49};
olBlack  = {35, 34, 35};
olGreen  = {0, 157, 87};
olRed    = {238, 50, 78};

Graphics @ GraphicsComplex[
  {{2.5, 0}, {1.3, -1}, {0, 0}, {5, 0}, {3.8, -1}},
  ringSegment @@@
   {{1, {0, 5/4 π}, olBlack},
    {2, {0, π}, olyellow},
    {3, {0, 2 π}, olblue},
    {2, {-π 9/8, 1/4 π}, olyellow},
    {4, {0, 5/4 π}, olRed},
    {5, {0, 7/8 π}, olGreen},
    {1, {5/4 π, 5/2 π}, olBlack},
    {5, {7/8 π, 2 π}, olGreen},
    {4, {-3/4 π, 1/4 π}, olRed}}
 ]

OL ring computed using the given code

$\endgroup$
8
  • 1
    $\begingroup$ This is much better than my attempt. I forgot about the third argument to Circle. $\endgroup$
    – Verbeia
    Commented Jul 31, 2012 at 0:14
  • $\begingroup$ this works fine on my computer. Perhaps a version 7 issue?? $\endgroup$ Commented Jul 31, 2012 at 0:21
  • $\begingroup$ jVincent I edited your answer with a rewrite using GraphicsComplex. If you don't care for it I'll post it as a separate answer. $\endgroup$
    – Mr.Wizard
    Commented Jul 31, 2012 at 0:41
  • $\begingroup$ @Mike yes, but I edited the answer to make it compatible. $\endgroup$
    – Mr.Wizard
    Commented Jul 31, 2012 at 0:42
  • 1
    $\begingroup$ No, \[Pi] is just fine, I simply prefer the readability of π. The problem for v7 was having {7/8 π, 0} instead of {0, 7/8 π}; it wants them ordered. $\endgroup$
    – Mr.Wizard
    Commented Jul 31, 2012 at 11:33
34
$\begingroup$

Why not create the 3D model of which this is a stylized representation?

To do so, we need to construct a 3D ring. Let's thicken a polygonal approximation to a circle:

ring[center_, normal_] := 
  With[{a = axes[normal], radius = 1, thickness = 0.25}, 
   Tube[center + radius {Cos[#], Sin[#]}.a & /@ Range[0, 2 Pi, 2 Pi / 72], thickness/2]];

The auxiliary function axes is a quick-and-dirty way to obtain two orthonormal axes perpendicular to a particular direction. (It will not work in directions parallel to the y axis.) This makes it simpler and more natural to describe a 3D circle in terms of its center and a vector perpendicular to its plane:

axes[normal_] := 
  Module[{x = {-normal[[3]], 0, normal[[1]]}, y},
   y =  Cross[normal, x]; {x / Norm[x], y / Norm[y]}];

Specify the positions of the centers and tilt the top row one way, the bottom row another:

dy = 2.4; offset = 0.25;
rings = Join[
   ring[#, {0, -offset, 1}] & /@ {{0, 0, 0}, {0, dy, 0}, {0, 2 dy, 0}},
   ring[#, {0, offset, 1}] & /@ {{Sqrt[3]/2, dy/2, 0}, {Sqrt[3]/2, 3 dy/2, 0}}];

Oh yes, the colors:

colors = {Cyan, Black, Red, Yellow, Green};

Render the rings:

Graphics3D[Riffle[colors, rings], Boxed -> False, 
 PlotRange -> {{-2, 4}, {-2, 3 dy}, {-2 offset, 2 offset}}]

Olympic rings

Now you can play with them in three dimensions!

Olympic rings 2

$\endgroup$
6
  • $\begingroup$ If desired, one could do Riffle[Glow /@ colors, rings]. $\endgroup$ Commented Jul 31, 2012 at 10:44
  • $\begingroup$ @J.M. That's a cool effect: to make it look right, you have to (1) use the correct colors (as in jVincent's reply) and (2) turn the lighting off (Lighting->None in Graphics3D). $\endgroup$
    – whuber
    Commented Jul 31, 2012 at 12:43
  • $\begingroup$ Oh, right. I use Lighting -> "Neutral" myself when using Glow[], but that works, too. $\endgroup$ Commented Jul 31, 2012 at 12:44
  • $\begingroup$ that 3d model needs some anti-aliasing... badly. $\endgroup$ Commented Jul 31, 2012 at 16:37
  • 1
    $\begingroup$ @Trevor The model needs no anti-aliasing; in fact, the concept doesn't even apply. But for sure the rendering used could use some anti-aliasing. Some good solutions have been posted at mathematica.stackexchange.com/questions/198/antialiasing-in-3d. $\endgroup$
    – whuber
    Commented Jul 31, 2012 at 16:41
31
$\begingroup$

3 D approach

It would be possible to do this using ParametricPlot3D, very slight variation in the $z$-direction, and a suitable ViewPoint:

Stealing jVincent's colors:

olblue = RGBColor[{0, 129, 188}/255.];
olyellow = RGBColor[{255, 177, 49}/255.];
olBlack = RGBColor[{35, 34, 35}/255.];
olGreen = RGBColor[{0, 157, 87}/255.];
olRed = RGBColor[{238, 50, 78}/255.];

olyrings = 
 ParametricPlot3D[{{Cos[t], Sin[t], 0.325 Sin[t + Pi/4] - 0.035},
 (* blue *){Cos[t], Sin[t], 0.325 Sin[t + Pi/4]},
   {3/4 Pi + Cos[t], Sin[t], 0.04 Sin[t + Pi/4] - 0.005},
 (*  black *){3/4 Pi + Cos[t], Sin[t], 
    0.04 Sin[t + Pi/4]}, {3/8 Pi + Cos[t], 
    Sin[t] - 9/8, -0.12 Sin[Pi/4 - t] - 0.05},
 (* yellow *){3/8 Pi + Cos[t], 
    Sin[t] - 9/8, -0.12 Sin[Pi/4 - t]}, {3/2 Pi + Cos[t], Sin[t], 
    0.005 Sin[t - Pi/4] - 0.001},
 (* red *){3/2 Pi + Cos[t], Sin[t], 
    0.005 Sin[t - Pi/4]}, {9/8 Pi + Cos[t], Sin[t] - 9/8, 
    0.01 Sin[t - Pi/4] - 0.001},
 (* green *){9/8 Pi + Cos[t], Sin[t] - 9/8, 0.01 Sin[t - Pi/4]}}, 
 {t, 0, 2 Pi}, Axes -> False, BaseStyle -> AbsoluteThickness[10], 
  PlotStyle -> {Directive[AbsoluteThickness[14], White], olblue, 
    Directive[AbsoluteThickness[14], White], olBlack, 
    Directive[AbsoluteThickness[14], White], olyellow, 
    Directive[AbsoluteThickness[14], White], olRed, 
    Directive[AbsoluteThickness[14], White], olGreen}, 
  ViewPoint -> Top, ImageSize -> 350, Boxed -> False, 
  PlotRangePadding -> 0.15]

enter image description here

$\endgroup$
3
  • $\begingroup$ Colors may be off due to Lighting specs. $\endgroup$
    – Yves Klett
    Commented Jul 31, 2012 at 13:31
  • $\begingroup$ Just going through all these answers now. Was there a 3D solution here once? $\endgroup$ Commented Aug 1, 2012 at 3:50
  • 2
    $\begingroup$ This is a 3D solution - it just looks 2D ;-) $\endgroup$
    – Verbeia
    Commented Aug 1, 2012 at 6:13
27
$\begingroup$

I tried to resist answering, but couldn't...

(* perturbed circle *)
circ = Cases[ParametricPlot3D[{Cos[t], Sin[t], Cos[3 t]},
                              {t, 0, 2 Pi}], _Line, Infinity][[1, 1]];

Graphics3D[MapThread[{Directive[Black, Glow[#3]], 
    Tube[Composition[TranslationTransform[#1], RotationTransform[#2, {0, 0, 1}]] /@
         circ, 1/8]} &,
     {PadRight[{{0, 9}, {12, 0}, {24, 9}, {36, 0}, {48, 9}}/10, {5, 3}], (* centers*)
     {0, Pi/3, 0, Pi/3, 0}, (* rotations *)
     RGBColor @@@ ({{0, 129, 188}, {255, 177, 49}, {35, 34, 35},
                    {0, 157, 87}, {238, 50, 78}}/255)}], (* colors *)
     Boxed -> False, Method -> {"TubePoints" -> 30}, ViewPoint -> {0, 0, Infinity}]

Olympic logo

$\endgroup$
0
23
$\begingroup$

I already did a refactor for jVincent's answer, and rather than edit whuber's too I feel like posting something myself; besides my style is controversial. Here is my refactor of his answer in my own style and with my own tweaks.

ring[
  {x_, y_, z_: 0},
  {u_: 0, v_, w_: 1},
  {dy_, offset_, r_}
 ] :=
 With[{ axes = Normalize /@ {#, {u, v offset, w}\[Cross]#} &@{-w, 0, u} },
  Tube[{x, y dy, z} + {Cos@#, Sin@#}.axes & /@ Range[0, 2 Pi, 2 Pi/72], r]
 ]

param = {2.4, 0.25, 0.17};

rings =
  Join[
   ring[{0, #}, {-1}, param] & /@ {0, 1, 2},
   ring[{Sqrt[3]/2, #/2}, {1}, param] & /@ {1, 3}
  ];

colors = {Cyan, Darker@Gray, Red, Yellow, Green};

Graphics3D[
 Riffle[colors, rings],
 Boxed -> False,
 ViewPoint -> {0, 0, ∞},
 ViewVertical -> {-1, 0, 0}
]

Olympic rings

Condensed code for this specific problem. (Less flexible than above; hard coded parameters.)

ring[x_, y_, v_] := 
  Table[
    {1.2 y, -v x, 0} + {Cos@i, Sin@i}.{{0, -1, 0}, {1, 0, 1/4 - v/2}},
    {i, 0, 2 π, π/200}
  ] ~Tube~ 0.17

Graphics3D[
  Riffle[
    {Cyan, Yellow, Darker @ Gray, Green, Red},
    Array[ring[Sqrt@3/2, #, # ~Mod~ 2] &, 5, 0] ],
  Boxed -> False,
  ViewPoint -> {0, 0, ∞}
]
$\endgroup$
7
  • $\begingroup$ (+1) Beautiful. $\endgroup$
    – whuber
    Commented Jul 31, 2012 at 16:44
  • $\begingroup$ @whuber thanks! $\endgroup$
    – Mr.Wizard
    Commented Jul 31, 2012 at 21:25
  • $\begingroup$ decisions, decisions ...I'll make a choice later today but some really great answers to this question. $\endgroup$ Commented Jul 31, 2012 at 23:07
  • $\begingroup$ #/Norm[#] & is in fact the same as Normalize. $\endgroup$ Commented Aug 1, 2012 at 9:30
  • $\begingroup$ @J.M. I forgot that. Thanks. Same number of keystrokes though. :-) $\endgroup$
    – Mr.Wizard
    Commented Aug 1, 2012 at 14:01
7
$\begingroup$
ParametricPlot3D[{
  {4 + (3 + Cos[v]) Sin[u], 4 + (3 + Cos[v]) Cos[u], 
   4 + Sin[v]}, {8 + (3 + Cos[v]) Cos[u], 3 + Sin[v], 
   4 + (3 + Cos[v]) Sin[u]}, {12 + (3 + Cos[v]) Sin[u], 
   4 + (3 + Cos[v]) Cos[u], 4 + Sin[v]}, {16 + (3 + Cos[v]) Cos[u], 
   3 + Sin[v], 4 + (3 + Cos[v]) Sin[u]}, {20 + (3 + Cos[v]) Sin[u], 
   4 + (3 + Cos[v]) Cos[u], 4 + Sin[v]}
  }, {u, 0, 2 Pi}, {v, 0, 2 Pi}, 
 PlotStyle -> {Red, Green, Blue, Yellow, Black}, Mesh -> None, 
 Axes -> None, Boxed -> False]

enter image description here

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.