

Title  Draw "stars" inside regular polygons 
Description  This example shows how to draw "stars" inside regular polygons in Visual Basic. 
Keywords  star, polygon 
Categories  Graphics 


The program draws stars by drawing lines between the vertices on a regular polygon. It always connects the current vertex to the Kth vertex after it. For example, a normal fivepointed star is drawn inside a pentagon by connecting every 2nd vertex. I.e. vertex 0 is connected to vertex 2, then vertex 4, then vertex 1, then vertex 3, then vertex 0 (draw one on paper if you don't understand this).
This drawing scheme will visit every vertex in the polygon before repeating if and only if the number of vertices N and the number K is relatively prime (i.e. have no common factors). I'll leave the proof to you. In the previous example, N = 5 and K = 2 are relatively prime so that drawing method visits every point before repeating.
Note that K = 1 is relatively prime to any number N so drawing with K = 1 visits every vertex before repeating. That just gives the polygon itself.
Also note that K = k and K = N  k draw the same "star." Try K = 2 and K = 3 for a pentagon.
Subroutine DrawStars draws the stars for a polygon with a given number of points. It allocates space for the polygon's points and places them evenly spaced around a circle. It then loops over the numbers 1 through N \ 2 and tries using them as K. It doesn't need to examine values N \ 2 through N because of the second note above.
For each skip (K) value, the program determines the greatest common divisor (GCD) of K and N. If the GCD is 1, then N and K are relatively prime and the program draws the "star."


' Draw the applicable stars.
Private Sub DrawStars()
Const RADIUS As Single = 40
Const PI As Double = 3.14159265
Dim skip, i, x, y As Integer
Dim pts() As POINTAPI
Dim theta As Double
Dim dtheta As Double
If m_NumPoints < 3 Then Exit Sub
' Position the original points.
ReDim pts(0 To m_NumPoints  1)
theta = PI / 2
dtheta = 2 * PI / m_NumPoints
For i = 0 To m_NumPoints  1
pts(i).x = RADIUS * Cos(theta)
pts(i).y = RADIUS * Sin(theta)
theta = theta + dtheta
Next i
' Draw stars.
y = RADIUS + 5
x = RADIUS + 5
picCanvas.Cls
For skip = 1 To m_NumPoints \ 2
' See if they are relatively prime.
If GCD(skip, m_NumPoints) = 1 Then
' Draw the star.
DrawStar picCanvas.hDC, x, y, pts, skip
' Draw a label.
CenterTextHorizontally picCanvas, _
Format$(skip), x, y + RADIUS + 2
x = x + 2 * RADIUS + 5
If x + RADIUS >= picCanvas.ScaleWidth Then
y = y + 2 * RADIUS + 15
x = RADIUS + 5
End If
End If
Next skip
End Sub


Subroutine GCD determines the greatest common divisor of two numbers. I'll leave this proof to you, too.


' Return the greatest common divisor (GCD) of a and b.
Public Function GCD(ByVal a As Long, ByVal b As Long) As _
Long
Dim tmp As Long
Dim remainder As Long
' Make a >= b.
a = Abs(a)
b = Abs(b)
If a < b Then
tmp = a
a = b
b = tmp
End If
' Pull out remainders.
Do
remainder = a Mod b
If remainder = 0 Then Exit Do
a = b
b = remainder
Loop
GCD = b
End Function





