From fdcf62db74da721e84145ce7206d0eaa9b75a6a8 Mon Sep 17 00:00:00 2001 From: Eryn Wells Date: Sun, 6 Aug 2017 08:25:13 -0700 Subject: [PATCH] [MetaballsKit] Just replace balls when size changes --- MetaballsKit/Metaballs.swift | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/MetaballsKit/Metaballs.swift b/MetaballsKit/Metaballs.swift index a4e201d..84b15a9 100644 --- a/MetaballsKit/Metaballs.swift +++ b/MetaballsKit/Metaballs.swift @@ -43,7 +43,16 @@ public class Field { let numberOfBallsBeforeFilter = balls.count // Remove balls that fall outside the new bounds. - balls = balls.filter { bounds.contains($0.bounds) } +// balls = balls.filter { bounds.contains($0.bounds) } + + // Scale balls to new position and size. + let scale = Float(size.width / oldValue.width) + balls = balls.map { + let r = $0.radius * scale + let p = randomPoint(forBallWithRadius: r) + let v = Vector(dx: $0.velocity.dx * scale, dy: $0.velocity.dy * scale) + return Ball(radius: r, position: p, velocity: v) + } // Update Metal state as needed. populateParametersBuffer() @@ -91,11 +100,7 @@ public class Field { } public func add(ballWithRadius radius: Float) { - let insetBounds = bounds.insetBy(dx: CGFloat(radius), dy: CGFloat(radius)) - - let x = Float(UInt32(insetBounds.minX) + arc4random_uniform(UInt32(insetBounds.width))) - let y = Float(UInt32(insetBounds.minY) + arc4random_uniform(UInt32(insetBounds.height))) - let position = Point(x: x, y: y) + let position = randomPoint(forBallWithRadius: radius) let dx = Float(5 - Int(arc4random_uniform(10))) let dy = Float(5 - Int(arc4random_uniform(10))) @@ -114,6 +119,14 @@ public class Field { balls.removeAll(keepingCapacity: true) } + private func randomPoint(forBallWithRadius radius: Float) -> Point { + let insetBounds = bounds.insetBy(dx: CGFloat(radius), dy: CGFloat(radius)) + let x = Float(UInt32(insetBounds.minX) + arc4random_uniform(UInt32(insetBounds.width))) + let y = Float(UInt32(insetBounds.minY) + arc4random_uniform(UInt32(insetBounds.height))) + let position = Point(x: x, y: y) + return position + } + // MARK: - Metal Configuration private var device: MTLDevice?