Algorithm-Shape-RandomTree
view release on metacpan or search on metacpan
lib/Algorithm/Shape/RandomTree.pm view on Meta::CPAN
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 );
lib/Algorithm/Shape/RandomTree.pm view on Meta::CPAN
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 ##
lib/Algorithm/Shape/RandomTree.pm view on Meta::CPAN
}
# Create Stem: creates the primary branch (stem) for in both recursive and
# linear tree creating algorithms
sub create_stem {
my $self = shift;
my $verb = $self->verbose;
$verb && print "[create_stem] Starting\n";
my $d = $self->stem_length;
# Set stem slope ( currently it's stragight up - slope = 0 )
my $m = 0;
# To set the slope to a random number between -/+0.5:
# my $m = -0.5 + rand(1);
# Set starting coordinates for the Tree's stem
# Stem's X position is in the middle of the image
my $x_start = int( $self->image_width / 2 );
# Y position is of 1st point is on the ground.
my $y_start = 0;
# Mathematically speaking:
# Stem length = distance between it's start and end points:
# d = sqrt[ (x2-x1)**2 + (y2-y1)**2 ] = sqrt( dx**2 + dy**2 )
# Slope:
# m = dy / dx = (y2-y1) / (x2-x1)
# After development and a applying the square-root:
# y = sqrt[ d**2 / ( m**2 + 1 ) ] + y1
# x = m * (y1 - y) + x1
my $y_end = int(
sqrt( $d ** 2 / ( ( $m ** 2 ) + 1 ) + $y_start )
lib/Algorithm/Shape/RandomTree.pm view on Meta::CPAN
parent => $parent,
# nodulation => ,
# complexity => ,
);
$self->add_branch( $newbranch );
}
# Calculate New Deltas: uses the parent branch's attributes and random factors
# to modify a new branche's dx and dy values, who determin the angle and length
# of the new branch.
sub calc_new_deltas {
my ( $self, $parent ) = @_;
my $verb = $self->verbose;
# Get parent branch's deltas
my $old_dx = $parent->dx;
my $old_dy = $parent->dy;
# Calculate modifiers:
# These slightly change the dx and dy to create variation and randomness
# in branches lengths and angles.
# Modifiers range from -range_value to +range_value
my $dx_modifier = (
int( rand( $self->dx_range ) * -1 ) +
int( rand( $self->dx_range ) )
);
my $dy_modifier = (
int( rand( $self->dy_range ) * -1 ) +
int( rand( $self->dy_range ) )
);
lib/Algorithm/Shape/RandomTree.pm view on Meta::CPAN
}
sub create_path {
my ( $self, $start, $end, $dx, $dy ) = @_;
my $x1 = $start->x;
my $y1 = $start->y;
my $x2 = $end->x;
my $y2 = $end->y;
my $length = sqrt( $dx ** 2 + $dy ** 2 );
my $phandle = $self->branch_curve * $length;
# X / Y values of control point 1 (curving the start point)
my $c1_x = $x1 - rand($phandle) + rand($phandle);
my $c1_y = $y1 - rand($phandle) + rand($phandle);
# X / Y values of control point 2 (curving the end point)
my $c2_x = $x2 - rand($phandle) + rand($phandle);
my $c2_y = $y2 - rand($phandle) + rand($phandle);
my $d_str = "M $x1 $y1 C $c1_x $c1_y $c2_x $c2_y $x2 $y2";
( run in 0.260 second using v1.01-cache-2.11-cpan-65fba6d93b7 )