Sander van de Bor
Published © LGPL

Creating Phyllotaxis Patterns with a Plugin in Kicad 8

KiCad 8: Generate mesmerizing PCB spirals in seconds with my Python plugin.

IntermediateProtip1 hour240
Creating Phyllotaxis Patterns with a Plugin in Kicad 8

Things used in this project

Software apps and online services

KiCad
KiCad

Story

Read more

Code

Phyllotaxis Plugin

Python
Phyllotactic patterns to generate Fibonacci-inspired designs.
import wx
import pcbnew
import math

class GreetingPlugin(pcbnew.ActionPlugin):
    def defaults(self):
        self.name = "Phyllotaxis Plugin"
        self.category = "General"
        self.description = "Phyllotactic patterns to generate Fibonacci-inspired designs."

    def Run(self):
        # Create a custom dialog
        app = wx.App(False)
        dialog = wx.Dialog(None, title="Phy", size=(600, 500))

        # Create a grid sizer with 2 columns
        sizer = wx.GridSizer(rows=0, cols=2, hgap=10, vgap=15)

        self.t_label = wx.StaticText(dialog, label="Enter number of LEDs:")
        self.t_input = wx.TextCtrl(dialog, value="104")
        sizer.Add(self.t_label, 0, wx.ALIGN_RIGHT | wx.ALIGN_CENTER_VERTICAL)
        sizer.Add(self.t_input, 1, wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL | wx.RIGHT, 10)
        
        self.angle_label = wx.StaticText(dialog, label="Enter angle (137.508):")
        self.angle_input = wx.TextCtrl(dialog, value="137.508")
        sizer.Add(self.angle_label, 0, wx.ALIGN_RIGHT | wx.ALIGN_CENTER_VERTICAL)
        sizer.Add(self.angle_input, 1, wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL | wx.RIGHT, 10)
        
        self.cspread_label = wx.StaticText(dialog, label="Enter cspread:")
        self.cspread_input = wx.TextCtrl(dialog, value="2")
        sizer.Add(self.cspread_label, 0, wx.ALIGN_RIGHT | wx.ALIGN_CENTER_VERTICAL)
        sizer.Add(self.cspread_input, 1, wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL | wx.RIGHT, 10)
        
        self.rot_label = wx.StaticText(dialog, label="Enter Led Rotation:")
        self.rot_input = wx.TextCtrl(dialog, value="90")
        sizer.Add(self.rot_label, 0, wx.ALIGN_RIGHT | wx.ALIGN_CENTER_VERTICAL)
        sizer.Add(self.rot_input, 1, wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL | wx.RIGHT, 10)
        
        self.angvalue_label = wx.StaticText(dialog, label="Enter angle offset (negative):")
        self.angvalue_input = wx.TextCtrl(dialog, value="-1")
        sizer.Add(self.angvalue_label, 0, wx.ALIGN_RIGHT | wx.ALIGN_CENTER_VERTICAL)
        sizer.Add(self.angvalue_input, 1, wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL | wx.RIGHT, 10)

        # Add buttons
        ok_button = wx.Button(dialog, label="Run Script")
        close_button = wx.Button(dialog, label="Close Window")

        def on_close_button_click(event):
            dialog.Close()

        ok_button.Bind(wx.EVT_BUTTON, self.on_ok_button_click)
        close_button.Bind(wx.EVT_BUTTON, on_close_button_click)

        # Add buttons to the sizer
        sizer.Add(close_button, 0, wx.ALIGN_CENTER | wx.ALL | wx.EXPAND, 10)
        sizer.Add(ok_button, 0, wx.ALIGN_CENTER | wx.ALL | wx.EXPAND, 10)

        dialog.SetSizer(sizer)

        # Show the dialog
        dialog.ShowModal()
        dialog.Destroy()
        app.MainLoop()
        
    def on_ok_button_click(self, event):
        t = int(self.t_input.GetValue())
        angle = float(self.angle_input.GetValue())
        cspread = float(self.cspread_input.GetValue())
        rot = int(self.rot_input.GetValue())
        angvalue = float(self.angvalue_input.GetValue())
        PhyllotacticPattern(t, angle, cspread, rot, angvalue)

# Register the plugin
GreetingPlugin().register()

def PhyllotacticPattern(t, angle = 137.508, cspread = 4, rot = 90, angvalue = -1):
    phi = angle * ( math.pi / 180.0 )
    xcenter = 100.0
    ycenter = 100.0
    pcb = pcbnew.GetBoard()
    for n in range (0,t):
        r = cspread * math.sqrt(n)
        theta = (n) * phi
        
        part = pcb.FindFootprintByReference("D" + str(n+1))
        
        x = r * math.cos(theta) + xcenter 
        y = r * math.sin(theta) + ycenter
        d = (n*angvalue*angle)+rot

        part.SetPosition(pcbnew.VECTOR2I_MM(x, y))
        part.SetOrientationDegrees(d)
    pcbnew.Refresh()

Credits

Sander van de Bor
1 project • 4 followers
Creator of unique jewelry pieces using microcontrollers and supercapacitors, Exploring the intersection of technology and art.
Contact

Comments

Please log in or sign up to comment.