Click here to Skip to main content
15,351,089 members
Articles / Desktop Programming / Windows Forms
Posted 1 Feb 2014


67 bookmarked

The Spiral TrackBar Control

Rate me:
Please Sign up or sign in to vote.
4.95/5 (56 votes)
13 Oct 2020CPOL7 min read
A track bar control which displays the track line as a spiral
In this article, you will learn about the SpiralTrackBar class. This class is a replacement for the .NET 2.0 TrackBar control, which displays the track line as a spiral.


This is release 1.0.3. It fixes a bug whereas the marker could jump to the wrong track if the starting angle was zero and the number of rotations was greater than 1.0.

The SpiralTrackBar class is a replacement for the .NET 2.0 TrackBar control, which displays the track line as a spiral.

Image 1 Image 2

All public and protected classes, methods and properties are fully documented using standard C# XML documentation comments. The project includes a HTML help file. Refer to the Overview section in the help file for more details on using the class.

All members of the control are fully configurable within Visual Studio Designer.

The SpiralTrackBar_103_Library download includes:

  GAW.SpiralTrackBar.dll Class library
  GAW.SimpleWidgets.dll Required library
  GAW.SpiralTrackBar.chm Help file

The SpiralTrackBar_103_Demo download includes the above files, as well as:

  GAW.SpiralTrackBarExplorerApp.exe Sample app demonstrating all of the SpiralTrackBar properties

The SpiralTrackBar_103_Source download includes the source for the SpiralTrackBar control and the explorer app as well as the necessary files for building the help file. It does not include the source for the SimpleWidgets library. That is available in a different project.

Compatibility with Other .NET Framework Versions

The SpiralTrackBar library is compiled using .NET Framework version 2.0. To confirm that there were no issues with other framework versions, the compiled library was used by an application which was compiled, in turn, under .NET Framework versions 3.0, 3.5, 4.0, and 4.5. The SpiralTrackBar functioned properly with all of them.

Using the Control

The possible values range from Minimum to Maximum in increments of StepSize. The current value is specified by the property Value, which increases as the marker is moved counter clockwise, and decreases as the marker is moved clockwise.

The Track Line

The size and orientation of the track line is determined by the properties StartAngle, Rotations, IndentStart, and IndentEnd.

StartAngle is specified in degrees measured clockwise from the x-axis. Rotations is the length of the track line arc (for example, 1.4 would be 504 degrees). The indent values are relative to the size of the control, where 0.0 is defined as the center of the control, and 1.0 is the distance from the center of the control to the nearest edge:

Image 3

The shape of the track line is determined by the properties TrackFillSize, TrackBorder, TrackFill, and TrackEnd.

Tick Marks

The length and position of the tick marks is determined by the properties TickLength and TickStyle. The thickness, color, and style of the line is determined by TickLine.

Major ticks occur every MajorTickFrequency steps. Minor ticks occur every MinorTickFrequency steps (there are no minor ticks if this value is zero). Major ticks are TickLength pixels long. Minor ticks are half length.

The spacing of tick marks on the track line is determined by the property TickSpacing. If TickSpacing is SpiralTrackBarTickSpacing.ArcLength, the tick marks are evenly spaced along the track line. If TickSpacing is SpiralTrackBarTickSpacing.Angular, the tick marks are spaced using angular increments. In this case, the tick marks will be closer together at the beginning of the track line, and farther apart near the end.

Image 4 Image 5
Angular ArcLength


The marker indicates the current value on the track line. It can be dragged with the mouse or moved programmatically.

The shape of the marker is determined by MarkerShape, the border is determined by MarkerBorder, and the interior fill is determined by MarkerFill.

Spiral Math

This section explains the math for plotting the spiral, drawing the tick marks, and calculating arc length.

The equation of a spiral in polar coordinates is:

$\begin{aligned} r = A + B \theta \end{aligned}$

where \(r\) is the distance from center, and \(\theta\) is the angle, specified in radians measured clockwise from the x-axis. The constants \(A\) and \(B\) depend on the size of the control, the indent values, and the start and stop angles:

