FE 'tkGooie' Utilities

IMAGEcreators
Shaded3D group

A Tk GUI
to Draw
SPIRALING-SQUARES

with a color-shaded,
3D-like effect

(FE = Freedom Environment)

FE 'tkGooie' interface for
a maker of color-shaded,
3D-like SPIRALING SQUARES

FE Home Page > FE Downloads Page >

FE 'tkGooies' Description Page >

FE 'tkGooies' 'IMAGEcreatorsShaded3D' Page >

This 'draw_SPIRALING-SQUARES_colorShaded3D' tkGooie Page

INTRODUCTION to
Code for a Tcl-Tk GUI to
'Draw SPIRALING-SQUARES
with a color-shaded 3D effect'

There is a rather old (1986) but nice book on computer graphics called 'Programming Principles in Computer Graphics', by Leendert Ammeraal, published by Wiley & Sons.

There are many nice examples of 2D and 3D graphics programs in that book. The graphics were apparently rendered on a black-and-white pen plotter, with essentially all the figures done in 'wireframe' mode.

Ammeraal provided code for many of the figures (in the C programming language).

The first figure in the book is the output of a program that he called SQUARES, and the output looked like this.

His figure did not have these jaggies.

He apparently did the plots on a pen plotter (or high-resolution raster-image plotter circa 1985?) with a resolution of around 150 dots/inch or better.

    (I did this rendering with the Tk script whose code is below.

    The rendering was on an LCD monitor at 1024x768 resolution, whose screen width and height were about 13.4 and 10.6 inches --- or about 1024/13.4 ~ 76 pixels/inch --- and 768/10.6 ~ 73 pixels/inch.

    Perhaps on a 150 pixels/inch monitor, or better, the jaggies would be hard to see.)

On seeing the SQUARES figure and the code, and based on my recent coding experiences with Tcl-Tk, I figured that this 2D graphics example was due for an update --- about 26 years later. But done on a Tk canvas instead of with a black-on-white plotter.

Using the Tk canvas, I could provide some colors --- colors for the outlines of the squares (using the '-outline' option of the Tk canvas 'create rectangle' command) and color for the canvas background.

Furthermore, I could use the '-fill' option of the Tk canvas 'create rectangle' command to make a sequence of color-filled squares.

But if I used the same constant color for the squares, I would end up with a canvas filled with a solid color.

So I decided to 'gradiate' the color of the filled-squares from one user-specified color to another.

And as a basis for all this, I could use the C code that Ammeraal presented.

For reference, here is the code that I keyed from my copy of the book.



   /* SQUARES: This program draws 50 squares inside each other */
   main ()
   { float xA, yA, xB, yB, xC, yC, xD, yD,
      xxA, yyA, xxB, yyB, xxC, yyC,xxD, yyD, p ,q ;
      int i;
      p=0.95; q=1.0-p;
      xA=2.0; xB=8.0; xC=8.0; xD=2.0;
      yA=0.5; yB=0.5; yC=6.5; yD=6.5;
      intgr();
      for (i=0; i<50; i++)
      { move(xA, yA);
         draw(xB, yB); draw(xC, yC); draw(xD, yD); draw(xA, yA);
         xxA=p*xA+q*xB; yyA=p*yA+q*yB; xxB=p*xB+q*xC; yyB=p*yB+q*yC;
         xxC=p*xC+q*xD; yyC=p*yC+q*yD; xxD=p*xD+q*xA; yyD=p*yD+q*yA;
         xA=xxA; xB=xxB; xC=xxC; xD=xxD;
         yA=yyA; yB=yyB; yC=yyC; yD=yyD;
      }
      endgr();
   }


After a couple of days of Tcl-Tk coding and enhancing, I arrived at the following Tk GUI to implement the spiraling squares --- with an option to show the squares in 'outline' mode or in 'fill' mode, with gradiation between 2 user-specified 'fill' colors.

The 'Proportion to advance' slider bar allows the user to specify a fraction between 0 and 1.

By specifying exactly 0.5, one gets a spiral like the following.

And if you unset the 'Outline' checkbutton, the Tk script goes into 'Fill' mode and makes a spiral of squares that gradiate in color from one user-chosen color (yellow in the following image) to another user-chosen color (black in this example).

    When the user turns OFF the 'Outline Square' checkbutton, the single 'Outline Color' button changes to TWO 'Fill Color' buttons --- 'Fill 1' and 'Fill 2'.

After experimenting with this GUI a little, I realized that it would be nice to have some control over the 'rate' at which the color gradiation was occurring between the two colors --- for a given N, where N is the number of squares to be drawn.

In the intitial implementation, I simply had the colors graduating 'linearly' between the two colors as the index 'i' advanced from 1 to N.

This was equivalent to weighting the 2 colors with two factors: (1 - i/N) and (i/N). One factor essentially goes from one to zero; the other from zero to one.

I have written a few 2D graphics Tk scripts that put nice color-shaded edges on geometric shapes.

I posted those scripts at wiki.tcl.tk, and on this freedomenv.com site, at pages:

In those, I used a 'color metric', v, over the geometric shape, where v varied between zero and 1.

