What's New
Q & A
Tip Jar
C# Helper...
Follow VBHelper on Twitter
MSDN Visual Basic Community
TitleMake an elliptical clock with numerals aligned with the ellipse
Keywordsposition, lower right, analog, clock, numerals, time, move form
CategoriesMultimedia, Graphics, Utilities
See Make an analog clock with numerals positioned at the lower right corner of the screen for the basics. This version makes two modifications.

First, tic marks have fixed lengths. In the previous example, tic marks were 5 percent of the distance from the edge of the clock face to the center. In this version, long tic marks are 10 pixels long and short tic marks are 5 pixels long.

The program calculates the point on the ellipse, subtracts the coordinates from the clock's center to get a difference vector, and then divides the vector's components by the vector's length to get a unit vector. It then multiplies by the desired tic mark length.

' Find the point on the ellipse.
x1 = cx + cx * Cos(theta)
y1 = cy + cy * Sin(theta)

' Find the unit vector towards the center.
dx = cx - x1
dy = cy - y1
R = Sqr(dx * dx + dy * dy)

If i Mod 5 = 0 Then
    ' Find the end point for a long
    ' tic mark.
    x2 = x1 + dx / R * LONG_TIC_LENGTH
    y2 = y1 + dy / R * LONG_TIC_LENGTH
    ' Find the end point for a long
    ' tic mark.
    x2 = x1 + dx / R * SHORT_TIC_LENGTH
    y2 = y1 + dy / R * SHORT_TIC_LENGTH
End If
Line (x1, y1)-(x2, y2)
The second change modifies how the text is aligned. In the original version, the numerals are rotated to fit their positions along a circle. This doesn't quite match the rotation of the ellipse. It's good enough for an ellipse that is reasonably close to a circle but is noticably off when the ellipse is very tall and thin or short and wide.

This version uses the ATan2 arctangent function to find the direction (in radians) of the vector from the point on the ellipse towards the center. It subtracts that angle from PI radians to get the text's escapement angle.

' Find the tic mark's angle.
ang = ATan2(dy, dx)

' Create a rotated font.
new_font = CustomFont(16, 0, _
    (PI / 2 - ang) * 1800 / PI, 0, _
    700, False, False, False, _
    "Times New Roman")
old_font = SelectObject(hdc, new_font)
Copyright © 1997-2010 Rocky Mountain Computer Consulting, Inc.   All rights reserved.