Algorithm-Shape-RandomTree

 view release on metacpan or  search on metacpan

lib/Algorithm/Shape/RandomTree.pm  view on Meta::CPAN

package Algorithm::Shape::RandomTree;

use Moose;
use namespace::autoclean;

use Algorithm::Shape::RandomTree::Branch;
use Algorithm::Shape::RandomTree::Branch::Point;

our $VERSION = '0.01';

## Attributes ##

has 'stem_length'   => ( is => 'ro', isa => 'Int' );   # Length of stem
has 'tree_width'    => ( is => 'ro', isa => 'Int' );   # Width of stem
has 'stem_curve'    => ( is => 'ro', isa => 'Int' );   # Curvature and complexity of stem
has 'branch_length' => ( is => 'ro', isa => 'Int' );   # Average (non-stem) branch length
has 'branch_stdev'  => ( is => 'ro', isa => 'Int' );   # Plus-minus range around the average
has 'complexity'    => ( is => 'ro', isa => 'Int' );   # Branching modifier: max number of
                                                       # branches sprouting from a node
has 'branch_curve'  => ( is => 'ro', isa => 'Num' );   # Average curvature of (non-stem) 
                                                       # branches

# Nodulation: determins the number of levels of sub-branching
has 'nodulation'    => ( is => 'ro', isa => 'Int' );
# Ebbing Factor: Determins how quickly the nodulation decreases along the tree
has 'ebbing_factor' => ( is => 'ro', isa => 'Int', default => 2 );

# Creation algorithm: can be either linear or recursive
# Linear gives more control but looks slightly less natural
has 'creation_algorithm' => ( is => 'ro', isa => 'Str', default => 'recursive' );

has 'branches' => ( 
    is      => 'ro',
    isa     => 'ArrayRef',
    traits  => [ 'Array' ],
    default => sub { [ ] },
    handles => {
        add_branch      => 'push',
        count_branches  => 'count',
        filter_branches => 'grep',
    },
);   

# These two determine the amount of change in branch length and angle
# between branches, and along the whole shape of the tree
has 'dx_range' => ( is => 'ro', isa => 'Int'  );
has 'dy_range' => ( is => 'ro', isa => 'Int'  );

has 'verbose'  => ( is => 'ro', isa => 'Bool' );

# TODO: Determines whether the tree's shape is more dominated by a single stem with
# shorter and less developed sub-branches, or is highly complex and branching.
# An apically dominant tree will have one dominant stem with many branches
# sprouting out of it, throughout it's length. ** Not yet implemented (I still 
# need to think how to do this). **
# The easier model is the non-apically-dominant tree, with modular branches.
has 'apical_dominance' => ( is => 'ro', isa => 'Int' );

# This is the width of the image on which the tree will be rendered, in pixels
has 'image_width' => ( is => 'ro', isa => 'Int' );


## Methods ##

sub create_tree {
    my $self = shift;

    my $verb = $self->verbose;
    
    $verb && print "[create_tree] Starting\n";
    $verb && print "[create_tree] algorithm is $self->creation_algorithm\n";

    if ( $self->creation_algorithm eq 'recursive' ) {
        # Create main stem
        my $stem = $self->create_stem;
        
        $verb && print "[create_tree] creating primary branches\n";
        
        # Create primary branches and recurse all sub-branches
        foreach my $branch ( 1 .. $self->complexity ) {
            $verb && print "[create_tree] \t creating primary branch $branch\n";
            
            $self->create_branches_recursive( $stem );
        }

    } else {
        
       # Set number of branching levels
        my $levels = $self->nodulation;



( run in 1.283 second using v1.01-cache-2.11-cpan-4991d5b9bd9 )