Math-PlanePath

 view release on metacpan or  search on metacpan

examples/c-curve-wx.pl  view on Meta::CPAN

  if (! defined $min_x) {
    $min_x = 0;
    $min_y = 0;
    $max_x = 0;
    $max_y = 0;

    foreach my $copy (@{$t->{'copies'}}) {
      my $this_min_x = -.5;
      my $this_max_x = 1.5;
      my $this_min_y = -1;
      my $this_max_y = .25;

      foreach (1 .. ($copy->{'rotate'} || 0)) {
        ($this_max_y,     $this_min_x,   $this_max_x,  $this_min_y)
          = ($this_max_x, -$this_max_y,  -$this_min_y, $this_min_x);
      }
      $this_min_x += $copy->{'x'};
      $this_max_x += $copy->{'x'};
      $this_min_y += $copy->{'y'};
      $this_max_y += $copy->{'y'};
      ### this extents: "X $this_min_x to $this_max_x    Y $this_min_y to $this_max_y"
      $min_x = min($min_x, $this_min_x);
      $min_y = min($min_y, $this_min_y);
      $max_x = max($max_x, $this_max_x);
      $max_y = max($max_y, $this_max_y);
    }
  }
  ### extents: "X $min_x to $max_x    Y $min_y to $max_y"

  #       min_x ----------- 0 ---- max_x
  #                    ^
  # mid = (max+min)/2
  my $extent_x = $max_x - $min_x;
  my $extent_y = $max_y - $min_y;
  ### $extent_x
  ### $extent_y

  my $affine = Geometry::AffineTransform->new;
  $affine->translate(- ($min_x + $max_x)/2,   # extent midpoints
                     - ($min_y + $max_y)/2);

  my $extent_scale = min($width/$extent_x, $height/$extent_y) * .9;
  $affine->scale($extent_scale, $extent_scale);                 # shrink
  ### $extent_scale

  $affine->scale(1, -1);                       # Y upwards
  $affine->scale($scale, $scale);
  $affine->scale(-1,-1);                       # rotate 180
  $affine->translate($width/2, $height/2);     # 0,0 at centre
  $affine->translate($x_offset, $y_offset);

  my ($prev_x,$prev_y) = $to01->transform($x_lo,$y_lo);
  ### origin: "$prev_x, $prev_y"

  undef $dc;

  my $bitmap = Wx::Bitmap->new ($width, $height);
  my $scale = 0.5;
  # $scale = sqrt(3)/2;

  my $iterations = 100;
  my $n = $n_lo+1;
  $idle_drawing = sub {
    my ($event) = @_;
    ### idle_drawing: $event

    my $time = Time::HiRes::time();
    # my $client_dc = Wx::ClientDC->new($draw);
    # my $dc = Wx::BufferedDC->new($client_dc, $bitmap);
    my $dc = Wx::ClientDC->new($draw);

    my $remaining = $iterations;
    for ( ; $n <= $n_hi; $n++) {
      if ($remaining-- < 0) {
        # each took time/iterations, want to take .25 sec so
        # new_iterations = .25/(time/iterations)
        # new_iterations = iterations * .25/time
        my $time = Time::HiRes::time() - $time;
        $iterations = int(($iterations+1) * .25/$time);
        # print "$iterations cf time $time\n";

        if ($event) { $event->RequestMore(1); }
        return;
      }

      my ($x,$y) = $path->n_to_xy($n);
      ($x,$y) = $to01->transform($x,$y);
      ### point: "$x, $y"

      my $c = 0;
      foreach my $copy (@{$t->{'copies'}}) {
        $c++;

        my $x = $x;
        my $y = $y;
        my $prev_x = $prev_x;
        my $prev_y = $prev_y;
        if ($copy->{'invert'}) {
          $y = -$y;
          $prev_y = -$prev_y;
        }
        if (my $r = $copy->{'rotate'}) {
          foreach (1 .. $r) {
            ($x,$y) = (-$y,$x); # rotate +90
            ($prev_x, $prev_y) = (-$prev_y, $prev_x);  # rotate +90
          }
        }
        $x += $copy->{'x'};
        $y += $copy->{'y'};
        $prev_x += $copy->{'x'};
        $prev_y += $copy->{'y'};

        my $dx = $x - $prev_x;
        my $dy = $y - $prev_y;
        my $mx = ($x + $prev_x)/2;  # midpoint prev to this
        my $my = ($y + $prev_y)/2;

        if (defined $t->{'clip_min_x'}) {
          my $cx = $mx - $dy * $scale * .5;
          my $cy = $my + $dx * $scale * .5;
          if ($cx < $t->{'clip_min_x'} || $cx > $t->{'clip_max_x'}
              || $cy < $t->{'clip_min_y'} || $cy > $t->{'clip_max_y'}) {
            next;
          }
        }
        $mx += $dy * $scale;   # dx,dy turned right -90deg
        $my -= $dx * $scale;   # for triangle top

        ($prev_x,$prev_y) = $affine->transform($prev_x,$prev_y);
        ($mx, $my) = $affine->transform($mx,$my);
        ($x,$y) = $affine->transform($x,$y);
        ### screen: "$prev_x, $prev_y to $x, $y"

        if (xy_in_rect($x,$y, 0,0,$width,$height)
            || xy_in_rect($prev_x,$prev_y, 0,0,$width,$height)
            || xy_in_rect($mx,$my, 0,0,$width,$height)) {
          if ($figure eq 'Triangles') {
            $dc->SetBrush ($brushes[$c]);
            $dc->SetPen ($pens[$c]);
            $dc->DrawPolygon



( run in 0.590 second using v1.01-cache-2.11-cpan-71847e10f99 )