我做了几个方法。计算质心,根据质心平移矩阵。计算质量中心工作正常。 x,y,z值很好。但是,我在translateMatrixOperation子方法中传递和返回数组时遇到了麻烦。实际上,translateMatrixOperation返回(\ @translatematrix),我无法访问另一个调用子方法的方法中的元素。这有什么问题?
my @ref = calculateCenterMass(@matrix);
my $x = $ref[0];
my $y = $ref[1];
my $z = $ref[2];
print "Center of Mass for Matrix Above\n";
printf("X:%.3f,Y:%.3f,Z:%.3f\n\n",$x,$y,$z);
my @tempMatrix = translateMatrixOperation($x,$y,$z,\@matrix);
-----------------------------------------
sub translateMatrixOperation
{
my ($x, $y, $z, $translatematrix) = @_;
my $arrsize = @$translatematrix;
for(my $i = 0; $i < $arrsize; $i++)
{
for(my $j = 0; $j < $arrsize; $j++)
{
if ($j == 0)
{
$translatematrix->[$i][$j] -= $x;
}
elsif ($j == 1)
{
$translatematrix->[$i][$j] -= $y;
}
elsif ($j == 2)
{
$translatematrix->[$i][$j] -= $z;
}
}
}
return (\@translatematrix);
}
答案 0 :(得分:5)
子例程返回对数组的引用。您将结果存储在数组@tempMatrix中。因此,整个矩阵存储在$tempMatrix[0]
。
这可能不是你想要的。如果子例程返回引用,请使用标量变量来保留它,或者在将结果赋给数组之前取消引用它:
my $array_ref = translateMatrixOperation($x,$y,$z,\@matrix);
my @array = @{ translateMatrixOperation($x,$y,$z,\@matrix) };
后一种选择速度较慢且占用内存较多,因为必须复制该数组。
答案 1 :(得分:0)
返回数组引用而不仅仅是返回数组的选择通常可以归结为大小。
如果要传输小数组,我只需用:
编写return @translatematrix;
如果要传输大型数组(大到足以影响性能),那么我可能会考虑返回一个引用。
我不确定你应该将它们称为矩阵,因为它们似乎是cartesian coordinates的数组。这会更容易思考。
无论如何,您的代码非常冗长,而且很可能是错误的。
当它不需要时,它使用C样式进行循环。
foreach
循环通常更快,并且它们更清楚地表明它们正在循环。
它循环遍历内部数组,即使你几乎总是会改变3个值。
你的内部for循环使用外部数组的长度,而不是内部数组。
如果外环少于3个元素,则会出现问题 这也意味着当你的外部数组很大时,你的代码会花费大量的时间做任何事情。
这也是使用foreach
循环的另一个原因,你无法将测试部分弄错。
您可以修改原始数组的元素。
您将返回对您在子例程中实际未使用的数组的引用。
我只能假设您的代码中没有use strict;
和use warnings;
,或者您已在代码中的其他位置声明了@translatematrix
。
这是一个仍然修改原始数组的版本。 (也许这就是你真正想要的)
use strict;
use warnings;
my @matrix = ...;
# no need for a temporary variable
my ($x,$y,$z) = calculateCenterMass(@matrix);
print "Center of Mass for Matrix Above\n";
printf( "X:%.3f,Y:%.3f,Z:%.3f\n\n", $x, $y, $z );
# it returns a reference, not an array.
my $tempMatrix = translateMatrixOperation( $x, $y, $z, \@matrix );
sub translateMatrixOperation {
my ($x, $y, $z, $translate_matrix) = @_;
for my $xyz ( @$translate_matrix ){
$xyz->[0] -= $x;
$xyz->[1] -= $y;
$xyz->[2] -= $z;
}
return @$translate_matrix if wantarray;
return $translate_matrix;
}
这是一个创建新数组的版本。
my $tempMatrix = translateMatrixOperation( $x, $y, $z, @matrix );
sub translateMatrixOperation {
my ($x, $y, $z, @coord) = @_;
# This is here in case you give it an array reference like you did before.
# It is quite fragile, you should remove it if you don't need it.
if( 1
and @coord == 1
and ref( my $aref = $coord[0] ) eq 'ARRAY'
and ref($aref->[0]) eq 'ARRAY'
){
@coord = @$aref;
}
# create a new list
my @return = map{
# of a new array refs based on the old ones
[ $_->[0] - $x, $_->[1] - $y, $_->[2] - $z, @$_[3..$#$_] ]
# the @$_[3..$#$_] part may be unnecessary
# it should be removed if that is the case
} @coord;
return @return if wantarray;
return \@return;
}
如果您删除我认为不需要的部件,则会很短暂
my $tempMatrix = translateMatrixOperation( $x, $y, $z, @matrix );
sub translateMatrixOperation {
my ($x, $y, $z, @coords) = @_;
my @return = map{
[ $_->[0] - $x, $_->[1] - $y, $_->[2] - $z ]
} @coords;
return @return if wantarray;
return \@return;
}
您还应该找出一个更好的名称,translateMatrixOperation
不是很具描述性。