I find that randomly displayed geometric objects like lines, circles, rectangles and Beziers make real interesting images. I enjoy the cool designs and like to find pattern in randomness. I put together a script which lets you create an image and randomly fill it with geometric objects. You can control the type and number of objects, image background color, output image size as well as drawing pen size and color. The image is saved to disk and displayed.
 
Here are a few examples generated from this script starting with Bezier Splines
 
Beziers1
 
Beziers2
 
Beziers3
 
and Connected Beziers
 
ConnectedBeziers1
 
ConnectedBeziers2
 
Lines
 
Lines1
 
Lines2
 
Connected Lines
 
ConnectedLines1
 
ConnectedLines2
 
Cornerbusrt Lines
 
LineCornerburst1
 
Starburst Lines
 
StarburstLine1
 
Rectangles
 
Rectangles1
 
Rectangles2
 
Ellipses
 
Ellipses1
 
Arcs
 
Arcs1
 
Pie Shapes
 
Pies1
 
Curves
 
Curves1
 
I setup a WinForms Form to collect the objects and pattern info. I defined some global values to be used in later functions.
 

Add-Type -AssemblyName System.Windows.Forms
Add-Type -AssemblyName System.Drawing

# Main Form
$mainForm = New-Object Windows.Forms.Form
$mainForm.Location = "200,200"
$mainForm.FormBorderStyle = "FixedDialog"
$mainForm.BackColor = "Cornsilk"
$mainForm.Font = “Comic Sans MS,8.25"
$mainForm.Text = "Draw Random Geometric Patterns"
$mainForm.Size = "580,550"

# Global Values
$scriptPath = split-path -parent $MyInvocation.MyCommand.Definition
$global:numberObjects = 100
$global:penWidth = 1
$global:colorText = "Multi(Random)"
$global:backgroundText = "Black"
$global:selectedObject = "Beziers"
$global:imageWidth = 1024
$global:imageHeight = 768

 
I setup 12 RadioButtons to select the geometric object with.
 
GeometricPatterns1
 

# Arcs Object
$radioButtonArcs = New-Object System.Windows.Forms.RadioButton
$radioButtonArcs.Location = "80,30"
$radioButtonArcs.ForeColor = "Indigo"
$radioButtonArcs.Text = "Arcs"
$radioButtonArcs.add_Click({
    $global:selectedObject = "Arcs"
})
$mainForm.Controls.Add($radioButtonArcs)

# Beziers Object
$radioButtonBeziers = New-Object System.Windows.Forms.RadioButton
$radioButtonBeziers.Location = "80,60"
$radioButtonBeziers.ForeColor = "Indigo"
$radioButtonBeziers.Text = "Beziers"
$radioButtonBeziers.add_Click({
    $global:selectedObject = "Beziers"
})
$mainForm.Controls.Add($radioButtonBeziers)

 
I next added two TrackBar Controls with Labels to select the Number of Objects and Pen Size.
 
GeometricPatterns2
 

# Number of Objects TrackBar
$numberTrackBar = New-Object Windows.Forms.TrackBar
$numberTrackBar.Location = "180,280"
$numberTrackBar.Orientation = "Horizontal"
$numberTrackBar.Width = 350
$numberTrackBar.Height = 40
$numberTrackBar.LargeChange = 500
$numberTrackBar.SmallChange = 10
$numberTrackBar.TickFrequency = 500
$numberTrackBar.TickStyle = "TopLeft"
$numberTrackBar.SetRange(1, 5000)
$numberTrackBar.Value = 200
$numberTrackBarValue = 200
$numberTrackBar.add_ValueChanged({
    $numberTrackBarValue = $numberTrackBar.Value
    $numberTrackBarLabel.Text = "Number Objects ($numberTrackBarValue)"
    $global:numberObjects = $numberTrackBarValue
})
$mainForm.Controls.add($numberTrackBar)