$\begin{aligned} B & = m (i_1 - i_2) / (r_1 - r_2) \\ A & = m i_1 - B r_1 \end{aligned}$


\(m\) Minimum of the control width and height
\(i_1, i_2\) IndentStart, IndentStop members
\(r_1, r_2\) StartAngle, StopAngle members in radians

The formula to convert a point in polar coordinates to Cartesian coordinates is:

$\begin{aligned} x = r \cos(\theta) \\ y = r \sin(\theta) \end{aligned}$

Location of Tick Marks

The tick marks are drawn perpendicular to the tangent of the spiral, so we need to calculated the tangent. The general equation of a tangent on a curve in polar coordinates is:

$\begin{aligned} t = \dfrac{r' \sin(\theta) + r \cos(\theta)} {r' \cos(\theta) - r \sin(\theta)} \end{aligned}$

where \(r '\) is first derivative of \(r\). In the case of spiral,

$\begin{aligned} r' = B \end{aligned}$

So the slope of a tick mark at position \(\theta\) on the spiral is:

$\begin{aligned} m & = \dfrac{-1}{t} \\ & = \dfrac{r \sin(\theta) - B \cos(\theta)} {B \sin(\theta) + r \cos(\theta)} \\ & = \dfrac{(A + B \theta) \sin(\theta) - B \cos(\theta)} {B \sin(\theta) + (A + B \theta) \cos(\theta)} \end{aligned}$

Arc Length

In order to place tick marks equidistant along the spiral, we need to calculate the arc length of the curve. The general equation for arc length on a curve in polar coordinates is:

$\begin{aligned} L = \int{ \sqrt{ r'^2 + r^2 } } d\theta \end{aligned}$

which expands to:

$\begin{aligned} L & = \int{ \sqrt{ B^2 + r^2 } } d\theta \\ & = \int{ \sqrt{ B^2 + (A + B \theta)^2 } } d\theta \end{aligned}$

The messy solution to this integral comes courtesy of Handbook of Tables for Mathematics (4th edition) (page 562 - integral formula #242). After many steps (not shown here), the final equation for the arc length is:

$\begin{aligned} L & = \dfrac{r \sqrt{ B^2 + r^2 }}{2 B} + \dfrac{B \log(2 B (\sqrt{ B^2 + r^2 } + r))} {2} \\ & = \dfrac{(A + B \theta) \sqrt{ B^2 + (A + B \theta)^2 }}{2 B} + \dfrac{B \log(2 B (\sqrt{ B^2 + (A + B \theta)^2 } + (A + B \theta)))} {2} \end{aligned}$

Note that this equation can not be inverted. That is, there is no function \(f\) such that:

$\begin{aligned} \theta = f(L) \end{aligned}$

So the only to find \(\theta\) for a given arc length \(L\) is through interpolation.

Points of Interest

After deriving the solution to the arc length formula, my concern was this would be an expensive calculation to be performed repetitively - square root and a log operations were not (computationally) cheap. My plan was to build a table of pre-calculated values to reduce the number of calculations to be done while interpolating. The pre-calculated values would prove to be unnecessary. My computer - purchased in 2008 and equipped with a Pentium D processor - was able to perform over four thousand arc length calculations in under one millisecond, or about four million calculations per second.

Further research led me to discovery that Pentium processors have instructions to handle many floating point operations which used to be done in software, such as square root, log, and trigonometric functions. This was, for me, a WOW moment. I first learned assembler over 30 years ago on the Z-80. An 8-bit processor with some 16-bit capabilities. It's arithmetic instructions were limited adding, subtracting and shifting integers. It didn't even have an instruction for an an 8-bit multiply. We've come a long way.

There are three read-only properties which reveal statistics internal to the control:

  • CalcLayoutArcCount - Number of arc length calculations performed
  • CalcLayoutTime - Number of milliseconds to calculate the most recent layout
  • PaintTime - Number of milliseconds spent during the most recent paint operation


  • October 12, 2020 - Release 1.0.3
    • Fixed a bug whereas the marker could jump to the wrong track if the starting angle was zero and the number of rotations was greater than 1.0
  • September 13, 2014 - Release 1.0.2
    • Converted .csproj files to Visual Studio 2013 format
    • Converted help files to work with SandCastle Help File Builder 2014.5.31.0
  • February 5, 2014 - Release 1.0.1
    • Fixed missing tags in documentation
  • February 2, 2014 - First release


This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


About the Author

Graham Wilson
Software Developer (Senior)
Canada Canada
No Biography provided

Comments and Discussions

QuestionGreat work Pin
NickyBics15-Oct-20 6:57
MemberNickyBics15-Oct-20 6:57 
AnswerRe: Great work Pin
Graham Wilson16-Oct-20 3:20
MemberGraham Wilson16-Oct-20 3:20 
Question5 from Me Pin
MarkTX14-Oct-20 7:18
MemberMarkTX14-Oct-20 7:18 
AnswerRe: 5 from Me Pin
Graham Wilson14-Oct-20 14:34
MemberGraham Wilson14-Oct-20 14:34 
QuestionWoW.. You get 5 from me. Pin
Member 428156614-Oct-20 4:22
MemberMember 428156614-Oct-20 4:22 
AnswerRe: WoW.. You get 5 from me. Pin
Graham Wilson14-Oct-20 14:33
MemberGraham Wilson14-Oct-20 14:33 
PraiseBrilliant and +5 Pin
grralph114-Oct-20 0:28
Membergrralph114-Oct-20 0:28 
GeneralRe: Brilliant and +5 Pin
Graham Wilson14-Oct-20 14:32
MemberGraham Wilson14-Oct-20 14:32 
QuestionYou've got my 5... Pin
Johnny J.13-Oct-20 23:37
professionalJohnny J.13-Oct-20 23:37 
AnswerRe: You've got my 5... Pin
Graham Wilson14-Oct-20 14:31
MemberGraham Wilson14-Oct-20 14:31 
GeneralRe: You've got my 5... Pin
Johnny J.14-Oct-20 21:23
professionalJohnny J.14-Oct-20 21:23 
GeneralMy vote of 5 Pin
BillWoodruff13-Oct-20 20:40
mveBillWoodruff13-Oct-20 20:40 
GeneralRe: My vote of 5 Pin
Graham Wilson14-Oct-20 14:28
MemberGraham Wilson14-Oct-20 14:28 
QuestionMaybe a little bit crazy but I like it! :) Pin
LightTempler13-Oct-20 9:07
MemberLightTempler13-Oct-20 9:07 
AnswerRe: Maybe a little bit crazy but I like it! :) Pin
Graham Wilson14-Oct-20 14:26
MemberGraham Wilson14-Oct-20 14:26 
QuestionHow to simulate the motors movement? Pin
yuzaihuan21-Jun-16 22:46
Memberyuzaihuan21-Jun-16 22:46 
AnswerRe: How to simulate the motors movement? Pin
Graham Wilson1-Jul-16 11:19
MemberGraham Wilson1-Jul-16 11:19 
GeneralRe: How to simulate the motors movement? Pin
yuzaihuan13-Aug-16 22:33
Memberyuzaihuan13-Aug-16 22:33 
GeneralMy vote of 5 Pin
User 1106097921-Jan-16 3:47
MemberUser 1106097921-Jan-16 3:47 
GeneralRe: My vote of 5 Pin
Graham Wilson21-Jan-16 15:48
MemberGraham Wilson21-Jan-16 15:48 
GeneralMakes me a bit dizzy looking at it... Pin
Brisingr Aerowing13-Sep-15 14:28
professionalBrisingr Aerowing13-Sep-15 14:28 
GeneralRe: Makes me a bit dizzy looking at it... Pin
Graham Wilson14-Sep-15 7:14
MemberGraham Wilson14-Sep-15 7:14 
QuestionCool Pin
Member 188040315-Sep-14 4:38
MemberMember 188040315-Sep-14 4:38 
AnswerRe: Cool Pin
Graham Wilson15-Sep-14 5:15
MemberGraham Wilson15-Sep-14 5:15 
QuestionNice, but where would you use this? Pin
Louis van Alphen5-Feb-14 8:10
MemberLouis van Alphen5-Feb-14 8:10 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.