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 )