├── CHANGELOG.md ├── .gitignore ├── Tests └── LatticeTests │ └── LatticeTests.swift ├── .swiftpm └── xcode │ └── package.xcworkspace │ └── xcshareddata │ └── IDEWorkspaceChecks.plist ├── Package.resolved ├── Package.swift ├── LICENSE.md ├── README.md └── Sources └── Lattice └── Kite.swift /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # CHANGELOG 2 | 3 | ## [0.1.0](https://github.com/zilmarinen/Lattice/releases/tag/0.1.0) (13/09/2025) 4 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | /.build 3 | /Packages 4 | /*.xcodeproj 5 | xcuserdata/ 6 | DerivedData/ 7 | .swiftpm/config/registries.json 8 | .swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata 9 | .netrc 10 | -------------------------------------------------------------------------------- /Tests/LatticeTests/LatticeTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // LatticeTests.swift 3 | // 4 | // Created by Zack Brown on 13/09/2025. 5 | // 6 | 7 | import Euclid 8 | import XCTest 9 | @testable import Deltille 10 | 11 | final class LatticeTests: XCTestCase { 12 | 13 | } 14 | -------------------------------------------------------------------------------- /.swiftpm/xcode/package.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /Package.resolved: -------------------------------------------------------------------------------- 1 | { 2 | "originHash" : "09dd89dedf6ced49eb81146d73a32b5e9604fccb82461142b02c8eae235bb493", 3 | "pins" : [ 4 | { 5 | "identity" : "euclid", 6 | "kind" : "remoteSourceControl", 7 | "location" : "git@github.com:nicklockwood/Euclid.git", 8 | "state" : { 9 | "branch" : "main", 10 | "revision" : "1aeb8a7c36c22d31c74d4bd2c7e4529e3d43c097" 11 | } 12 | } 13 | ], 14 | "version" : 3 15 | } 16 | -------------------------------------------------------------------------------- /Package.swift: -------------------------------------------------------------------------------- 1 | // swift-tools-version: 6.1 2 | // The swift-tools-version declares the minimum version of Swift required to build this package. 3 | 4 | import PackageDescription 5 | 6 | let package = Package( 7 | name: "Lattice", 8 | platforms: [.macOS(.v14), 9 | .iOS(.v17)], 10 | products: [ 11 | .library(name: "Lattice", 12 | targets: ["Lattice"]), 13 | ], 14 | dependencies: [ 15 | .package(path: "../Deltille"), 16 | .package(url: "git@github.com:nicklockwood/Euclid.git", 17 | branch: "main"), 18 | ], 19 | targets: [ 20 | .target(name: "Lattice", 21 | dependencies: ["Deltille", 22 | "Euclid"]), 23 | .testTarget(name: "LatticeTests", 24 | dependencies: ["Deltille", 25 | "Euclid"]), 26 | ] 27 | ) 28 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) Zack Brown 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![Platforms](https://img.shields.io/badge/platforms-iOS%20|%20Mac-lightgray.svg)]() 2 | [![Swift 6.1](https://img.shields.io/badge/swift-6.1-red.svg?style=flat)](https://developer.apple.com/swift) 3 | [![Swift Package Manager](https://img.shields.io/badge/Swift_Package_Manager-compatible-red?style=flat)](https://www.swift.org/documentation/package-manager/) 4 | [![License](https://img.shields.io/badge/license-MIT-green.svg)](https://opensource.org/licenses/MIT) 5 | 6 | - [Introduction](#lattice) 7 | - [Installation](#installation) 8 | - [Implementation](#implementation) 9 | - [Examples](#examples) 10 | - [Credits](#credits) 11 | 12 | # Lattice 13 | 14 | 15 | # Installation 16 | To install using Swift Package Manager, add this to the `dependencies:` section in your Package.swift file: 17 | 18 | ```swift 19 | .package(url: "https://github.com/zilmarinen/Lattice.git", branch: "main"), 20 | ``` 21 | 22 | ## Dependencies 23 | [Deltille](https://github.com/zilmarinen/deltille) is a Swift library for working with hexagonal and triangular grid systems. 24 | [Euclid](https://github.com/nicklockwood/Euclid) is a Swift library for creating and manipulating 3D geometry and is used extensively within this project for mesh generation and vector operations. 25 | 26 | ## License 27 | 28 | This project is licensed under the MIT License - see the [LICENSE.md](LICENSE.md) file for details. 29 | 30 | # Implementation 31 | 32 | 33 | # Examples 34 | [Regolith](https://github.com/zilmarinen/Regolith/) makes use of the concepts introduced by Deltille / Lattice to generate meshes for predefined tessellations of a triangle interior using [Ortho-Tiling](https://www.boristhebrave.com/2023/05/31/ortho-tiles/). 35 | 36 | [Verdure](https://github.com/zilmarinen/Verdure/) implements additional mesh generation on top of Deltille / Lattice to create stylised foliage canopies constrained to a triangular grid. 37 | 38 | # Credits 39 | 40 | The Lattice framework is primarily the work of [Zack Brown](https://github.com/zilmarinen). 41 | -------------------------------------------------------------------------------- /Sources/Lattice/Kite.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Kite.swift 3 | // 4 | // Created by Zack Brown on 13/09/2025. 5 | // 6 | 7 | import Deltille 8 | 9 | extension Triangle { 10 | 11 | public enum Kite: String, 12 | CaseIterable, 13 | Identifiable { 14 | 15 | case delta 16 | case epsilon 17 | case gamma 18 | case kappa 19 | case lambda 20 | case omega 21 | case phi 22 | case psi 23 | case sigma 24 | 25 | public var id: String { rawValue.capitalized } 26 | 27 | public var vertices: [Stencil.Vertex] { 28 | 29 | switch self { 30 | 31 | case .delta: [.v0, .v1, .v2] 32 | case .epsilon: [.v0, .v5, .center, .v7] 33 | case .gamma: [.v0, .v5, .v6, .v9, .v10, .v7] 34 | case .kappa: [.v0, .v5, .v7] 35 | case .lambda: [.v0, .v5, .v9, .v10, .v6, .v7] 36 | case .omega: [.v0, .v5, .v9, .v10, .v7] 37 | case .phi: [.v0, .v5, .v6, .v10, .v7] 38 | case .psi: [.v0, .v5, .v9, .v6, .v7] 39 | case .sigma: [.v0, .v5, .v9, .v6, .v10, .v7] 40 | } 41 | } 42 | } 43 | } 44 | 45 | extension Triangle.Kite { 46 | 47 | public enum Tile: String, 48 | CaseIterable, 49 | Identifiable { 50 | 51 | case descartes 52 | case euclid 53 | case euler 54 | case gauss 55 | case mobius 56 | case pascal 57 | case thales 58 | 59 | public var id: String { rawValue.capitalized } 60 | 61 | public var kites: [Triangle.Kite] { 62 | 63 | switch self { 64 | 65 | case .descartes: [.epsilon, .epsilon, .epsilon] 66 | case .euclid: [.lambda, .delta, .sigma] 67 | case .euler: [.psi, .delta, .omega] 68 | case .gauss: [.lambda, .psi, .psi] 69 | case .mobius: [.delta, .gamma, .sigma] 70 | case .pascal: [.phi, .gamma, .phi] 71 | case .thales: [.delta, .phi, .omega] 72 | } 73 | } 74 | } 75 | } 76 | --------------------------------------------------------------------------------