Source code for vSCAD.Tree.tree

import numpy as np

[docs] class Branch(): def __init__(self, start_point, end_point, start_diameter, end_diameter, num_points): ''' Initializes a Branch object. Parameters ---------- start_point : np.ndarray The starting point of the branch. end_point : np.ndarray The ending point of the branch. start_diameter : float The diameter at the starting point of the branch. end_diameter : float The diameter at the ending point of the branch. num_points : int The number of points to generate in the branch. ''' self.start_point = start_point self.end_point = end_point # Generate a set of points and diameters for each branch p = int(num_points) if p < 2: p = 2 self.points = np.array(np.linspace(start_point, end_point, p)) self.diameters = np.linspace(start_diameter, end_diameter, p)
[docs] class BinaryTree(): def __init__(self, start_point, length, angle, depth, diameter = 2, num_points_base = 100): ''' Initializes a BinaryTree object. Parameters ---------- start_point : np.ndarray The starting point of the tree. length : float The length of the main branch. angle : float The bifurcation angle in radians. depth : int The depth of the tree. diameter : float, optional The diameter of the main branch, defaults to 2. num_points_base : int, optional The number of points to generate in the base branch, defaults to 100. ''' self.start_point = start_point self.length = length self.bifurcation_angle = angle self.depth = depth self.num_points_base = num_points_base self.diameter = diameter self.murray_exponent = 3.0 self.angle = np.pi / 2 self.branch_length_reduction = 0.7
[docs] def set_murray_exponent(self, exponent): ''' Sets the Murray's law exponent for the tree generation. Parameters ---------- exponent : float The exponent value to use in Murray's law. ''' self.murray_exponent = exponent
[docs] def set_branch_length_reduction(self, reduction): ''' Sets the branch length reduction factor for the tree generation. Parameters ---------- reduction : float The reduction factor for branch length. ''' self.branch_length_reduction = reduction
[docs] def draw_tree(self): ''' Begins recursive tree generation. Returns ------- list of Branch A list of Branch objects representing the generated tree. ''' self.branches = self.generate_tree(self.start_point, self.length, self.diameter, self.num_points_base, self.angle, self.depth) return self.branches
[docs] def generate_tree(self, start_point, length, diameter, num_points, angle, depth): ''' Generates a binary tree structure recursively. Parameters ---------- start_point : np.ndarray The starting point of the current branch as a 3D coordinate. length : float The length of the current branch. diameter : float The diameter of the current branch. num_points : int The number of points to generate along the branch. angle : float The angle (in radians) of the current branch relative to the parent. depth : int The remaining depth of recursion (number of branching levels). Returns ------- list of Branch A list of Branch objects representing the generated tree structure. ''' if depth == 0: return [] end_point = start_point + length * np.array([np.cos(angle), np.sin(angle), 0]) start_diameter = self.calculate_diameter(diameter) end_diameter = self.calculate_diameter(start_diameter) branch = Branch(start_point=start_point, end_point=end_point, start_diameter=start_diameter, end_diameter=end_diameter, num_points=num_points) left_branch = self.generate_tree(end_point, length * 0.7, self.calculate_diameter(diameter), int(num_points * self.branch_length_reduction), angle + self.bifurcation_angle, depth - 1) right_branch = self.generate_tree(end_point, length * 0.7, self.calculate_diameter(diameter), int(num_points * self.branch_length_reduction,), angle - self.bifurcation_angle, depth - 1) return [branch] + left_branch + right_branch
[docs] def calculate_diameter(self, diameter): ''' Calculates the diameter of the branch based on Murray's law. Parameters ---------- diameter : float The diameter of the parent branch. Returns ------- float The calculated diameter for the child branch. ''' return diameter * (2 ** (-1 / self.murray_exponent))
[docs] class NodalTree(): def __init__(self, connectivity, points, diameters, num_points): ''' Initializes a NodalTree object. Parameters ---------- connectivity : array_like Connectivity matrix. The row index of the matrix represents the branch number. The first column is the starting point of the branch, and the second column is the ending point of the branch. points : array_like List of points in 3D space. diameters : array_like List of diameters. num_points : int Number of points to generate per branch. ''' self.connectivity = np.array(connectivity) self.points = np.array(points) self.diameters = np.array(diameters) self.num_points = np.array(num_points)
[docs] def draw_tree(self): ''' Generates branch objects for each branch (row) in the connectivity matrix. Returns ------- list of Branch A list of Branch objects. ''' self.branches = [] for row in self.connectivity: start_point = self.points[row[0]] end_point = self.points[row[1]] start_diameter = self.diameters[row[0]] end_diameter = self.diameters[row[1]] self.branches.append(Branch(start_point=start_point, end_point=end_point, start_diameter=start_diameter, end_diameter=end_diameter, num_points=self.num_points)) return self.branches