File Coverage

blib/lib/Physics/Springs.pm
Criterion Covered Total %
statement 43 43 100.0
branch n/a
condition n/a
subroutine 8 8 100.0
pod 1 1 100.0
total 52 52 100.0


line stmt bran cond sub pod time code
1             package Physics::Springs;
2              
3 2     2   30723 use 5.006;
  2         7  
  2         88  
4 2     2   13 use strict;
  2         4  
  2         71  
5 2     2   10 use warnings;
  2         4  
  2         114  
6              
7             our $VERSION = '1.01';
8              
9 2     2   10 use Carp;
  2         5  
  2         202  
10 2     2   1833 use Physics::Particles;
  2         23375  
  2         64  
11 2     2   1978 use Sub::Assert;
  2         4037  
  2         135  
12              
13 2     2   14 use base 'Physics::Particles';
  2         4  
  2         2017  
14              
15              
16             sub new {
17             my $proto = shift;
18             my $class = ref($proto) || $proto;
19              
20             my $self = $class->SUPER::new();
21             $self->{_PhSprings_springs} = [];
22             return $self;
23             }
24              
25             assert
26             pre => '@PARAM == 1',
27             post => '@RETURN == 1',
28             context => 'novoid',
29             action => 'croak',
30             sub => 'new';
31              
32             sub add_spring {
33             my $self = shift;
34             my %args = @_;
35             my $spring = {};
36             my $k = $args{k};
37             my $p1 = $args{p1};
38             my $p2 = $args{p2};
39             my $l = $args{l};
40              
41             defined($k) && defined($p1) && defined($p2)
42             or croak("You need to supply several named arguments.");
43              
44             # default to being relaxed
45             if (not defined $l) {
46             my $dist = sqrt(
47             ( ($self->{p}[$p1]{x} - $self->{p}[$p2]{x}) )**2 +
48             ( ($self->{p}[$p1]{y} - $self->{p}[$p2]{y}) )**2 +
49             ( ($self->{p}[$p1]{z} - $self->{p}[$p2]{z}) )**2
50             );
51             $l = abs($dist);
52             }
53              
54             $spring->{k} = $k;
55             $spring->{p1} = $p1;
56             $spring->{p2} = $p2;
57             $spring->{len} = $l;
58              
59             push @{$self->{_PhSprings_springs}}, $spring;
60             return $#{$self->{_PhSprings_springs}};
61             }
62              
63             assert
64             pre => '@PARAM >= 9',
65             post => '$VOID or @RETURN == 1 && $RETURN >= 0',
66             action => 'croak',
67             sub => 'add_spring';
68              
69             sub iterate_step {
70 10     10 1 5232 my $self = shift;
71 10         26 my @params = @_;
72 10         12 my $time_diff = $params[0];
73 10         13 foreach my $spring (@{$self->{_PhSprings_springs}}) {
  10         21  
74 30         55 my $p1 = $self->{p}[$spring->{p1}];
75 30         48 my $p2 = $self->{p}[$spring->{p2}];
76 30         37 my $l = $spring->{len};
77 30         41 my $k = $spring->{k};
78              
79 30         105 my $dist = sqrt(
80             ( ($p1->{x} - $p2->{x}) )**2 +
81             ( ($p1->{y} - $p2->{y}) )**2 +
82             ( ($p1->{z} - $p2->{z}) )**2
83             );
84              
85 30         42 my $force1 = $k * ($dist-$l);
86 30         54 my $force2 = -$force1;
87              
88 30         48 my $dx = ($p2->{x} - $p1->{x}) / $dist;
89 30         49 my $dy = ($p2->{y} - $p1->{y}) / $dist;
90 30         39 my $dz = ($p2->{z} - $p1->{z}) / $dist;
91              
92 30         45 $p1->{_fx} += $force1 * $dx;
93 30         37 $p1->{_fy} += $force1 * $dy;
94 30         38 $p1->{_fz} += $force1 * $dz;
95              
96 30         39 $p2->{_fx} += $force2 * $dx;
97 30         40 $p2->{_fy} += $force2 * $dy;
98 30         65 $p2->{_fz} += $force2 * $dz;
99             }
100              
101 10         44 $self->SUPER::iterate_step(@params);
102             }
103              
104             1;
105             __END__