Recent

Author Topic: Olympic Rings (Interleaved)  (Read 1053 times)

Boleeman

  • Hero Member
  • *****
  • Posts: 1108
Olympic Rings (Interleaved)
« on: January 16, 2026, 10:22:04 am »
Olympic Rings (Interleaved)

Finally found a reliable way to interleave the rings.
Used a different way to here https://forum.lazarus.freepascal.org/index.php/topic,72212.msg565323.html#msg565323 (I converted from csharp last time, but it was unreliable)

Perhaps one might be able to adapt this code for other ring configurations?

Hooray.
« Last Edit: January 17, 2026, 02:17:51 am by Boleeman »

Zvoni

  • Hero Member
  • *****
  • Posts: 3252
Re: Olympic Rings (Interleaved)
« Reply #1 on: January 16, 2026, 10:37:21 am »
I'm in no way a graphics-expert.
Just looked at your code.
In TRingArcs you have a hardcoded Array of TArcSegments, which actually corresponds to the Count-Property.

i see 2 ways (untested):
1) Instead of a Record use Class for TArcSegments. In its Constructor you pass the Count, and SetLength the then dynamic Array for ArcSegments.
But looks overkill, nevermind memory-management (If you Create you have to Free et. al)
2) Advanced Records. Write a Procedure SetCount, in which you pass the Count, and inside you set Count-Property and SetLength the dynamic Array for TArcSegments

That's just on first look
One System to rule them all, One Code to find them,
One IDE to bring them all, and to the Framework bind them,
in the Land of Redmond, where the Windows lie
---------------------------------------------------------------------
Code is like a joke: If you have to explain it, it's bad

speter

  • Sr. Member
  • ****
  • Posts: 487
Re: Olympic Rings (Interleaved)
« Reply #2 on: January 17, 2026, 02:19:26 am »
EDIT: Oops my blue ring is wrong. :) I will fix and repost. :o

Here is a simpler Olympic Rings, the paint proc =
Code: Pascal  [Select][+][-]
  1. procedure TForm1.Panel_drawing_areaPaint(Sender: TObject);
  2. const
  3.   grid : tpoint = (x:6;y:3);
  4.   colours : array of integer = ($c88600, $00c4f4, $000000, $3aa000, $1f00e0);
  5.  
  6.   angle1  = -15*16;  // 15 degrees
  7.   angle2  =  73*16;  // 73 degrees
  8.   arc_len =  20*16;  // 20 degrees, arc "length"
  9. var
  10.   sz , a, x, y, off : integer;
  11.   lt : tpoint;
  12. begin
  13.   with panel_drawing_area do
  14.     begin
  15.       sz := min(width div grid.x, height div grid.y) - 10;
  16.       lt := point((width - sz*grid.x) div 2, (height - sz*grid.y) div 2);
  17.       off := sz div 10;
  18.  
  19.       canvas.pen.width := off *2;
  20.       canvas.brush.style := bsclear;
  21.  
  22.       // draw the rings
  23.       for a := 0 to 4 do
  24.         begin
  25.           x := lt.x + a*sz;
  26.           y := lt.y;
  27.           if odd(a) then
  28.             y += sz;
  29.  
  30.           canvas.pen.color := colours[a];
  31.           canvas.ellipse(x+off, y+off, x+2*sz-off,y+2*sz-off);
  32.         end;
  33.  
  34.       // draw the arcs, to fix overlapping
  35.       canvas.pen.color := colours[1];
  36.       canvas.arc(lt.x + sz*1 + off, lt.y + sz*1 + off,
  37.                  lt.x + sz*3 - off, lt.y + sz*3 - off,  angle2, arc_len);
  38.  
  39.       canvas.pen.color := colours[0];
  40.       canvas.arc(lt.x + sz*0 + off, lt.y + sz*0  + off,
  41.                  lt.x + sz*2 - off, lt.y + sz*2 - off, -angle1, arc_len);
  42.  
  43.       canvas.pen.color := colours[3];
  44.       canvas.arc(lt.x + sz*3 + off, lt.y + sz*1 + off,
  45.                  lt.x + sz*5 - off, lt.y + sz*3 - off,  angle2, arc_len);
  46.  
  47.       canvas.pen.color := colours[2];
  48.       canvas.arc(lt.x + sz*2 + off, lt.y + sz*0 + off,
  49.                  lt.x + sz*4 - off, lt.y + sz*2 - off, -angle1, arc_len);
  50.     end;
  51. end;
« Last Edit: January 17, 2026, 02:21:09 am by speter »
I climbed mighty mountains, and saw that they were actually tiny foothills. :)

speter

  • Sr. Member
  • ****
  • Posts: 487
