Skip to content

This interactive application provides a visual demonstration of arcs drawn with various starting and sweep angles

License

Notifications You must be signed in to change notification settings

JoeLumbley/Draw-Arc

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

39 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Draw Arc

This interactive application provides a visual demonstration of arcs drawn with various starting and sweep angles using GDI (Graphics Device Interface) graphics.

It aims to help users gain a deeper understanding of how angles affect the rendering of arcs in graphical applications.

003

Features

  • Interactive Visualization: Adjust starting and sweep angles dynamically to see real-time changes in arc rendering.
  • Intuitive Controls: User-friendly interface for manipulating angles.
  • Educational Tool: Designed to help users grasp the concepts of angles in graphics programming.

Code Walkthrough

Imports

Imports System.Drawing.Drawing2D
  • This line imports the System.Drawing.Drawing2D namespace, which provides advanced 2D graphics functionality. It includes classes for drawing shapes, such as arcs and curves.

Class Definition

Public Class Form1
  • This line defines a new class called Form1. A class is a blueprint for creating objects. Here, Form1 is a form (window) in the application.

Variable Declarations

Private Context As BufferedGraphicsContext
Private Buffer As BufferedGraphics
  • Context: This variable will hold the graphics context for buffered graphics, which helps in rendering graphics smoothly.
  • Buffer: This variable is used to store the graphics buffer, which allows for double buffering to reduce flickering during drawing.

Structure Definition

Private Structure DisplayStructure
    Public Location As Point
    Public Text As String
    Public Font As Font
End Structure
  • This defines a structure called DisplayStructure that holds information about where to display text (Location), the text itself (Text), and the font used (Font).

More Variable Declarations

Private CodeDisplay As DisplayStructure
Private CircleOfProgress As Rectangle
Private CircleOfProgressPen As Pen
Private CircleOfProgressBackgroundPen As Pen
  • CodeDisplay: An instance of DisplayStructure to display code-related information.
  • CircleOfProgress: A rectangle that defines the area where the arc will be drawn.
  • CircleOfProgressPen and CircleOfProgressBackgroundPen: Pens used to draw the arc and its background.
Private startAngle As Single = 0.0F
Private sweepAngle As Single
  • startAngle: A variable representing the starting angle for the arc (0 degrees).
  • sweepAngle: A variable that will hold the sweep angle, which determines how far the arc extends.

String Format for Centering Text

Private ReadOnly AlineCenterMiddle As New StringFormat With {
    .Alignment = StringAlignment.Center,
    .LineAlignment = StringAlignment.Center}
  • This creates a StringFormat object that centers text both horizontally and vertically.

Form Load Event

Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    InitializeApp()
    Debug.Print($"Program running... {Now.ToShortTimeString}")
End Sub
  • This method is called when the form loads. It initializes the application by calling InitializeApp().
  • It also prints a message to the debug console indicating that the program is running, along with the current time.

Form Resize Event

Private Sub Form1_Resize(sender As Object, e As EventArgs) Handles Me.Resize
    If Not WindowState = FormWindowState.Minimized Then
        ResizeCodeDisplay()
        ResizeControls()
        ResizeCircleOfProgress()
        DisposeBuffer()
    End If
End Sub
  • This method handles the form's resize event. If the window is not minimized, it resizes various components of the form (like text display and controls) and disposes of the buffer to prepare for redrawing.

Timer Tick Event

Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
    If Not WindowState = FormWindowState.Minimized Then
        UpdateCodeDisplay()
        Invalidate() ' Calls OnPaint Sub
    End If
End Sub
  • This method is called every time the timer ticks (every 30 milliseconds, as set later). It updates the code display and triggers a repaint of the form.

OnPaint Method

Protected Overrides Sub OnPaint(ByVal e As PaintEventArgs)
    AllocateBuffer(e)
    DrawDisplays()
    Buffer.Render(e.Graphics)
    MyBase.OnPaint(e)
End Sub
  • This method is overridden to perform custom painting. It allocates a graphics buffer, draws the displays, and then renders the buffer onto the form.

TrackBar Scroll Events

Private Sub StartAngleTrackBar_Scroll(sender As Object, e As EventArgs) Handles StartAngleTrackBar.Scroll
    StartAngleLabel.Text = $"Start Angle: {StartAngleTrackBar.Value}°"
End Sub

Private Sub SweepAngleTrackBar_Scroll(sender As Object, e As EventArgs) Handles SweepAngleTrackBar.Scroll
    SweepAngleLabel.Text = $"Sweep Angle: {SweepAngleTrackBar.Value}°"
