Skip to content

Commit

Permalink
Add Lattice Example
Browse files Browse the repository at this point in the history
  • Loading branch information
li3zhen1 committed Oct 19, 2023
1 parent 62be92a commit d7cb676
Show file tree
Hide file tree
Showing 2 changed files with 93 additions and 3 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/swift.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,6 @@ jobs:
steps:
- uses: actions/checkout@v3
- name: Build
run: swift build -v - c release
run: swift build -v
- name: Run tests
run: swift test -v -c release
run: swift test -v
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,101 @@
//

import SwiftUI
import NDTree
import ForceSimulation
import CoreGraphics

struct ForceDirectedLatticeView: View {
@State var points: [Vector2d]? = nil

private let sim: Simulation2D<Int>
private let edgeIds: [(Int,Int)]
private let nodeIds: [Int]
private let canvasWidth: CGFloat = 800.0
let width = 30

init() {
self.nodeIds = Array(0..<(width*width))

var edge = [(Int, Int)]()
for i in 0..<width {
for j in 0..<width {
if j != width-1
{
edge.append((width*i+j, width*i+j+1))
}
if i != width-1 {
edge.append((width*i+j, width*(i+1)+j))
}
}
}

// self.edgeIds = Array(0..<width).flatMap { i in
// return Array(0..<width).flatMap{ j in [
// (width*i+j, width*i+j+1),
// (width*i+j, width*(i+1)+1)
// ] }
// }
self.edgeIds = edge
self.sim = Simulation2D(nodeIds: nodeIds)
sim.createLinkForce(self.edgeIds, stiffness: .constant(1), originalLength: .constant(1.5))
sim.createManyBodyForce(strength: -1.5)

}

var body: some View {
Text(/*@START_MENU_TOKEN@*/"Hello, World!"/*@END_MENU_TOKEN@*/)
Canvas { context, sz in
guard let points else { return }
for l in self.edgeIds {
let s = points[l.0]
let t = points[l.1]
// draw a line from s to t
let x1 = CGFloat( canvasWidth/2 + s.x )
let y1 = CGFloat( canvasWidth/2 - s.y )
let x2 = CGFloat( canvasWidth/2 + t.x )
let y2 = CGFloat( canvasWidth/2 - t.y )

context.stroke(Path { path in
path.move(to: CGPoint(x: x1, y: y1))
path.addLine(to: CGPoint(x: x2, y: y2))
}, with: .color(.gray.opacity(0.7)))

}

for i in points.indices {

let _i = Double(i/width) / Double(width)
let _j = Double(i%width) / Double(width)
let x = canvasWidth/2 + points[i].x - 3.5
let y = canvasWidth/2 - points[i].y - 3.5

let rect = CGRect(origin: .init(x: x, y: y), size: CGSize(width: 7.0, height: 7.0))

context.fill(Path(ellipseIn: rect), with: .color(red: 1, green: _i, blue: _j))
context.stroke(Path(ellipseIn: rect), with: .color(red: 0.1568, green: 0.1568, blue:0.1569), style: StrokeStyle(lineWidth: 1.5))

}
}
.onAppear {
self.points = sim.nodePositions
}
.frame(width: canvasWidth, height: canvasWidth)
.navigationTitle("Force Directed Lattice Example")
.toolbar {
Button(action: {
Timer.scheduledTimer(withTimeInterval: 1/60, repeats: true) { t in
self.sim.tick()
self.points = sim.nodePositions
}
}, label: {
HStack {
Image(systemName: "play.fill")
Text("Run")
}.padding()
})
}
}

}

#Preview {
Expand Down

0 comments on commit d7cb676

Please sign in to comment.