Skip to content

Commit

Permalink
[docs] adds newline to break out abstract for symbol from the discuss…
Browse files Browse the repository at this point in the history
…ion to simplify high level overview pages
  • Loading branch information
heckj committed Oct 30, 2023
1 parent e8fe811 commit 5e9fddb
Show file tree
Hide file tree
Showing 27 changed files with 160 additions and 52 deletions.
1 change: 1 addition & 0 deletions Sources/ForceSimulation/ForceLike.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@


/// A protocol that represents a force.
///
/// A force takes a simulation state and modifies its node positions and velocities.
public protocol ForceLike {

Expand Down
5 changes: 5 additions & 0 deletions Sources/ForceSimulation/NDTree/NDBox.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
//

/// A box in N-dimensional space.
///
/// - Note: `p0` is the minimum point of the box, `p1` is the maximum point of the box.
public struct NDBox<V> where V: VectorLike {
/// the minimum anchor of the box
Expand All @@ -15,6 +16,7 @@ public struct NDBox<V> where V: VectorLike {
public var p1: V

/// Create a box with 2 anchors.
///
/// - Parameters:
/// - p0: anchor
/// - p1: another anchor in the diagonal position of `p0`
Expand All @@ -39,6 +41,7 @@ public struct NDBox<V> where V: VectorLike {
}

/// Create a box with 2 anchors.
///
/// - Parameters:
/// - pMin: minimum anchor of the box
/// - pMax: maximum anchor of the box
Expand Down Expand Up @@ -111,6 +114,7 @@ extension NDBox {
extension NDBox {

/// Get the small box that contains a list points and guarantees the box's size is at least 1x..x1.
///
/// - Parameter points: The points to be covered.
/// - Returns: The box that contains all the points.
@inlinable public static func cover(of points: [V]) -> Self {
Expand Down Expand Up @@ -141,6 +145,7 @@ extension NDBox {
}

/// Get the small box that contains a list points and guarantees the box's size is at least 1x..x1.
///
/// Please note that KeyPath is slow.
///
/// - Parameter
Expand Down
37 changes: 27 additions & 10 deletions Sources/ForceSimulation/NDTree/NDTree.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,17 @@
// Created by li3zhen1 on 10/14/23.
//

/// The data structure carried by a node of NDTree
/// The data structure carried by a node of NDTree.
///
/// It receives notifications when a node is added or removed on a node, regardless of whether the node is internal or leaf.
/// It is designed to calculate properties like a box's center of mass.
public protocol NDTreeDelegate {
associatedtype NodeID: Hashable
associatedtype V: VectorLike

/// Called when a node is added on a node, regardless of whether the node is internal or leaf.
/// If you add `n` points to the root, this method will be called `n` times in the root delegate,
///
/// If you add `n` points to the root, this method will be called `n` times in the root delegate,
/// although it is probably not containing points now.
/// - Parameters:
/// - node: The nodeID of the node that is added.
Expand All @@ -23,11 +25,13 @@ public protocol NDTreeDelegate {
/// Called when a node is removed on a node, regardless of whether the node is internal or leaf.
mutating func didRemoveNode(_ node: NodeID, at position: V)

/// Copy object. This method is called when the root box is not large enough to cover the new nodes.
/// The method
/// Copy object.
///
/// This method is called when the root box is not large enough to cover the new nodes.
func copy() -> Self

/// Create new object with properties set to initial value as if the box is empty.
///
/// However, you can still carry something like a closure to get information from outside.
/// This method is called when a leaf box is splited due to the insertion of a new node in this box.
func spawn() -> Self
Expand Down Expand Up @@ -155,6 +159,7 @@ public final class NDTree<V, D> where V: VectorLike, D: NDTreeDelegate, D.V == V
}

/// Expand the current node multiple times by calling `expand(towards:)`, until the point is covered.
///
/// - Parameter point: The point to be covered.
private func cover(_ point: V) {
if box.contains(point) { return }
Expand All @@ -165,8 +170,9 @@ public final class NDTree<V, D> where V: VectorLike, D: NDTreeDelegate, D.V == V
} while !box.contains(point)
}

/// Expand the current node towards a direction. The expansion
/// will double the size on each dimension. Then the data in delegate will be copied to the new children.
/// Expand the current node towards a direction.
///
/// The expansion will double the size on each dimension. Then the data in delegate will be copied to the new children.
/// - Parameter direction: An Integer between 0 and `directionCount - 1`, where `directionCount` equals to 2^(dimension of the vector).
private func expand(towards direction: Direction) {
let nailedDirection = (Self.directionCount - 1) - direction
Expand Down Expand Up @@ -195,6 +201,7 @@ public final class NDTree<V, D> where V: VectorLike, D: NDTreeDelegate, D.V == V
}

/// The children count of a node in NDTree.
///
/// Should be equal to the 2^(dimension of the vector).
/// For example, a 2D vector should have 4 children, a 3D vector should have 8 children.
/// This property is a getter property but it is probably be inlined.
Expand Down Expand Up @@ -232,6 +239,7 @@ public final class NDTree<V, D> where V: VectorLike, D: NDTreeDelegate, D.V == V
}

/// Copy object while holding the same reference to children.
///
/// Consider this function something you would do when working with linked list.
private func shallowCopy() -> NDTree<V, D> {
let copy = NDTree(
Expand All @@ -246,6 +254,7 @@ public final class NDTree<V, D> where V: VectorLike, D: NDTreeDelegate, D.V == V
}

/// Get the index of the child that contains the point.
///
/// **Complexity**: `O(n*(2^n))`, where `n` is the dimension of the vector.
private func getIndexInChildren(_ point: V, relativeTo originalPoint: V) -> Int {
var index = 0
Expand All @@ -262,7 +271,8 @@ public final class NDTree<V, D> where V: VectorLike, D: NDTreeDelegate, D.V == V
extension NDTree where D.NodeID == Int {

/// Initialize a NDTree with a list of points and a key path to the vector.
/// - Parameters:
///
/// - Parameters:
/// - points: A list of points. The points are only used to calculate the covering box. You should still call `add` to add the points to the tree.
/// - clusterDistance: If 2 points are close enough, they will be clustered into the same leaf node.
/// - buildRootDelegate: A closure that tells the tree how to initialize the data you want to store in the root.
Expand All @@ -282,7 +292,8 @@ extension NDTree where D.NodeID == Int {
}

/// Initialize a NDTree with a list of points and a key path to the vector.
/// - Parameters:
///
/// - Parameters:
/// - points: A list of points. The points are only used to calculate the covering box. You should still call `add` to add the points to the tree.
/// - keyPath: A key path to the vector in the element of the list.
/// - clusterDistance: If 2 points are close enough, they will be clustered into the same leaf node.
Expand All @@ -309,10 +320,14 @@ extension NDTree {
/// The bounding box of the current node
@inlinable public var extent: Box { box }

/// Returns true is the current tree node is leaf. Does not guarantee that the tree node has point in it.
/// Returns true is the current tree node is leaf.
///
/// Does not guarantee that the tree node has point in it.
@inlinable public var isLeaf: Bool { children == nil }

/// Returns true is the current tree node is internal. Internal tree node are always empty and do not contain any points.
/// Returns true is the current tree node is internal.
///
/// Internal tree node are always empty and do not contain any points.
@inlinable public var isInternalNode: Bool { children != nil }

/// Returns true is the current tree node is leaf and has point in it.
Expand All @@ -323,6 +338,7 @@ extension NDTree {


/// Visit the tree in pre-order.
///
/// - Parameter shouldVisitChildren: a closure that returns a boolean value indicating whether should continue to visit children.
@inlinable public func visit(shouldVisitChildren: (NDTree<V,D>) -> Bool) {
if shouldVisitChildren(self), let children {
Expand All @@ -334,6 +350,7 @@ extension NDTree {
}

/// Visit the tree in post-order.
///
/// - Parameter action: a closure that takes a tree as its argument.
@inlinable public func visitPostOrdered(
_ action: (NDTree<V, D>) -> ()
Expand Down
39 changes: 27 additions & 12 deletions Sources/ForceSimulation/NDTree/Octree.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,17 @@
#if canImport(simd)
import simd

/// The data structure carried by a node of NDTree
/// The data structure carried by a node of NDTree.
///
/// It receives notifications when a node is added or removed on a node, regardless of whether the node is internal or leaf.
/// It is designed to calculate properties like a box's center of mass.
public protocol OctreeDelegate {
associatedtype NodeID: Hashable
typealias V = simd_float3

/// Called when a node is added on a node, regardless of whether the node is internal or leaf.
/// If you add `n` points to the root, this method will be called `n` times in the root delegate,
///
/// If you add `n` points to the root, this method will be called `n` times in the root delegate,
/// although it is probably not containing points now.
/// - Parameters:
/// - node: The nodeID of the node that is added.
Expand All @@ -26,17 +28,20 @@ public protocol OctreeDelegate {
/// Called when a node is removed on a node, regardless of whether the node is internal or leaf.
mutating func didRemoveNode(_ node: NodeID, at position: V)

/// Copy object. This method is called when the root box is not large enough to cover the new nodes.
/// The method
/// Copy object.
///
/// This method is called when the root box is not large enough to cover the new nodes.
func copy() -> Self

/// Create new object with properties set to initial value as if the box is empty.
///
/// However, you can still carry something like a closure to get information from outside.
/// This method is called when a leaf box is splited due to the insertion of a new node in this box.
func spawn() -> Self
}

/// A node in NDTree
/// A node in NDTree.
///
/// - Note: `NDTree` is a generic type that can be used in any dimension.
/// `NDTree` is a reference type.
public final class Octree<D> where D: OctreeDelegate {
Expand Down Expand Up @@ -170,8 +175,9 @@ public final class Octree<D> where D: OctreeDelegate {
} while !box.contains(point)
}

/// Expand the current node towards a direction. The expansion
/// will double the size on each dimension. Then the data in delegate will be copied to the new children.
/// Expand the current node towards a direction.
///
/// The expansion will double the size on each dimension. Then the data in delegate will be copied to the new children.
/// - Parameter direction: An Integer between 0 and `directionCount - 1`, where `directionCount` equals to 2^(dimension of the vector).
private func expand(towards direction: Direction) {
let nailedDirection = (Self.directionCount - 1) - direction
Expand Down Expand Up @@ -200,6 +206,7 @@ public final class Octree<D> where D: OctreeDelegate {
}

/// The children count of a node in NDTree.
///
/// Should be equal to the 2^(dimension of the vector).
/// For example, a 2D vector should have 4 children, a 3D vector should have 8 children.
/// This property is a getter property but it is probably be inlined.
Expand Down Expand Up @@ -237,6 +244,7 @@ public final class Octree<D> where D: OctreeDelegate {
}

/// Copy object while holding the same reference to children.
///
/// Consider this function something you would do when working with linked list.
private func shallowCopy() -> Self {
let copy = Self(
Expand All @@ -251,6 +259,7 @@ public final class Octree<D> where D: OctreeDelegate {
}

/// Get the index of the child that contains the point.
///
/// **Complexity**: `O(n*(2^n))`, where `n` is the dimension of the vector.
private func getIndexInChildren(_ point: V, relativeTo originalPoint: V) -> Int {
// var index = 0
Expand All @@ -271,7 +280,8 @@ public final class Octree<D> where D: OctreeDelegate {
extension Octree where D.NodeID == Int {

/// Initialize a NDTree with a list of points and a key path to the vector.
/// - Parameters:
///
/// - Parameters:
/// - points: A list of points. The points are only used to calculate the covering box. You should still call `add` to add the points to the tree.
/// - clusterDistance: If 2 points are close enough, they will be clustered into the same leaf node.
/// - buildRootDelegate: A closure that tells the tree how to initialize the data you want to store in the root.
Expand All @@ -291,7 +301,8 @@ extension Octree where D.NodeID == Int {
}

/// Initialize a NDTree with a list of points and a key path to the vector.
/// - Parameters:
///
/// - Parameters:
/// - points: A list of points. The points are only used to calculate the covering box. You should still call `add` to add the points to the tree.
/// - keyPath: A key path to the vector in the element of the list.
/// - clusterDistance: If 2 points are close enough, they will be clustered into the same leaf node.
Expand All @@ -318,10 +329,14 @@ extension Octree {
/// The bounding box of the current node
@inlinable public var extent: Box { box }

/// Returns true is the current tree node is leaf. Does not guarantee that the tree node has point in it.
/// Returns true is the current tree node is leaf.
///
/// Does not guarantee that the tree node has point in it.
@inlinable public var isLeaf: Bool { children == nil }

/// Returns true is the current tree node is internal. Internal tree node are always empty and do not contain any points.
/// Returns true is the current tree node is internal.
///
/// Internal tree node are always empty and do not contain any points.
@inlinable public var isInternalNode: Bool { children != nil }

/// Returns true is the current tree node is leaf and has point in it.
Expand All @@ -341,4 +356,4 @@ extension Octree {
}
}

#endif
#endif
Loading

0 comments on commit 5e9fddb

Please sign in to comment.