Jalaj P. Jha Technical & Miscellaneous Ramblings

16Feb/070




WinAPI : AngleArc Function

After Line let’s see how we draw arcs. AngleArc allows you to draw a circular arc. The arc that’s drawn is actually a part of the circle of given radius, with start angle and angle of sweep determining the start and end points of the arc. The first parameter that it takes is the handle to the device context. The next two parameters specify the X and Y co-ordinates of the center of the circle. Fourth parameter is the radius of the circle. The next two parameters are the start angle, with reference to the X-axis and the sweep angle in anti-clockwise direction.

Private Declare Function AngleArc Lib "gdi32" (ByVal hdc As Long, _
    ByVal x As Long, ByVal y As Long, ByVal dwRadius As Long, _
    ByVal eStartAngle As Single, ByVal eSweepAngle As Single) As Long

However catch here is that the above function not only draws an arc but also a line segement from the current position on device context to the start point of the arc. So if you need to draw a pure arc then you will require to determine the X and Y co-ordinates of the point of start of arc and use MoveToEx function to move to that point before drawing the arc.

Private Declare Function MoveToEx Lib "gdi32" (ByVal hdc As Long, _
    ByVal x As Long, ByVal y As Long, lpPoint As POINTAPI) As Long

Private Type POINTAPI
        x As Long
        y As Long
End Type

Let’s declare all the required variables.

Dim lngCenterX As Long ‘ X-co-ord. of center of circle
Dim lngCenterY As Long ‘ Y-co-ord. of center of circle
Dim lngRadius As Long ‘ Radius of the circle
Dim lngStartAngle As Single ‘ Start Angle
Dim lngEndAngle As Single ‘ End Angle
Dim lngSweepAngle As Single ‘ Sweep angle to be calculated from above two

Dim blnStart As Boolean ‘ Boolean to determine start/end point
Dim objDummyPoint As POINTAPI ‘ Dummy point for MoveToEx

Let’s calculate the Center of the circle as the co-ordinates of center of the form. Assign true to blnStart.

Private Sub Form_Load()

    blnStart = True
    lngCenterX = Form1.ScaleWidth / Screen.TwipsPerPixelX / 2
    lngCenterY = Form1.ScaleHeight / Screen.TwipsPerPixelY / 2

End Sub

The first click on the form will determine the start point of the arc. The distance of that point of click from the center of the form will be stored as the radius. Pythagoras Theorem will be used here to calculate the radius. We will use application defined CalculateAngle function to calculate the angle. We will not get into the Trigonometry and the Co-ordinate system here.

Private Sub Form_MouseDown(Button As Integer, Shift As Integer, _
    x As Single, y As Single)

    If blnStart Then
        MoveToEx Form1.hdc, x / Screen.TwipsPerPixelX, _
            y / Screen.TwipsPerPixelY, objDummyPoint
        lngRadius = Sqr((x / Screen.TwipsPerPixelX - lngCenterX) ^ 2 + _
            (y / Screen.TwipsPerPixelY - lngCenterY) ^ 2)
        lngStartAngle = CalculateAngle(x / Screen.TwipsPerPixelX, _
            y / Screen.TwipsPerPixelY, lngCenterX, lngCenterY)
        blnStart = False
    Else
        lngEndAngle = CalculateAngle(x / Screen.TwipsPerPixelX, _
            y / Screen.TwipsPerPixelY, lngCenterX, lngCenterY)
        lngSweepAngle = lngEndAngle - lngStartAngle
        blnStart = True
        AngleArc Form1.hdc, lngCenterX, lngCenterY, lngRadius, _
            lngStartAngle, lngSweepAngle
    End If

End Sub

Function CalculateAngle(x1, y1, x2, y2)

    If x1  x2 And y1  y2 Then '3rd Quadrant
        CalculateAngle = 180 + Atn((y1 - y2) / (x2 - x1)) * 180 / 3.1416
    End If
    If x1 > x2 And y1 > y2 Then '4th Quadrant
        CalculateAngle = 360 - Atn((y1 - y2) / (x1 - x2)) * 180 / 3.1416
    End If

End Function

anglearc.jpg

The end result of the project can be seen by executing it.

Comments (0) Trackbacks (1)

Leave a comment