Re: Olympic Rings (Interleaved)
« Reply #3 on: January 17, 2026, 02:28:37 am »
Here is the corrected project.
Lines #41 and #48 in the above use "-angle1" instead of "angle1". ;)

cheers
S.
I climbed mighty mountains, and saw that they were actually tiny foothills. :)

Boleeman

  • Hero Member
  • *****
  • Posts: 1108
Re: Olympic Rings (Interleaved)
« Reply #4 on: January 17, 2026, 03:13:34 am »
Wow, speter achieved the same result with that smaller amount of code. I'm impressed.

How did you realize to get 15, 73 and 20 degrees and why *16:

  angle1  = -15*16;  // 15 degrees
  angle2  =  73*16;  // 73 degrees
  arc_len =  20*16;  // 20 degrees, arc "length"

Just trying to understand your code.

I can see you are using the TPanel for the resizing and a grid : tpoint = (x:6;y:3) . Nice.


I spent all morning on my own versions trying to save to svg, but without success.

Thanks speter for you brilliant code.


440bx

  • Hero Member
  • *****
  • Posts: 6082
Re: Olympic Rings (Interleaved)
« Reply #5 on: January 17, 2026, 03:32:19 am »
I'll pretend I'm making this comment in the name of accuracy to hide that I'm being picky ;)

From what I"ve seen, the horizontal separation between rings seems to equal the thickness of the ring.  IOW, everyone's rings shown in this thread are too close together. 

Reportedly, in 1986, the IOC completely spec-ed the Olympic Logo including how much space there should be between rings.  I looked for the spec but didn't find it, otherwise I would have contributed it.

FPC v3.2.2 and Lazarus v4.0rc3 on Windows 7 SP1 64bit.

speter

  • Sr. Member
  • ****
  • Posts: 487
Re: Olympic Rings (Interleaved)
« Reply #6 on: January 17, 2026, 03:57:10 am »
How did you realize to get 15, 73 and 20 degrees and why *16:

  angle1  = -15*16;  // 15 degrees
  angle2  =  73*16;  // 73 degrees
  arc_len =  20*16;  // 20 degrees, arc "length"

There are 2 variants of the LCL canvas.arc function. My code uses:
canvas.arc(x1,y1, x2,y2, start, alen);
where
  (x1,y1)-(x2,y2) defines the enclosing rectangle;
  start = angle of the start of the arc, where 0=east and positive=anti-clockwise
             also the value is = degree * 16
  alen = angle of the arc (anti-clockwise), again = degree * 16

So an arc starting at north = 90*16...

As to how I calculated the values: basically by guessing, then refining the numbers, until they looked correct ;) (very low-tech).

From what I"ve seen, the horizontal separation between rings seems to equal the thickness of the ring.  IOW, everyone's rings shown in this thread are too close together.
You are absolutely correct. My aim was simply to reproduce Boleeman's rings, using simpler code.

I would think it would be comparatively easy to change Boleeman's or my code to produce the correct spacing etc. ;)

cheers
S.
I climbed mighty mountains, and saw that they were actually tiny foothills. :)

440bx

  • Hero Member
  • *****
  • Posts: 6082
Re: Olympic Rings (Interleaved)
« Reply #7 on: January 17, 2026, 05:13:22 am »
I would think it would be comparatively easy to change Boleeman's or my code to produce the correct spacing etc. ;)
Yes, it would be.  I thought I'd mention the separation because it is obvious that care went into producing something reasonably accurate therefore accurate spacing would have increased the total accuracy. :)

I looked for the IOC spec but, didn't find it.  As you stated, establishing the correct spacing is easy as long as it is known.

FPC v3.2.2 and Lazarus v4.0rc3 on Windows 7 SP1 64bit.

Boleeman

  • Hero Member
  • *****
  • Posts: 1108
Re: Olympic Rings (Interleaved)
« Reply #8 on: January 17, 2026, 05:16:12 am »
440bx and speter, I was just trying to render the pattern with the correct interleaving (producing something reasonably accurate is good enough for me).

Speter, using your code I was able to successfully save to svg.

Hooray.
« Last Edit: January 17, 2026, 07:31:09 am by Boleeman »

Boleeman

  • Hero Member
  • *****
  • Posts: 1108
Re: Olympic Rings (Interleaved)
« Reply #9 on: January 17, 2026, 07:34:34 am »
Finally sorted out the svg saving.

Enjoy.



Many thanks to speter for your help in rendering the rings in a much simpler way.
Much Appreciated speter.

speter

  • Sr. Member
  • ****
  • Posts: 487
Re: Olympic Rings (Interleaved)
« Reply #10 on: January 17, 2026, 08:16:27 am »
Here is a new version of my code.
Using the correct colours, spacing and padding.

