App-GUI-Harmonograph

 view release on metacpan or  search on metacpan

README  view on Meta::CPAN

    this time four types of acceleration. Minus and times work as before and
    plus and divided by are just their opposite.

    The fifth row has a slider that sets the starting position of the
    pendulum along its expected track. If the slider is on max you move the
    pendulum a quater rotation ahead. To add another quarter check the box
    left beside it. The last box adds another half rotation. This allows you
    to flip or mirror the image in meaningful ways.

    The sixth row mirrors the first but with 2 distinctions. Its not about
    integer values but percentage values of the original pendulum length.
    This length will be calculated by the program for opimal display. Thi
    slider helps you only to change the proportions of the amplitude towards
    the other pendula. Natural constants are also here available as a factor
    and behind the on the most right is a button to reset the radius to 100
    percent.

    The seventh row is the amplitude size, which simple allows to make the
    picture larger or smaller depending if the pendulum left the frame or
    doesn't move enough. As with reqency, also the amplitude can be damped
    over time and this damping can accelerated.

    Row eight and nine are exact copies of row three and four, they just
    affect the radius / amplitude.

  Functions

lib/App/GUI/Harmonograph.pm  view on Meta::CPAN

this time four types of acceleration. Minus and times work as before
and plus and divided by are just their opposite.

The fifth row has a slider that sets the starting position of the
pendulum along its expected track. If the slider is on max you move
the pendulum a quater rotation ahead. To add another quarter check the
box left beside it. The last box adds another half rotation. This allows
you to flip or mirror the image in meaningful ways.

The sixth row mirrors the first but with 2 distinctions. Its not about
integer values but percentage values of the original pendulum length.
This length will be calculated by the program for opimal display.
Thi slider helps you only to change the proportions of the amplitude
towards the other pendula. Natural constants are also here available as
a factor and behind the on the most right is a button to reset the
radius to 100 percent.

The seventh row is the amplitude size, which simple allows to make the
picture larger or smaller depending if the pendulum left the frame or
doesn't move enough. As with reqency, also the amplitude can be damped
over time and this damping can accelerated.

Row eight and nine are exact copies of row three and four, they just
affect the radius / amplitude.


lib/App/GUI/Harmonograph/Compute/Drawing.pm  view on Meta::CPAN

    push @code, '$Cr /= (($max_xr > $max_yr) ? $max_xr : $max_yr)'; # zoom out so everything is visible
    push @code, @init_var_code, 'my ($x, $y)';
    push @code, 'my ($x_old, $y_old)','my $line_broke = 1' if $set->{'visual'}{'connect_dots'};
    push @code, '$dc->SetPen( Wx::Pen->new( shift @wx_colors, $pen_size, $pen_style ) )',
                'my $first_color = shift @colors';
    push @code, 'my $color_timer = 0' if $color_swap_time;
    push @code, 'for my $i (1 .. $dot_count){';
    if ($color_swap_time){
        push @code, '  if ($color_timer++ == $color_swap_time){', '    $color_timer = 1',
                    '    $dc->SetPen( Wx::Pen->new( shift @wx_colors, $pen_size, $pen_style) )';
        push @code, '    $progress_bar->add_percentage( ($i/ $dot_count*100), [(shift @colors)->values] )' unless defined $sketch;
        push @code, '  }';
    }
    push @code, @compute_coor_code, @update_var_code;
    push @code, '  next if rand(1) > $pen_probability' if $pen_probability < 1;
    push @code, ($set->{'visual'}{'connect_dots'}
              ? ('  if ($line_broke) {$line_broke = 0; ($x_old, $y_old) = ($x, $y) }',
                 '  if ($x < 0 or $x > $board_size or $y < 0 or $y > $board_size) {$line_broke++; next}',
                '  $dc->DrawLine( $x_old, $y_old, $x, $y)',
                '  ($x_old, $y_old) = ($x, $y)' )
              : '  $dc->DrawPoint( $x, $y )');
    push @code, '}';
    push @code, '$progress_bar->add_percentage( 100, [$first_color->values] )' unless defined $sketch or $color_swap_time ;

    my $code = join '', map {$_.";\n"} @code, '}'; # say $code;
    my $code_ref = eval $code;
    die "bug '$@' in drawing code: $code" if $@; #
    # say "comp: ",timestr( timediff( Benchmark->new(), $t) );
    return $code_ref
}

1;