Then I used factors (1 - v^M) and v^M, applied to two user-selected colors --- where M is an exponent, positive integer or real number.

I used the Tcl 'pow' (power) function to compute v^M via pow(v,M).

In this spiraling-squares case, I used a similar 'color metric', v = i/N. And I provided a scale widget on the GUI, so that the user can set the exponent M.

The following GUI is the result.

The exponent M controls what I call the 'extensity' of the color gradient, because it seems to control the 'extent' and/or 'intensity' of the color at the edges of the shape --- in this case, at the outer square's edges and the inner square's edges.

In this image and the one above it, I used the same values for the 'Proportion' and 'Number of squares' scales -- 0.01 and 91.

So, by comparing the 2 images, you can see the difference that one can make between the linear-gradiation of the colors (in the upper image) and an image made with an 'extensity' exponent, of 6.0, for example.

The linear color gradient is given by setting the 'extensity' exponent to 1.0.

---

Some uses of these images

This 'spiraling squares' program seems to be just 'for grins'.

But I can see some uses for the resulting images:

  • backgrounds for logos
  • backgrounds for icons
  • frames for photos

and no doubt you can think of some more.

I present an example 'photo-frame' image below the code that is presented below.


DESCRIPTION OF THE CODE

I provide the code for this 'spiraling squares' GUI below.

I follow my usual 'canonical' structure for Tk code, for this Tk script:



  0) Set general window & widget parms (win-name, win-position,
     win-color-scheme, fonts, widget-geometry-parms, win-size-control,
     text-array-for-labels-etc).

  1a) Define ALL frames (and sub-frames, if any).
  1b) Pack   ALL frames and sub-frames.

  2) Define & pack all widgets in the frames, frame by frame.

  3) Define keyboard and mouse/touchpad/touch-sensitive-screen action
     BINDINGS, if needed.

  4) Define PROCS, if needed.

  5) Additional GUI initialization (typically with one or more of
     the procs), if needed.


This Tk coding structure is discussed in more detail on the page A Canonical Structure for Tk Code --- and variations.

This makes it easy for me to find code sections --- while generating and testing this script, and when looking for code snippets to include in other scripts (code re-use).

I call your attention to step-zero. One new thing that I have started doing recently is using a text-array for text in labels, buttons, and other widgets in the GUI. This can make it easier for people to internationalize my scripts. I will be using a text-array like this in most of my scripts in the future.


Experimenting with the GUI

As in all my scripts that use the 'pack' geometry manager (which is all of my 100-plus scripts, so far), I provide the four main pack parameters --- '-side', '-anchor', '-fill', '-expand' --- on all of the 'pack' commands for the frames and widgets.

That helps me when I am initially testing the behavior of a GUI (the various widgets within it) as I resize the main window.

I think that I have used a nice choice of the 'pack' parameters. The labels and buttons and scales stay fixed in size and relative-location as the window is re-sized --- while the 'canvas' expands/contracts as the window is re-sized.

You can experiment with the '-side', '-anchor', '-fill', and '-expand' parameters on the 'pack' commands for the various frames and widgets --- to get the widget behavior that you want.

---

Additional experimentation:
You might want to change the fonts used for the various GUI widgets. For example, you could change '-weight' from 'bold' to 'normal' --- or '-slant' from 'roman' to 'italic'. Or change font families.

In fact, you may NEED to change the font families, because the families I used may not be available on your computer --- and the default font that the 'wish' interpreter chooses may not be very pleasing.

I use variables to set geometry parameters of widgets --- parameters such as border-widths and padding. And I have included the '-relief' parameter on the definitions of frames and widgets. Feel free to experiment with those 'appearance' parameters as well.

---

Note that the color buttons call on a color-selector-GUI script to set the colors.

You can make that color-selector script by cutting-and-pasting the code from the page that offers a non-obfuscated color selector GUI on this site.


Some features in the code

There are plenty of comments in the code to describe what most of the code-sections are doing.

See the top of the 'PROCS' section for a list of the procs used in this Tk script.

See comments in the procs for details on the purpose of each proc and for details on the methods by which each proc was implemented.

Here is a quick overview of the procs --- to give an idea of the 'guts' of this utility:



  - ReDraw                 - called by:
                              - the 'set_*_color*' procs
                              - button1-release binding on the outline/fill checkbutton
                              - button1-release binding on the 'p' (proportion to advance) scale
                              - button1-release binding on the 'N' (number of squares) scale
                              - button1-release binding on the 'M' (extensity) scale
                            Also to be called when the window (and thus the canvas
                            and the image area) is resized.

  - set_squares_color1      - called by the outline or 'fill1' color button

  - set_squares_color2      - called by the 'fill2' color button

  - set_background_color    - called by background color button

  - show_hide_fill_buttons  - called by button1-release on the outline checkbutton


The Tcl-Tk code that is adapted from Ammeraal's SQUARES C-code is in the proc 'ReDraw'.

Note that Ammeraal hard-coded the values for p (what I call 'Proportion to advance') and N (the number of squares to draw). I allow the user to change those 2 parameters via a couple of scale widgets on the GUI.