End Sub
  • These methods handle the scrolling of two trackbars (sliders) for adjusting the start angle and sweep angle. They update the corresponding labels to show the current angle values.

Update Code Display Method

Private Sub UpdateCodeDisplay()
    CodeDisplay.Text = $"Graphics.DrawArc(Pen, Rectangle, {StartAngleTrackBar.Value}, {SweepAngleTrackBar.Value})"
End Sub
  • This method updates the text displayed in the CodeDisplay structure to show the current code that would be used to draw the arc with the selected angles.

OnPaintBackground Method

Protected Overrides Sub OnPaintBackground(ByVal e As PaintEventArgs)
    'Intentionally left blank. Do not remove.
End Sub
  • This method is overridden but intentionally left blank to prevent flickering during painting.

Allocate Buffer Method

Private Sub AllocateBuffer(e As PaintEventArgs)
    If Buffer Is Nothing Then
        Buffer = Context.Allocate(e.Graphics, ClientRectangle)
        With Buffer.Graphics
            .CompositingMode = Drawing2D.CompositingMode.SourceOver
            .TextRenderingHint = Drawing.Text.TextRenderingHint.AntiAlias
            .SmoothingMode = Drawing2D.SmoothingMode.HighQuality
            .PixelOffsetMode = Drawing2D.PixelOffsetMode.HighQuality
            .CompositingQuality = Drawing2D.CompositingQuality.HighQuality
            .InterpolationMode = InterpolationMode.HighQualityBicubic
            .TextContrast = SmoothingMode.HighQuality
        End With
    End If
End Sub
  • This method checks if the buffer has been allocated. If not, it allocates a new buffer and sets various rendering properties to ensure high-quality graphics.

Draw Displays Method

    Private Sub DrawDisplays()

        If Buffer IsNot Nothing Then

            Try

                With Buffer.Graphics

                    .Clear(SystemColors.Control)

                    .DrawEllipse(CircleOfProgressBackgroundPen,
                                 CircleOfProgress)

                    .DrawArc(CircleOfProgressPen,
                             CircleOfProgress,
                             StartAngleTrackBar.Value,
                             SweepAngleTrackBar.Value)

                    .DrawString(CodeDisplay.Text,
                                CodeDisplay.Font,
                                New SolidBrush(SystemColors.ControlText),
                                CodeDisplay.Location,
                                AlineCenterMiddle)

                End With

            Catch ex As Exception

                Debug.Print("Draw error: " & ex.Message)

            End Try

        Else

            Debug.Print("Buffer is not initialized.")

        End If

    End Sub
  • This method draws the background ellipse, the arc based on the current angles, and the code display text on the buffer. It also handles any potential drawing errors.

Dispose Buffer Method

Private Sub DisposeBuffer()
    If Buffer IsNot Nothing Then
        Buffer.Dispose()
        Buffer = Nothing ' Set to Nothing to avoid using a disposed object
    End If
End Sub
  • This method disposes of the buffer if it exists and sets it to Nothing to avoid using a disposed object.

Initialize App Method

Private Sub InitializeApp()
    InitializeForm()
    InitializeBuffer()
    InitializeLabels()
    InitializeTimer()
End Sub
  • This method initializes the application by calling several initialization methods for the form, buffer, labels, and timer.

Initialize Form Method

Private Sub InitializeForm()
    CenterToScreen()
    SetStyle(ControlStyles.OptimizedDoubleBuffer Or ControlStyles.AllPaintingInWmPaint, True)
    SetStyle(ControlStyles.UserPaint, True)
    Text = "Draw Arc - Code with Joe"
    Me.WindowState = FormWindowState.Maximized
End Sub
  • This method centers the form on the screen, sets styles for double buffering (to reduce flickering), sets the window title, and maximizes the window.

Initialize Buffer Method

Private Sub InitializeBuffer()
    Context = BufferedGraphicsManager.Current
    Context.MaximumBuffer = Screen.PrimaryScreen.WorkingArea.Size
    Buffer = Context.Allocate(CreateGraphics(), ClientRectangle)
    With Buffer.Graphics
        .CompositingMode = Drawing2D.CompositingMode.SourceOver
        .TextRenderingHint = Drawing.Text.TextRenderingHint.AntiAlias
        .SmoothingMode = Drawing2D.SmoothingMode.HighQuality
        .PixelOffsetMode = Drawing2D.PixelOffsetMode.None
        .CompositingQuality = Drawing2D.CompositingQuality.HighQuality
    End With