lib/App/GUI/Harmonograph/Frame/Tab/Visual.pm  view on Meta::CPAN


    $self->{'widget'}{'draw'} = Wx::RadioBox->new( $self, -1, 'Draw', [-1, -1], [120, -1], ['Dots', 'Line']);
    $self->{'widget'}{'draw'}->SetToolTip('draw just dots (off) or connect them with lines (on)');
    $self->{'widget'}{'pen_style'} = Wx::ComboBox->new( $self, -1, 'solid', [-1,-1], [125, -1],
        [qw/dotted short_dash solid vertical horizontal cross diagonal bidiagonal/], &Wx::wxTE_READONLY );
    $self->{'widget'}{'pen_style'}->SetToolTip('which pattern is engraved in drawn line / dots');
    $self->{'widget'}{'line_thickness'} = App::GUI::Harmonograph::Widget::SliderCombo->new( $self, 355, 'Thickness','dot size or thickness of drawn line in pixel',  1,  55,  1);
    $self->{'widget'}{'duration_min'} = App::GUI::Harmonograph::Widget::SliderCombo->new( $self, 85, 'Minutes','', 0,  100,  10);
    $self->{'widget'}{'duration_s'}   = App::GUI::Harmonograph::Widget::SliderCombo->new( $self, 85, 'Seconds','', 0,  59,  10);
    $self->{'widget'}{'dot_probability'} = App::GUI::Harmonograph::Widget::SliderCombo->new( $self, 340, 'Probability','', 1,  100,  100, .1);
    $self->{'widget'}{'dot_probability'}->SetToolTip("How high is the chance that a dot is actually set in percent ?");
    $self->{'widget'}{'100dots_per_second'} = App::GUI::Harmonograph::Widget::SliderCombo->new( $self, 110, 'Coarse','how many dots is drawn in a second in batches of 50 ?',  0,  90,  10);
    $self->{'widget'}{'dots_per_second'} = App::GUI::Harmonograph::Widget::SliderCombo->new( $self, 100, 'Fine','how many dots is drawn in a second ?',  0,  99,  10);
    $self->{'widget'}{'color_flow_type'} = Wx::ComboBox->new( $self, -1, 'no', [-1,-1], [115, -1], [qw/no one_time alternate circular/], &Wx::wxTE_READONLY );
    $self->{'widget'}{'color_flow_type'}->SetToolTip("type of color flow: - linear - from start to end color \n  - alter(nate) - linearly between start and end color \n   - cicular - around the rainbow from start color visiting end color");
    $self->{'label'}{'flow_type'}->SetToolTip("type of color flow: - linear - from start to end color \n  - alter(nate) - linearly between start and end color \n   - cicular - around the rainbow from start color visiting end color");
    $self->{'widget'}{'color_flow_dynamic'} = App::GUI::Harmonograph::Widget::SliderCombo->new( $self, 115, 'Dynamic', '0 = equally paced color change, larger = starting with slow color change becoming faster - or vice versa when dir activated', -12,...
    $self->{'widget'}{'color_flow_speed'} = App::GUI::Harmonograph::Widget::SliderCombo->new( $self, 116, 'Speed','color changes per minute', 1, 90, 1, .1);
    $self->{'widget'}{'invert_flow_speed'} = Wx::CheckBox->new( $self, -1, ' Invert');
    $self->{'widget'}{'invert_flow_speed'}->SetToolTip("invert value of color change speed by 1/x");

lib/App/GUI/Harmonograph/Widget/ProgressBar.pm  view on Meta::CPAN


sub new {
    my ( $class, $parent, $x, $y, $color  ) = @_;
    return unless ref $color eq 'ARRAY' and @{$color} == 3;

    my $self = $class->SUPER::new( $parent, -1, [-1,-1], [$x, $y]);

    $self->{'x'}     = $x;
    $self->{'y'}     = $y;
    $self->{'color'} = $color;
    $self->{'percentage'} = [];

    Wx::Event::EVT_PAINT( $self, sub {
        my( $cpanel, $event ) = @_;
        my $dc = Wx::PaintDC->new( $cpanel );
        my $bg_color = Wx::Colour->new( 255, 255, 255 );
        my ($x, $y) = ( $self->GetSize->GetWidth, $self->GetSize->GetHeight );
        $dc->SetBackground( Wx::Brush->new( $bg_color, &Wx::wxBRUSHSTYLE_SOLID ) );
        $dc->Clear();

        my $l_pos = 0;
        my $l_color = Wx::Colour->new( @{$self->{'color'}} );
        if (@{$self->{'percentage'}} > 1){
            my $i = 1;
            while (exists $self->{'percentage'}[$i]){
                my $r_pos = $x * ($self->{'percentage'}[$i] / 100);
                my $r_color = Wx::Colour->new( @{$self->{'percentage'}[$i-1]} );
                $dc->GradientFillLinear( Wx::Rect->new( $l_pos, 0, $r_pos, $y ), $l_color, $r_color );
                $i += 2;
                $l_pos = $r_pos;
                $l_color = $r_color;
            }
        }
    } );
    $self;
}

sub reset {
    my ( $self, $p, $color ) = @_;
    $self->{'percentage'} = [];
    $self->Refresh;
}

sub set_color {
    my ( $self, $r, $g, $b ) = @_;
    return unless defined $b;
    $self->{'color'} = [$r, $g, $b];
}

sub add_percentage {
    my ( $self, $percent, $color ) = @_;
    return unless defined $percent and $percent <= 100 and $percent >= 0
        and $percent != $self->{'percentage'} and ref $color eq 'ARRAY' and @$color == 3;
    push @{$self->{'percentage'}}, $color, $percent; # say " $percent  $color->[0],$color->[1],$color->[2]";
    $self->Refresh;
}

sub get_percentage { $_[0]->{'percentage'} }

1;



( run in 0.338 second using v1.01-cache-2.11-cpan-05162d3a2b1 )