Students of analytic geometry, (the kind that combines algebra and
geometry), often work in one of two coordinate systems: **Cartesian**
or **Polar** - and frequently must convert from one to the other. ** **

The Cartesian system locates points on a plane by measuring the
horizontal and vertical distances from an arbitrary origin to a point.
These are usually denoted as a pair of values** (X,Y)**.

The Polar system locates the point by measuring the straight line distance, usually denoted by **R**, from the origin
to the point and the angle of an imaginary line
from the origin to the point, q, (Greek
letter Theta), measured counterclockwise from the positive X
axis.

The conversion math is fairly straightforward:

#### Polar from Cartesian:

**R=Sqrt(x**^{2}+y^{2});

Theta=ArcTan(Y/X); (Note: If both X and Y are positive or
both are negative Y/X will have the same value. Similarly if we
have one value positive and one negative. The angles in these cases will
be different by 180 degrees so signs of X and Y must be considered when
calculating Theta. Luckily, Delphi's ArcTan routine is smart enough to
handle this for us.)

#### Cartesian From Polar:

** X= R*cos(Theta)**

Y= R*sin(Theta)

This program that allows you explore this relationship by dragging sliders to
change **X**, **Y**, **R**, or **Theta** values and observing the
effect on the point and other parameters. Angles may be reported in the
range of 0 to 360 degrees, or equivalently, from -180 to 180
degrees.

Non-programmers can skip to the bottom of the page and download the program now.

#### Programming Techniques

There are a few subtle problems which can occur when using trackbars:

The **TTrackbar**
components used to implement the sliders work fine in the horizontal position,
but when oriented vertically, they perversely put the minimum value at the top
and maximum value on the bottom. To correct for this, we
need to convert values by adding the number of units that the slider is from **max**
(the bottom) to **min**, i.e. **Xreported=min+max-pos. **Simple
but not immediately obvious.

There is another tricky problem that can cause problems when using **OnChange**
event exits. I ran across this in the WindChill program which uses
the exit in each of two sliders change to modify values in the other.
Without provisions to account for this effect -- trackbar A OnChange modifies trackbar B,
whose OnChange modifies trackbar A whose OnChange modies trackbar B, whose..., etc. until we run out of stack space. The fix is a simple
boolean switch for each exit used to control whether or not to honor the
exit. If A wants to modify B, it sets B's "ignore" flag
before doing so, and vice-versa.

One other subtle error can occur if trackbar **max** and **min**
values are modified. In this case, I decided to allow users to set
the range of reported angles to "-180 to +180" or "0 to
360" degrees. If the change puts the current **position**
value out of range, Delphi adjusts it for you so that it is back in range.
It's the right thing to do, but it happens behind the scenes and so can be a
little tricky to debug. The trick is to save **position** value before
adjusting **max** and **min**, then reset **position** as
required.

Enough babble - here's the code.

### Running/Exploring the Program