Perl 循环变量
我正在使用perl编写一个脚本,该脚本将用于点积/组合向量数学。我已经有了一个工作脚本(仍在进行中/需要改进),可以满足我的要求Perl 循环变量,perl,scripting,Perl,Scripting,我正在使用perl编写一个脚本,该脚本将用于点积/组合向量数学。我已经有了一个工作脚本(仍在进行中/需要改进),可以满足我的要求 #!/usr/bin/perl use strict; use warnings; use diagnostics; use Math::Vector::Real; use 5.010; use Math::Trig; my $source = "./IN"; my $out = "./OUT"; open(IN, '<', $source) or die
#!/usr/bin/perl
use strict;
use warnings;
use diagnostics;
use Math::Vector::Real;
use 5.010;
use Math::Trig;
my $source = "./IN";
my $out = "./OUT";
open(IN, '<', $source) or die "Couldn't open $source: $!\n";
open(OUT, '>', $out) or die "Couldn't open $out: $!\n";
my(@data);
while (<IN>) {
push @data, [ split ];
}
my $v;
my $u;
$v = V(0, 0, 0);
$u = V(0, 0, 0);
my $i = 0;
sub maths {
my $dot = $v * $u;
my $mag1 = (sqrt ((@$v[0])**2 + (@$v[1])**2 + (@$v[2])**2 ));
my $mag2 = (sqrt ((@$u[0])**2 + (@$u[1])**2 + (@$u[2])**2 ));
my $prefinal = acos( ( $dot ) / ( $mag1 * $mag2 ) );
my $degrees = ( ( 180 / 3.14159 ) * ( $prefinal ) );
return ($degrees);
}
my $ref1 = $data[$i][0];
my $ref2 = $data[$i][1];
my $ref3 = $data[$i][2];
my $ref4 = $data[$i+1][0];
my $ref5 = $data[$i+1][1];
my $ref6 = $data[$i+1][2];
$v->[0] = $ref1;
$v->[1] = $ref2;
$v->[2] = $ref3;
$u->[0] = $ref4;
$u->[1] = $ref5;
$u->[2] = $ref6;
my $result = maths;
print "$result\n";
感谢您所做的一切。您可以使用以下内容:
my $v = V( @{ $data[$i+0] } );
my $u = V( @{ $data[$i+1] } );
清理:
#!/usr/bin/perl
use strict;
use warnings;
use Math::Trig qw( acos );
use Math::Vector::Real qw( V );
sub maths {
my ($v, $u) = @_;
my $dot = $v * $u;
my $mag1 = sqrt( $v->[0]**2 + $v->[1]**2 + $v->[2]**2 );
my $mag2 = sqrt( $u->[0]**2 + $u->[1]**2 + $u->[2]**2 );
my $prefinal = acos( $dot / ( $mag1 * $mag2 ) );
my $degrees = ( 180 / 3.14159 ) * $prefinal;
return $degrees;
}
{
my @data = map { V( split ) } <>;
for my $i (0..$#data-1) {
for my $j ($i+1..$#data) {
my $maths = maths(@data[$i, $j]);
print("$i,$j: $maths\n");
}
}
}
根据我的评论,您程序的大部分功能都是由您正在使用的模块提供的 看起来您需要文件中连续的3D向量对之间的角度(以度为单位)。此代码从文件中的每一行创建向量,直到
@pair
中有两个向量,然后使用atan2
计算它们之间的角度DEG_PER_RAD
是根据定义为π÷4的atan2(1,1)
的值预先计算出来的常数
#!/usr/bin/perl
use strict;
use warnings;
use Math::Vector::Real;
use constant DEG_PER_RAD => 45 / atan2(1, 1);
my ( $source, $out ) = qw/ IN OUT /;
open my $in_fh, '<', $source or die qq{Unable to open "$source" for input: $!\n};
open my $out_fh, '<', $out or die qq{Unable to open "$out" for output: $!\n};
select $out_fh;
my @pair;
while ( <$in_fh> ) {
push @pair, V(split);
if ( @pair == 2 ) {
my $degrees = atan2(@pair) * DEG_PER_RAD;
print "$degrees\n";
shift @pair;
}
}
请注意,模块还将计算向量的大小,因此
my$mag1=abs$v;my$mag2=abs$u代码>。事实上,如果您只需要向量之间的角度,那么数学
子例程就是atan2($v,$u)*180/3.14159
必须稍微编辑以使其工作(等待同行审查),但它做到了。我读过关于atan函数的书,但是没有清楚地解释,所以我很难做到。一路上学了一两件事。谢谢但是,有没有办法让它计算从每一条线到另一条线的角度?我尝试了一些嵌套的foreach循环,但没有效果。即,对于每条线,计算角度。转到下一行,计算角度,直到文件结束。@jcklasster:好的,我添加了一些代码来完成我认为您需要的操作。请解释您所做的更改,因为我看不出我的代码有任何错误,因为它位于我的mac上,嵌套的atan必须将(@data[$I,$j])写入(@data[$I],@data[$j])。Strict还抱怨,并让我将@data更改为$data。此外,输出文件将打开以进行输入。无论出于何种原因,我的更改没有通过同行评审。@jcklasster,根据您的评论更新。
#!/usr/bin/perl
use strict;
use warnings;
use Math::Trig qw( acos atan2 );
use Math::Vector::Real qw( V );
use constant DEG_PER_RAD => 45 / atan2(1, 1);
{
my @data = map { V( split ) } <>;
for my $i (0..$#data-1) {
for my $j ($i+1..$#data) {
my $maths = atan2(@data[$i, $j]) * DEG_PER_RAD;
print("$i,$j: $maths\n");
}
}
}
perl script.pl ./IN >./OUT
#!/usr/bin/perl
use strict;
use warnings;
use Math::Vector::Real;
use constant DEG_PER_RAD => 45 / atan2(1, 1);
my ( $source, $out ) = qw/ IN OUT /;
open my $in_fh, '<', $source or die qq{Unable to open "$source" for input: $!\n};
open my $out_fh, '<', $out or die qq{Unable to open "$out" for output: $!\n};
select $out_fh;
my @pair;
while ( <$in_fh> ) {
push @pair, V(split);
if ( @pair == 2 ) {
my $degrees = atan2(@pair) * DEG_PER_RAD;
print "$degrees\n";
shift @pair;
}
}
my @data;
push @data, V(split) while <$in_fh>;
for my $i ( 0 .. $#data-1 ) {
for my $j ( $i+1 .. $#data ) {
my $degrees = atan2(@data[$i,$j]) * DEG_PER_RAD;
print "[$i,$j] $degrees\n";
}
}