Ammeraal also fixed the size of the starting square. With this GUI, when the window is re-sized, the canvas is re-sized accordingly, and the initial square size is determined from the current canvas size.

---

One interesting feature of this GUI is that when the user 'turns off' the 'Outline' option via the checkbox, the GUI changes --- an additional color button is added to the row of buttons at the top of the GUI.

This is to allow the user to specify a 2nd color for the color-gradient in the 'fill' mode of drawing the squares.

I originally had all the buttons showing, but the button labelling was rather confusing and the extra button when in 'outline' mode was also rather confusing.

So I decided to make the buttons change according to the setting of the 'outline checkbutton'.

The Tk 'pack forget' command is used to implement to hiding/showing of the extra color button.


Comments in the Code

It is my hope that the copious comments in the code will help Tcl-Tk coding 'newbies' get started in making GUI's like this.

Without the comments, it might not be clear the purpose of some of the code --- for example, how the 'pack forget' command is being used to hide/show the additional fill-color button.

Without the comments, potential young Tcler's might be tempted to return to their iPhones and iPads and iPods --- to watch videos of people being bashed to the street by large vehicles.


The Tcl-Tk CODE

Here is a link to CODE for the script 'draw_squares_spiral.tk'.

With your web browser, you can 'right-click' on this link --- and in the menu that pops up, select an item like 'Save Link Target As ...' --- to save this file to your local computer.

Then you can rename the file to remove the '.txt' suffix. Make sure that you have execute permission set on the file --- in order to execute the script.


An example of using a
spiraling-squares color-shaded-image

Here is an image that I made from one of the yellow-to-black spiraling-squares images above --- by making black transparent, and overlaying the image over a photo image.

To make this image, I actually used my 'Title Block' utility, whose code I posted at a wiki.tcl.tk page, and later on this freedomenv.com site, at A GUI for making 'Title Blocks' . . . with text, fonts, colors, images.

The exact sequence of steps that I followed are:

  1. I used the 'mtpaint' image-editor program (on Linux) to crop the canvas image from the spiraling squares (yellow-to-black) GUI window capture above.

  2. I used one of my 'feNautilusScripts', which uses the ImageMagick command 'convert', with '-transparent' and '-fuzz' options, to make a transparent GIF, using black as the color to make transparent.

  3. I converted a JPEG photo of a face to a 256-color GIF file, again using one of my 'feNautilusScripts', which uses the ImageMagick command 'convert', with '-palette 256', to make a GIF file from the photo.

  4. I started up my 'TitleBlock' utility and imported first the face-GIF and dragged that image to the middle of the canvas. Then I imported the yellow-shaded-GIF and dragged it over the face-GIF image.

  5. Then I did a screen capture of the 'TitleBlock' GUI with the 'gnome-screenshot' utility, on Linux.

  6. I took the captured image, in a PNG file, into the 'mtpaint' image-editor program to crop it. I saved the cropped image as a PNG file.

  7. I have found the PNG files from 'mtpaing' to be quite large. So I used another of my 'feNatuilusScripts', which uses the ImageMagick command 'convert', with '-quality 92', to make a '.jpg' file from the framed-photo image.

It looks like a lot, but it only took a couple of minutes, thanks to my 'feNautilusScripts' and the 'TitleBlock' utility --- as well as thanks to 'mtpaint' and 'gnome-screenshot'.


Some Next Steps

At the end of each chapter of Ammeraal's book, he presents some exercises. At the end of the first chapter, he proposes "Write a program to draw a great number of triangles inside each other similar to the way in which the squares are drawn in the program SQUARES".

If I were to take on such an exercise, I think it may be more useful to draw pentagons, hexagons, or octagons.

They would be more useful as photo frames and backgrounds for logos/icons/webpage-titles.

There are other interesting examples in the Ammeraal book --- especially in the area of 3D graphics.

I may use some of those examples as food for thought for various 3D Tk GUI's.

Bottom of this page with
Tcl-Tk Code for a GUI to
Draw SPIRALING-SQUARES
with a color-shaded 3D effect

--- a utility in the FE 'tkGooies' system,
in the 'IMAGEcreators - Shaded3D' group.

To return to a previously visited web page location, click on the Back button of your web browser a sufficient number of times. OR, use the History-list option of your web browser.
OR ...

< Go to Top of Page, above. >

Page history:

The code was created in 2012 --- and posted 2012 Nov 27 at http://wiki.tcl.tk/37340.

This FE web page was created 2014 May 10 --- as a backup and alternative to the wiki.tcl.tk page.

This page was changed 2015 Oct 07.
(Small changes.)

Page was changed 2015 Dec 30.
(Added some paragraphs and some links.)

Page was changed 2019 Mar 01.
(Added css and javascript to try to handle text-size for smartphones, esp. in portrait orientation.)

Page was changed 2019 Jun 14.
(Specified image widths in percents to size the images according to width of the browser window.)


NOTE:
The code here MAY BECOME more 'up-to-date' than the code posted on the Tcler's Wiki ---
wiki.tcl-lang.org --- formerly wiki.tcl.tk.