Lindenmayer2DSwift is a swift framework that generates trees and other fractal structures using L-Systems.
The Lindenmayer2DSwift framework can be installed using the Swift Package Manager. In Xcode: File > Swift Packages > Add Package Dependency..
with URL: https://github.com/TateLiang/Lindenmayer2DSwift.git
Or alternatively:
.package(url: "https://github.com/TateLiang/FortuneSwift.git", from: "1.0.3")
to your Package.swift
file's dependencies
.$ swift package update
.import Lindenmayer2DSwift
Turtle
objectvar turtle = Turtle()
LSystem
objectvar lsystem = LSystem("X", [
"F": "FF",
"X": "F-[[X]+X]+F[+FX]-X"
])
Alternatively, use one of the preset trees of type Tree
:
var tree = Library.tree3
5. Setup the turtle with custom values:
private func setupTurtle() {
turtle.initialLength = 100
turtle.initialPos = Turtle.Coordinate(canvas.bounds.midX, canvas.bounds.minY)
turtle.initialAngle = .pi/2
turtle.angle = .pi/6
turtle.lengthFactor = 1.3
}
Alternatively, use the preset tree's values:
private func setupTurtle() {
turtle.initialLength = 100
turtle.initialPos = Turtle.Coordinate(canvas.bounds.midX, canvas.bounds.minY)
turtle.angle = tree.angle
turtle.lengthFactor = tree.lengthFactor
}
var tree = Library.tree3
var turtle = Turtle(initialLength: 100)
private func setupTurtle() {
turtle.initialPos = Turtle.Coordinate(canvas.bounds.midX, canvas.bounds.minY)
turtle.angle = tree.angle
turtle.lengthFactor = tree.lengthFactor
}
private func nextGeneration() {
let string = tree.lsystem.advanceGeneration()
turtle.run(string)
turtle.initialLength *= 0.66
let edges = turtle.edgeList.map { ($0.cgPoint, $1.cgPoint) }
canvas.clear()
canvas.drawEdges(at: edges, type: .thick)
}
Lindenmayer2DSwift uses two main objects, LSystem
and Turtle
.
LSystem
object is defined by the axiom and rules:LSystem("X", [
"F": "FF",
"X": "F-[[X]+X]+F[+FX]-X"
])
The generation can be advanced using either:
@discardableResult public mutating func advanceGeneration() -> String
public mutating func advanceGeneration(by generations: Int)
The following properties are provided for accessing the string:
public var strings: [String]
public var currentString: String { strings.last ?? "" }
public var generations: Int { strings.count }
2. The Turtle
object can be run by using:
public mutating func run(_ string: String)
The following properties are provided for accessing the resulting graph:
public var root: Coordinate?
public var graph: [Coordinate: [Coordinate]] = [:]
public var edgeList: [(Coordinate, Coordinate)]
Coloring the edges differently depending on depth:
private func getEdgesByDepth(cutoff: Int) -> (near: [(CGPoint, CGPoint)], far: [(CGPoint, CGPoint)])? {
guard let root = turtle.root else { return nil }
let graph = turtle.graph
var nearEdges: [(CGPoint, CGPoint)] = []
var farEdges: [(CGPoint, CGPoint)] = []
func dfs(node: Turtle.Coordinate, depth: Int) {
if let nextNodes = graph[node] {
if depth < cutoff {
nextNodes.forEach {
nearEdges.append((node.cgPoint, $0.cgPoint))
dfs(node: $0, depth: depth+1)
}
}else {
nextNodes.forEach {
farEdges.append((node.cgPoint, $0.cgPoint))
dfs(node: $0, depth: depth+1)
}
}
}
}
dfs(node: root, depth: 0)
return (near: nearEdges, far: farEdges)
}
link |
Stars: 3 |
Last commit: 3 years ago |
Swiftpack is being maintained by Petr Pavlik | @ptrpavlik | @swiftpackco | API | Analytics