# Object Number Label
$numberTrackBarLabel = New-Object System.Windows.Forms.Label 
$numberTrackBarLabel.Location = "10,280"
$numberTrackBarLabel.Size = "160,23"
$numberTrackBarLabel.ForeColor = "MediumBlue"
$numberTrackBarLabel.Text = "Number Objects ($numberTrackBarValue)"
$mainForm.Controls.Add($numberTrackBarLabel)

 
Three ComboBoxes Controls with Labels are added for Object and Background Color and Output Image Size.
 
GeometricPatterns3
 

# Background ComboBox
$backgroundComboBox = New-Object System.Windows.Forms.ComboBox
$backgroundComboBox.Location = "350,420"
$backgroundComboBox.Size = "120,20"
$backgroundComboBox.ForeColor = "Indigo"
$backgroundComboBox.BackColor = "White"
[void]$backgroundComboBox.items.add("Black")
[void]$backgroundComboBox.items.add("White")
[void]$backgroundComboBox.items.add("Random")         
$backgroundComboBox.SelectedIndex = 0
$mainForm.Controls.Add($backgroundComboBox)

# Background ComboBox Label
$backgroundComboBoxLabel = New-Object System.Windows.Forms.Label 
$backgroundComboBoxLabel.Location = "200,420"
$backgroundComboBoxLabel.Size = "100,23"
$backgroundComboBoxLabel.ForeColor = "MediumBlue"
$backgroundComboBoxLabel.Text = "Background Color"
$mainForm.Controls.Add($backgroundComboBoxLabel)

 
To comlete the Form I added a Draw and Exit button. Draw will call the appropriate function to draw the selected object. Exit closes the Form.
 
GeometricPatterns4
 

# Draw Button
$drawButton = New-Object System.Windows.Forms.Button 
$drawButton.Location = "40,420"
$drawButton.Size = "75,23"
$drawButton.ForeColor = "Green"
$drawButton.BackColor = "White"
$drawButton.Text = "Draw"
$drawButton.add_Click({DrawIt})
$mainForm.Controls.Add($drawButton)

# Exit Button
$exitButton = New-Object System.Windows.Forms.Button
$exitButton.Location = "40,460"
$exitButton.Size = "75,23"
$exitButton.ForeColor = "Red"
$exitButton.BackColor = "White"
$exitButton.Text = "Exit"
$exitButton.add_Click({$mainForm.close()})
$mainForm.Controls.Add($exitButton)

 
As an example drawing function I selected Beziers. The Draw Button calls the DrawIt Function where the output image Width and Height variables are set from the ComboBox values. The appropriate drawing function is called from the value selected with the RadioButtons using Invoke-Expression.
 

Function DrawIt {
    $global:imageWidth = $imageComboBox.Text.Substring(0,4)
    $global:imageHeight = $imageComboBox.Text.Substring(5,4)
    Invoke-Expression $global:selectedObject
}

 
A default random color is set. The bitmap image is defined using System.Drawing.Bitmap and that images graphic properties exposed with System.Drawing.Graphics. The images background color is set depending on the ComboBox selection.
 