End Sub
  • This method initializes the graphics buffer context, sets the maximum buffer size, and allocates the buffer with high-quality rendering settings.

Initialize Timer Method

Private Sub InitializeTimer()
    Timer1.Interval = 30
    Timer1.Enabled = True
End Sub
  • This method sets the timer interval to 30 milliseconds and enables the timer, which will trigger periodic updates.

Initialize Labels Method

Private Sub InitializeLabels()
    StartAngleLabel.Text = $"Start Angle: {StartAngleTrackBar.Value}°"
    SweepAngleLabel.Text = $"Sweep Angle: {SweepAngleTrackBar.Value}°"
End Sub
  • This method initializes the text for the angle labels based on the initial values of the trackbars.

Resize Methods

  • ResizeCodeDisplay, ResizeControls, ResizeCircleOfProgress
    Private Sub ResizeCodeDisplay()

        Dim FontSize As Single

        If ClientSize.Height / 25 > 13 Then

            FontSize = ClientSize.Height / 25

        Else

            FontSize = 13

        End If

        Dim YPosition As Integer

        If ClientSize.Height / 2.5 > 175 Then

            YPosition = ClientSize.Height / 2.5

        Else

            YPosition = 175

        End If

        CodeDisplay.Font = New Font("Segoe UI",
                                    FontSize,
                                    FontStyle.Regular)

        CodeDisplay.Location.X = ClientSize.Width / 2

        CodeDisplay.Location.Y = ClientSize.Height / 2 - YPosition

    End Sub

    Private Sub ResizeControls()

        Dim TrackBarWidth As Integer

        If ClientSize.Height / 2 > 225 Then

            TrackBarWidth = ClientSize.Height / 2

        Else

            TrackBarWidth = 225

        End If

        StartAngleTrackBar.Width = TrackBarWidth

        StartAngleTrackBar.Left = ClientSize.Width / 2 - StartAngleTrackBar.Width / 2

        StartAngleTrackBar.Top = ClientSize.Height / 2 - StartAngleTrackBar.Height

        StartAngleLabel.Left = StartAngleTrackBar.Left + 8

        StartAngleLabel.Top = StartAngleTrackBar.Top + 40

        SweepAngleTrackBar.Width = TrackBarWidth

        SweepAngleTrackBar.Left = ClientSize.Width / 2 - SweepAngleTrackBar.Width / 2

        SweepAngleTrackBar.Top = ClientSize.Height / 2 + SweepAngleTrackBar.Height * 0.1

        SweepAngleLabel.Left = SweepAngleTrackBar.Left + 8

        SweepAngleLabel.Top = SweepAngleTrackBar.Top + 40

    End Sub

    Private Sub ResizeCircleOfProgress()

        Dim PenSize As Single

        If ClientSize.Height / 30 > 15 Then

            PenSize = ClientSize.Height / 30

        Else

            PenSize = 15

        End If

        CircleOfProgressBackgroundPen = New Pen(SystemColors.ControlLightLight,
                                                PenSize)

        If ClientSize.Height / 40 > 10 Then

            PenSize = ClientSize.Height / 40

        Else

            PenSize = 10

        End If

        CircleOfProgressPen = New Pen(SystemColors.MenuHighlight, PenSize) With {
            .EndCap = LineCap.Round,
            .StartCap = LineCap.Round
        }

        Dim CircleSize As Single

        If ClientSize.Height / 1.5 > 300 Then

            CircleSize = ClientSize.Height / 1.5

        Else

            CircleSize = 300

        End If

        CircleOfProgress.Width = CircleSize
        CircleOfProgress.Height = CircleSize

        CircleOfProgress.X = ClientSize.Width / 2 - CircleOfProgress.Width / 2
        CircleOfProgress.Y = ClientSize.Height / 2 - CircleOfProgress.Height / 2

    End Sub
  • These methods adjust the size and position of the code display, controls (like trackbars), and the drawing area (circle) based on the current size of the form.

This code creates an interactive application that allows users to visualize how arcs are drawn based on different starting and sweep angles. It uses VB.NET's GDI+ for graphics rendering and provides a user-friendly interface for manipulating the angles. Each section of the code is designed to handle specific aspects of the application, from initialization to drawing and resizing components.

AnglesDiagram02

About

This interactive application provides a visual demonstration of arcs drawn with various starting and sweep angles

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published