modules¶
geometor.phyllotaxis¶
Symbolic modeling, 2D planar analysis, and 3D recursive meristem path propagation.
Everything centers around Phyllotaxis, MeristemNode, and MeristemConfig.
Submodules¶
Attributes¶
Classes¶
Mixin for Phyllotaxis class containing divergence angle functionality. |
|
Mixin for Phyllotaxis class containing geometor.model.Model construction helpers. |
|
Configuration for 3D Node-as-Path and recursive meristem propagation. |
|
A 3D phyllotaxic node that grows as a path from its origin and may act as a meristem. |
|
Mixin for Phyllotaxis class containing 3D path and meristem propagation methods. |
|
Main class for symbolic and parametric 2D/3D phyllotaxis modeling. |
|
Mixin for Phyllotaxis class containing 2D planar growth and parastichy methods. |
Functions¶
|
Return the $n$-th Fibonacci number ($F_0 = 0, F_1 = 1$). |
|
Return consecutive Fibonacci rational approximations $(F_k, F_{k+2}, text{degrees})$. |
|
Return a catalog of short/long golden sweeps, $phi^{-k}$ powers, and rational sweep factors. |
|
Return the exact symbolic Lucas divergence angle $2pi / (3 + 1/phi) approx 99.5^circ$. |
|
Return the exact symbolic short golden sweep $2pi(1 - 1/phi) = 2pi / phi^2$. |
|
Return a rational factor $(text{numerator}/text{denominator})$ of the short or long golden sweep. |
|
Return the exact symbolic long golden sweep $2pi / phi approx 222.492236^circ$. |
|
Return the $k$-th golden section sweep $2pi / phi^k$ ($k=1$: Long, $k=2$: Short). |
|
Return the exact symbolic short golden sweep $2pi / phi^2 approx 137.507764^circ$. |
|
Return a rational divergence angle $2pi(1 - n/m)$ from two integers. |
|
Construct a geometor.model.Model containing phyllotaxic node points and dot circles. |
|
Evaluate a node's 3D trajectory $gamma(s)$ for $s in [0, text{age}]$ from origin. |
|
Propagate a 3D phyllotaxic meristem system for steps plastochrons. |
|
Count parastichy curves in each closest-neighbor rank and radial zone until they bend. |
|
Classify a node's ontogenetic organ type in the meristem's production life cycle. |
|
For each point in test_points, find the num_nearest closest subsequent points. |
|
Group node indices into parastichy spiral chains for each modulo family $m in text{families}$. |
|
Compute Euclidean distances from pt to each point in other_pts. |
|
Generate a single planar growth frame with num_nodes symbolic points. |
|
Grow planar frames from $0$ up to steps - 1 nodes. |
|
Compute 2D apical meristem coordinates with radial acceleration, node growth, and life-cycle phases. |
Package Contents¶
- geometor.phyllotaxis.__version__ = '0.2.2'¶
- class geometor.phyllotaxis.AnglesMixin¶
Mixin for Phyllotaxis class containing divergence angle functionality.
- get_sweep_phi() sympy.Expr¶
- get_sweep_phi_short() sympy.Expr¶
- get_sweep_phi_long() sympy.Expr¶
- get_sweep_phi_factor(numerator: int = 1, denominator: int = 1, *, long_sweep: bool = False) sympy.Expr¶
- get_sweep_lucas() sympy.Expr¶
- geometor.phyllotaxis.PHI: sympy.Expr¶
- geometor.phyllotaxis.fibonacci(n: int) int¶
Return the $n$-th Fibonacci number ($F_0 = 0, F_1 = 1$).
- geometor.phyllotaxis.fibonacci_convergents(count: int = 8) list[tuple[int, int, float]]¶
Return consecutive Fibonacci rational approximations $(F_k, F_{k+2}, text{degrees})$.
- Parameters:
count – Number of convergent pairs to generate starting from $(1, 2)$.
- Returns:
List of tuples (numerator, denominator, angle_degrees).
- geometor.phyllotaxis.golden_sweep_presets() list[dict[str, str | float]]¶
Return a catalog of short/long golden sweeps, $phi^{-k}$ powers, and rational sweep factors.
- geometor.phyllotaxis.sweep_lucas() sympy.Expr¶
Return the exact symbolic Lucas divergence angle $2pi / (3 + 1/phi) approx 99.5^circ$.
- geometor.phyllotaxis.sweep_phi() sympy.Expr¶
Return the exact symbolic short golden sweep $2pi(1 - 1/phi) = 2pi / phi^2$.
- geometor.phyllotaxis.sweep_phi_factor(numerator: int = 1, denominator: int = 1, *, long_sweep: bool = False) sympy.Expr¶
Return a rational factor $(text{numerator}/text{denominator})$ of the short or long golden sweep.
- geometor.phyllotaxis.sweep_phi_long() sympy.Expr¶
Return the exact symbolic long golden sweep $2pi / phi approx 222.492236^circ$.
- geometor.phyllotaxis.sweep_phi_power(k: int = 2) sympy.Expr¶
Return the $k$-th golden section sweep $2pi / phi^k$ ($k=1$: Long, $k=2$: Short).
- geometor.phyllotaxis.sweep_phi_short() sympy.Expr¶
Return the exact symbolic short golden sweep $2pi / phi^2 approx 137.507764^circ$.
- geometor.phyllotaxis.sweep_rational(n: int, m: int) sympy.Expr¶
Return a rational divergence angle $2pi(1 - n/m)$ from two integers.
- class geometor.phyllotaxis.ModelBuilderMixin¶
Mixin for Phyllotaxis class containing geometor.model.Model construction helpers.
- geometor.phyllotaxis.build_rings_model(num_rings: int = 8, sweep: sympy.Expr | float | None = None, name: str = 'phyllotaxis_rings') geometor.model.Model¶
Construct a geometor.model.Model containing phyllotaxic node points and dot circles.
- Parameters:
num_rings – Number of primordia rings to construct.
sweep – Symbolic or numeric divergence angle (defaults to sweep_phi()).
name – Name of the created Model.
- Returns:
Populated geometor.model.Model instance.
- class geometor.phyllotaxis.MeristemConfig¶
Configuration for 3D Node-as-Path and recursive meristem propagation.
- class geometor.phyllotaxis.MeristemNode¶
A 3D phyllotaxic node that grows as a path from its origin and may act as a meristem.
- class geometor.phyllotaxis.Propagation3DMixin¶
Mixin for Phyllotaxis class containing 3D path and meristem propagation methods.
- propagate_3d(steps: int, config: MeristemConfig | None = None) list[MeristemNode]¶
- geometor.phyllotaxis.compute_node_path(origin: Vec3, parent_tangent: Vec3, radial_dir: Vec3, binormal_dir: Vec3, age: int, generation: int, config: MeristemConfig) tuple[list[Vec3], Vec3, Vec3, Vec3]¶
Evaluate a node’s 3D trajectory $gamma(s)$ for $s in [0, text{age}]$ from origin.
At $s = 0$, $gamma(0) = text{origin}$. As $s to text{age}$, the path advances outward along radial_dir and lifts/curves along parent_tangent with optional helical twist around binormal_dir.
- Parameters:
origin – 3D point on the parent meristem where this node originated.
parent_tangent – Unit tangent of the parent meristem at origin.
radial_dir – Unit radial outward vector at the node’s divergence angle.
binormal_dir – Unit binormal vector perpendicular to parent_tangent and radial_dir.
age – Plastochron age ($t - t_{text{birth}} ge 0$) of the node.
generation – Branching depth ($1$ = primary lateral node, $2$ = secondary, etc.).
config – Propagation parameters.
- Returns:
Tuple (path_points, tip_tangent, tip_normal, tip_binormal).
- geometor.phyllotaxis.propagate_3d(steps: int, config: MeristemConfig | None = None) list[MeristemNode]¶
Propagate a 3D phyllotaxic meristem system for steps plastochrons.
Node 0 is the primary apical meristem growing along $+Z$. At each step $t$, active meristems grow along their paths and emit new lateral child nodes at the divergence angle $Phi$ around their local tangent frame.
- Parameters:
steps – Number of plastochron steps to simulate.
config – Optional MeristemConfig instance.
- Returns:
List of MeristemNode instances (including the root stem and all lateral/recursive paths).
- class geometor.phyllotaxis.Phyllotaxis(name: str = 'phyllotaxis')¶
Bases:
geometor.phyllotaxis.angles.AnglesMixin,geometor.phyllotaxis.planar.PlanarMixin,geometor.phyllotaxis.paths3d.Propagation3DMixin,geometor.phyllotaxis.builder.ModelBuilderMixinMain class for symbolic and parametric 2D/3D phyllotaxis modeling.
- name = 'phyllotaxis'¶
- class geometor.phyllotaxis.PlanarMixin¶
Mixin for Phyllotaxis class containing 2D planar growth and parastichy methods.
- get_node_points(num_nodes: int, sweep: sympy.Expr | float | None = None) list[sympy.geometry.Point2D]¶
- vogel_points(num_nodes: int, scale: float = 5.0, angle_rad: float = GOLDEN_ANGLE_RAD, base_size: float = 1.5, growth_factor: float = 0.25, radial_acceleration: float = 0.0, leaf_span: int = 34) list[dict[str, float | int | str]]¶
- find_point_distances(pt: sympy.geometry.Point2D, other_pts: list[sympy.geometry.Point2D]) dict[float, sympy.geometry.Point2D]¶
- find_nearest_points(test_points: list[sympy.geometry.Point2D], num_nearest: int = 3) dict[sympy.geometry.Point2D, list[sympy.geometry.Point2D]]¶
- geometor.phyllotaxis.analyze_parastichy_curves(nodes: list[dict[str, float | int | str]], num_nearest: int = 3) dict[str, object]¶
Count parastichy curves in each closest-neighbor rank and radial zone until they bend.
Demonstrates that the two primary closest-neighbor curve families wind in opposite directions (CW vs CCW) and always form a consecutive pair of Fibonacci numbers $(F_m, F_{m+1})$ within each radial zone between curve bends.
- Parameters:
nodes – List of node dictionaries from
vogel_points().num_nearest – Number of closest inner nodes connected per node ($1 le k le 4$).
- Returns:
outer_counts: Curve count $Delta$, winding direction ("CW"or"CCW"), and Fibonacci status for each rank at the outer rim.opposing_pair: Tuple(cw_count, ccw_count)of the two primary opposing spiral families in the outer zone.is_fibonacci_pair:Trueifopposing_pairconsists of consecutive Fibonacci numbers with opposite chirality.zones: Radial zones from inner to outer separated by bend radii.
- Return type:
Dictionary containing
- geometor.phyllotaxis.classify_meristem_phase(node_id: int, total_nodes: int, leaf_span: int = 34) str¶
Classify a node’s ontogenetic organ type in the meristem’s production life cycle.
In a composite capitulum (such as a sunflower), the apical meristem transitions through distinct organ-production phases as the sequence progresses: 1. “leaf”: Early vegetative/involucral bracts (0 <= node_id < leaf_span). 2. “petal”: Ray florets / corolla petals (leaf_span <= node_id < leaf_span + round(leaf_span * φ)). 3. “floret”: Mature tubular disc florets in the capitulum interior. 4. “bud”: Newly initiated unopened primordia at the apical center (age < round(leaf_span / φ)).
- geometor.phyllotaxis.find_nearest_points(test_points: list[sympy.geometry.Point2D], num_nearest: int = 3) dict[sympy.geometry.Point2D, list[sympy.geometry.Point2D]]¶
For each point in test_points, find the num_nearest closest subsequent points.
- geometor.phyllotaxis.find_parastichies(num_nodes: int, families: tuple[int, ...] = (5, 8, 13, 21)) dict[int, list[list[int]]]¶
Group node indices into parastichy spiral chains for each modulo family $m in text{families}$.
- Parameters:
num_nodes – Total number of nodes.
families – Parastichy numbers (typically consecutive Fibonacci numbers).
- Returns:
Mapping from family number $m$ to a list of $m$ index chains [r, r+m, r+2m, …].
- geometor.phyllotaxis.find_point_distances(pt: sympy.geometry.Point2D, other_pts: list[sympy.geometry.Point2D]) dict[float, sympy.geometry.Point2D]¶
Compute Euclidean distances from pt to each point in other_pts.
- geometor.phyllotaxis.get_node_points(num_nodes: int, sweep: sympy.Expr | float | None = None) list[sympy.geometry.Point2D]¶
Generate a single planar growth frame with num_nodes symbolic points.
Each node $i in [0, N-1]$ has radius $N - i$ and angle $i cdot text{sweep}$.
- Parameters:
num_nodes – Number of primordia in the frame.
sweep – Divergence angle in radians (symbolic or float). Defaults to sweep_phi().
- Returns:
List of SymPy Point2D instances.
- geometor.phyllotaxis.grow(steps: int, sweep: sympy.Expr | float | None = None) list[list[sympy.geometry.Point2D]]¶
Grow planar frames from $0$ up to steps - 1 nodes.
- geometor.phyllotaxis.vogel_points(num_nodes: int, scale: float = 5.0, angle_rad: float = GOLDEN_ANGLE_RAD, base_size: float = 1.5, growth_factor: float = 0.25, radial_acceleration: float = 0.0, leaf_span: int = 34) list[dict[str, float | int | str]]¶
Compute 2D apical meristem coordinates with radial acceleration, node growth, and life-cycle phases.
New primordia emerge at the center ($k_{text{eff}} = (N - 1) - i$) while older primordia are displaced radially as $r = csqrt{k_{text{eff}}}left(frac{k_{text{eff}} + 1}{K_0}right)^{a}$, and node size grows as $s = s_0 + gsqrt{k_{text{eff}}}left(frac{k_{text{eff}} + 1}{K_0}right)^{1.15a}$.
- Parameters:
num_nodes – Total number of primordia.
scale – Radial spread constant $c$.
angle_rad – Divergence angle in radians.
base_size – Initial radius of a newly emerged primordium ($s_0$).
growth_factor – Rate $g$ at which primordium size scales as it moves outward.
radial_acceleration – Acceleration exponent $a ge 0$ controlling how much faster older outer nodes move and expand compared to young inner primordia.
leaf_span – Characteristic Fibonacci cohort span for meristem life-cycle phases.
- Returns:
List of dictionaries with keys id, age, phase, x, y, r, theta, size.