It is also a better implementation because I am using a loop to draw the covering arcs.

cheers
S.

EDIT: The project included here, has a range-check error. The project in reply #13 is a fixed version.
« Last Edit: January 17, 2026, 05:58:07 pm by speter »
I climbed mighty mountains, and saw that they were actually tiny foothills. :)

440bx

  • Hero Member
  • *****
  • Posts: 6082
Re: Olympic Rings (Interleaved)
« Reply #11 on: January 17, 2026, 09:20:21 am »
That looks really good. :)
FPC v3.2.2 and Lazarus v4.0rc3 on Windows 7 SP1 64bit.

Boleeman

  • Hero Member
  • *****
  • Posts: 1108
Re: Olympic Rings (Interleaved)
« Reply #12 on: January 17, 2026, 10:34:01 am »
With the latest speter version I noticed that 12 seems to be the common factor of 36, 60, 72 and 120 in the main part of the code:

Code: Pascal  [Select][+][-]
  1. begin
  2.   with panel_drawing_area do
  3.     begin
  4.       scale := min(width / grid.x, height / grid.y);
  5.       lt := point(trunc((width - scale*grid.x) / 2),
  6.                   trunc((height - scale*grid.y) / 2));
  7.  
  8.       canvas.pen.width := 1;
  9.       canvas.brush.color := clwhite;
  10.       canvas.pen.color := canvas.brush.color;
  11.       canvas.rectangle(lt.x,lt.y, lt.x + trunc(grid.x*scale), lt.y + trunc(grid.y*scale));
  12.  
  13.       canvas.pen.color := clblack;
  14.       canvas.brush.style := bsclear;
  15.       canvas.pen.width := trunc(12*scale);
  16.       dia := trunc(120*scale);
  17.       sc60 := trunc(60*scale);
  18.       sc36 := trunc(36*scale);
  19.  
  20.       for a := 0 to 4 do
  21.         begin
  22.           x := lt.x + trunc(scale*(36 + a*72));
  23.           y := lt.y + sc36;
  24.           if odd(a) then
  25.             y += sc60;
  26.  
  27.           canvas.pen.color := colours[a];
  28.           canvas.ellipse(x,y, x + dia, y + dia);
  29.         end;
  30.  
  31.       // draw the arcs, to fix overlapping
  32.       for a := 0 to 4 do
  33.         begin
  34.           canvas.pen.color := colours[order[a]];
  35.           x := lt.x + trunc(scale*(36 + order[a]*72));
  36.           y := lt.y + sc36;
  37.           angle := angle1;
  38.           if odd(order[a]) then
  39.             begin
  40.               y += sc60;
  41.               angle := angle2;
  42.             end;
  43.  
  44.           canvas.arc(x,y, x + dia, y + dia, angle, arc_len);
  45.         end;
  46.     end;
  47. end;  

Also is the penwidth of each ring: 
canvas.pen.width := trunc(12*scale);


I like picking up patterns.
Looks like the code could be optimized, but trunc seems to make small differences in the renderings when I tried that out.
« Last Edit: January 17, 2026, 10:35:48 am by Boleeman »

speter

  • Sr. Member
  • ****
  • Posts: 487
Re: Olympic Rings (Interleaved)
« Reply #13 on: January 17, 2026, 05:51:36 pm »
With the latest speter version I noticed that 12 seems to be the common factor of 36, 60, 72 and 120 in the main part of the code:
Yes there is lots of base-6 numbering; which is an attribute of the image I found. When I imported it into GIMP to check out the geometry, I found that the circles' radii ~60px and thickness ~11px (I changed that to 12 to make the thickness 1/5 of the radius). I was tempted to change the numbers to use base-5, but decided not to bother.

Note that the project posted in reply #10 includes a range check error (the second loop should be 0..3 not 0..4). So I am posting a corrected version here.

cheers
S.
« Last Edit: January 17, 2026, 05:54:24 pm by speter »
I climbed mighty mountains, and saw that they were actually tiny foothills. :)

Boleeman

  • Hero Member
  • *****
  • Posts: 1108
Re: Olympic Rings (Interleaved)
« Reply #14 on: January 18, 2026, 04:28:24 am »
Thanks for the fix speter. Not sure why, but Lazarus IDE did not complain about that error.

Ah also found in arc_len =  20*16;   the *16 is old Delphi (back in the integer days) a one degree equivalent.

With speter's nice Olympic Rings interleaving I am tempted to go back to https://forum.lazarus.freepascal.org/index.php/topic,72212.msg564983.html#msg564983  and try to attempt the other interleaving configurations from that CSharp source that Rod Stevens so cleverly did.

« Last Edit: January 18, 2026, 04:49:12 am by Boleeman »

 

TinyPortal © 2005-2018