Function Beziers {
    # Default Random Color
    $red   = (Get-Random -minimum 0 -maximum 255)
    $green = (Get-Random -minimum 0 -maximum 255)
    $blue  = (Get-Random -minimum 0 -maximum 255)
    # Create Image
    $bitmap = New-Object System.Drawing.Bitmap([int]$global:imageWidth, [int]$global:imageHeight)
    $bitmapGraphics = [System.Drawing.Graphics]::FromImage($bitmap)
    # Image Background Color
    If ($backgroundComboBox.Text -eq "Random") {
        $red   = (Get-Random -minimum 0 -maximum 255)
        $green = (Get-Random -minimum 0 -maximum 255)
        $blue  = (Get-Random -minimum 0 -maximum 255)
        $backColor = [System.Drawing.Color]::FromArgb($red, $green, $blue)
        $bitmapGraphics.Clear($backColor)
    } Else {
        $bitmapGraphics.Clear($backgroundComboBox.Text)
    }

 
Next is a loop with an iteration equal to the number of objects. A drawing pen color is set by using the default random color or a new random color for each loop iteration. The pen is defined with using the selected color and width. Next the four x/y coordinates defining the Bezier spline are set using randomly selected points. Finally the Bezier is drawn onto the image with the DrawBezier method.
 

    # Main Loop
    $i = 0
    While ($i -le $global:numberObjects) { $i++
        # Get Random Color if Selected
        If ($colorsComboBox.Text -eq "MultiColored") {
            $red   = (Get-Random -minimum 0 -maximum 255)
            $green = (Get-Random -minimum 0 -maximum 255)
            $blue  = (Get-Random -minimum 0 -maximum 255)
        }
        # Setup Pen
        $penColor = [System.Drawing.Color]::FromArgb($red, $green, $blue)
        $pen = New-Object Drawing.Pen $penColor
        $pen.Width = $global:penWidth
        # Randomize All 4 Points of the Bezier
        $point1X = (Get-Random -minimum 0 -maximum $global:imageWidth)
        $point1Y = (Get-Random -minimum 0 -maximum $global:imageHeight)
        $point2X = (Get-Random -minimum 0 -maximum $global:imageWidth)
        $point2Y = (Get-Random -minimum 0 -maximum $global:imageHeight)
        $point3X = (Get-Random -minimum 0 -maximum $global:imageWidth)
        $point3Y = (Get-Random -minimum 0 -maximum $global:imageHeight)
        $point4X = (Get-Random -minimum 0 -maximum $global:imageWidth)
        $point4Y = (Get-Random -minimum 0 -maximum $global:imageHeight)
        # Draw Bezier Curve
        $bitmapGraphics.DrawBezier($pen, $point1X, $point1Y, $point2X, $point2Y, $point3X, $point3Y, $point4X, $point4Y)
    }

 
When the drawing loop has completed the image is saved to disk and displayed with the default Windows image viewer. The file name is made unique by post pending the date and time. The image files are written to the same folder where the script resides. When all processing has completed the image COM object is disposed of.
 

   
# Save Image to File and Display
    $outFile = $scriptPath + "\"  + "Beziers_" + (Get-Date -UFormat %Y%m%d_%H%M%S) + ".bmp"
    $bitmap.Save($outFile)
    Invoke-Item $outFile

    # Dispose of the image
    $bitmap.Dispose()
}

 
All the drawing functions are quite similar. They all use System.Drawing.Graphics methods like DrawLine, DrawEllipse, DrawCurve, DrawRectangle, DrawArc, DrawPie, etc. They vary by the way the points are defined, how many points there are and how the are positioned. The Connected objects, Lines and Beziers, are obviously not totally random as one end of each object connects to the previously drawn object. Polygons are the same as Connected Lines except they are randomized building the input array instead of by each line end point and since they are drawn in one continuous processing of the array, you only get a single drawing color. Curves are similar to Connected Beziers in the same way. The Starburst and Cornerburst Lines are also not totally random as they have a fixed point as well as a random point.
 
Some images I felt looked best with the all the objects being drawn within the image boundaries, such as both the Beziers and Connected Lines. Other images I thought were best looking with the drawing range of the objects expanding beyond the image boundaries like Arcs, Ellipses, Lines and Rectangles. The partial objects extending within the image edges adds to the randomness and pattern, I think. While with Connected Lines and Beziers, I think the sharp angles and continuousness were important and so I keep the objects within the image. With Arcs and Pie Shapes I put limits on the shapes so that Arcs and Pies are distinctly shaped and not just almost circles.
 
GeometricPatterns
 
Download the complete script here – GeometricPatterns.ps1

There is a new Version 2 of Geometric Patterns Maker here.

Advertisements