use strict; use warnings; use Tk; use Tk::WorldCanvas; use Physics::Springs; my $sim = Physics::Springs->new(); use Data::Dumper; my $mw = MainWindow->new(); my $worldcanvas = $mw->WorldCanvas(-width=>400,-height=>400); my $i = 1; $worldcanvas->configure(-bandColor => 'purple'); $worldcanvas->CanvasBind('<3>' => sub {$worldcanvas->CanvasFocus; $worldcanvas->rubberBand(0) }); my $spring_start = undef; $worldcanvas->CanvasBind('<1>' => sub { my ($x,$y) = $worldcanvas->eventLocation; my $name = "Sun_" . $i++; print "Inserting at $name ($x,$y)\n"; $worldcanvas->createOval( $x-5,$y-5,$x+5,$y+5, -fill=>'yellow', -tag=> $name); my $spring_end = $sim->add_particle( x=> $x, y=> $y, z=>0, xv => 1, yv => 0, m=>10_000, n => $name); $sim->add_spring(k=>1,p1=>$spring_start, p2=>$spring_end,l=>undef) if defined $spring_start; $spring_start = $spring_end; } ); $worldcanvas->CanvasBind('<2>' => sub { my ($x,$y) = $worldcanvas->eventLocation; my $name = "Vertex_" . $i++; print "Inserting at $name ($x,$y)\n"; $worldcanvas->createOval( $x-5,$y-5,$x+5,$y+5, -fill=>'red', -tag=> $name); my $spring_end = $sim->add_particle( x=> $x, y=> $y, z=>0, xv => 1, yv => 0, m=>50, n => $name); $sim->add_spring(k=>1,p1=>$spring_start, p2=>$spring_end, l=>50) if defined $spring_start; $spring_start = $spring_end; } ); $worldcanvas->CanvasBind('' => sub {$worldcanvas->rubberBand(1)}); $worldcanvas->CanvasBind('' => sub {my @box = $worldcanvas->rubberBand(2); my @ids = $worldcanvas->find('enclosed', @box); foreach my $id (@ids) {$worldcanvas->delete($id)} }); $worldcanvas->CanvasBind('' => sub {$worldcanvas->rubberBand(1);}); $worldcanvas->CanvasBind('' => sub {$worldcanvas->rubberBand(1);}); $worldcanvas->CanvasBind('' => sub {$worldcanvas->rubberBand(1);}); $worldcanvas->CanvasBind('' => sub {$worldcanvas->rubberBand(1);}); $worldcanvas->CanvasBind('' => sub {$worldcanvas->zoom(1.25); $worldcanvas->rubberBand(1);}); $worldcanvas->CanvasBind('' => sub {$worldcanvas->zoom(0.8); $worldcanvas->rubberBand(1);}); $worldcanvas->pack(); $worldcanvas->CanvasFocus; $worldcanvas->repeat(100, sub { $sim->iterate_step(1); foreach my $p (@{ $sim->{p} }) { $worldcanvas->coords($p->{n}, $p->{x} - 5 , $p->{y} - 5, $p->{x} + 5 , $p->{y} + 5 ); } foreach my $spring (@{$sim->{_PhSprings_springs}}) { my $p1 = $sim->{p}[$spring->{p1}]; my $p2 = $sim->{p}[$spring->{p2}]; my $spring_name = 'spring_' . $spring; if ($worldcanvas->find('withtag',$spring_name)) { $worldcanvas->coords($spring_name, $p1->{x}, $p1->{y}, $p2->{x}, $p2->{y}); #print "$spring_name ", $spring->{strech}, "\n"; } else { $worldcanvas->createLine($p1->{x}, $p1->{y}, $p2->{x}, $p2->{y}, -tag=>$spring_name); } } }); MainLoop; #### foreach my $spring (@{$self->{_PhSprings_springs}}) { my $p1 = $self->{p}[$spring->{p1}]; my $p2 = $self->{p}[$spring->{p2}]; my $l = $spring->{len}; my $k = $spring->{k}; my $dist = sqrt( ( ($p1->{x} - $p2->{x}) )**2 + ( ($p1->{y} - $p2->{y}) )**2 + ( ($p1->{z} - $p2->{z}) )**2 ); my $force1 = $k * ($dist-$l); my $force2 = -$force1; my $dx = ($p2->{x} - $p1->{x}) / $dist; my $dy = ($p2->{y} - $p1->{y}) / $dist; my $dz = ($p2->{z} - $p1->{z}) / $dist; $p1->{_fx} += $force1 * $dx; $p1->{_fy} += $force1 * $dy; $p1->{_fz} += $force1 * $dz; $p2->{_fx} += $force2 * $dx; $p2->{_fy} += $force2 * $dy; $p2->{_fz} += $force2 * $dz; }