在{/}的除法中使用未初始化的值$ d

时间:2019-03-19 09:27:30

标签: perl

因此,我已经完成了一些谷歌搜索和其他工作,我的控制台充满了所有这些警告。只是有点不确定如何整体解决此方法。同样,我希望我的代码不会模糊,因为我不太确定这里的代码是否足够。不管这里是问题。一段时间以来,我一直在尝试将Perl脚本集成到我的模块中。脚本本身可以工作,但不能在模块中工作。当我尝试运行它时,错误消息是这种方法:

 sub generate_pillars_shape{
    my $d=$_[4];
    @X_values=$_[0]/$d..$_[1]/$d;
    @X_values=map{$_*$d} @X_values;
    @Y_values=$_[2]/$d..$_[3]/$d;
    @Y_values=map{$_*$d} @Y_values;
    for $i (0..$#X_values){
    @Y=(@Y,@Y_values);
    for $j (0..$#Y_values){
        $X[$i*($#Y_values+1)+$j]= $X_values[$i];
    }
    }
    return (\@X,\@Y);
}

整个代码包含以下内容:

use 5.010;
use Math::Trig ':radial';
use Math::Trig;
use List::Util qw(max min);

my $min_X=0;
my $max_X=60;
my $min_Y=0;
my $max_Y=60;
my $distance=10;
my @X_values;
my @Y_values;
my $i;
my $j;

#The minimum angle from horizontl your printer can make, in degrees
my $min_angle= 30;

#Ignore the next line, it is not an input parame
my @Z;
my ($X_ref,$Y_ref)= generate_pillars_shape($min_X,$max_X,$min_Y,$max_Y,$distance);my @X=@$X_ref;my @Y=@{$Y_ref};
for my $i (0..$#X){
    $Z[$i]=20;#The function that defined the height of each point. This setting wil give you a flat roof. For a more advanced tree, try:
    #$Z[$i]=-0.01*$X[$i]**2+0.2*$Y[$i]-0.005*$Y[$i]**2+20;
}

#End of input parameters.

my $min_radian = deg2rad($min_angle);
my $b = tan($min_radian);
@Z=map{$_/$b} @Z;



while ($#X>0){
  my ($I,$J)=find_min_dist(\@X,\@Y,\@Z);
  my ($X_branch,$Y_branch,$Z_branch)=find_branch($X[$I],$Y[$I],$Z[$I],$X[$J],$Y[$J],$Z[$J]);
  my @X_list= ($X_branch,$X[$I],$X[$J]);
  my @Y_list= ($Y_branch,$Y[$I],$Y[$J]);
  my @Z_list= ($Z_branch,$Z[$I],$Z[$J]);
  for my $j (0..$#Y_list){
      if (abs($X_list[my $j]) < 0.001){
      $X_list[$j]=0;
      }
      if (abs($Y_list[my $j]) < 0.001){
      $Y_list[$j]=0;
      }
      if (abs($Z_list[my $j]) < 0.001){
      $Z_list[$J]=0;
      }
  }
  branch (\@X_list,\@Y_list,\@Z_list);
  splice (@X,$I,1,$X_branch);
  splice (@X,$J,1);
  splice (@Y,$I,1,$Y_branch);
  splice (@Y,$J,1);
  splice (@Z,$I,1,$Z_branch);
  splice (@Z,$J,1);
}

sub generate_pillars_shape{
    my $d=$_[4];
    @X_values=$_[0]/$d..$_[1]/$d;
    @X_values=map{$_*$d} @X_values;
    @Y_values=$_[2]/$d..$_[3]/$d;
    @Y_values=map{$_*$d} @Y_values;
    for $i (0..$#X_values){
    @Y=(@Y,@Y_values);
    for $j (0..$#Y_values){
        $X[$i*($#Y_values+1)+$j]= $X_values[$i];
    }
    }
    return (\@X,\@Y);
}

sub branch{
  my @X=@{ $_[0] };
  my @Y=@{ $_[1] };
  my @Z=@{ $_[2] };
  @Z=map{$_*$b}@Z;
  for my $i (1..$#X){
    my ($rho, $theta, $phi) = cartesian_to_spherical($X[$i]-$X[0],$Y[$i]-$Y[0],$Z[$i]-$Z[0]);
    $phi = rad2deg($phi);
    if (abs($phi)<0.001){$phi=0;}
    $theta = rad2deg($theta)+90;
    if (abs($theta)<0.001){$theta=0;}
    if (abs($rho)>0.001){}
  }
}

sub find_min_dist{
  my @X=@{ $_[0] };
  my @Y=@{ $_[1] };
  my @Z=@{ $_[2] };
  my $min_dist=($X[0]-$X[1])**2+($Y[0]-$Y[1])**2+($Z[0]-$Z[1])**2;
  my $max_Z=$Z[0];
  my $I=0;
  my $J=1;
  for my $i (1..$#Z){
      if ($Z[$i]>=$max_Z){
      $max_Z=$Z[$i];
      my $I=$i;}
  }
  for my $j (0..$#X){
    if ($j!=$I){
      my $dist=(($X[$I]-$X[$j])**2+($Y[$I]-$Y[$j])**2+($Z[$I]-$Z[$j])**2);
      if ($min_dist>$dist){
    $min_dist=$dist;
    my $J=$j;
      }}}
  return ($I,$J);
}

sub find_branch{
  my $X1=$_[0];
  my $Y1=$_[1];
  my $Z1=$_[2];
  my $X2=$_[3];
  my $Y2=$_[4];
  my $Z2=$_[5];
  my $rXY=sqrt(($X1-$X2)**2+($Y1-$Y2)**2);
  if (abs($Z1-$Z2) < $rXY) {
    my $Z_branch=($Z1+$Z2-$rXY)/2;
    my $a=($Z1-$Z_branch)/$rXY;
    my $X_branch=(1-$a)*$X1+$a*$X2;
    my $Y_branch=(1-$a)*$Y1+$a*$Y2;
  }
  elsif ($Z1 < $Z2) {
    my $X_branch=$X1;
    my $Y_branch=$Y1;
    my $Z_branch=$Z1;
  }
  else {
    my $X_branch=$X2;
    my $Y_branch=$Y2;
    my $Z_branch=$Z2;
  }
  return my($X_branch,$Y_branch,$Z_branch);
}

我希望能解释大致情况,希望能对您有所帮助。谢谢。

1 个答案:

答案 0 :(得分:5)

我无法重现您的错误。但是,您的代码中有很多错误,因此让我仔细研究一下,希望可以帮助您找到实际的错误。

首先,应在尽可能小的范围内定义变量:如果仅在函数内使用变量,则应在此函数内定义变量。如果变量仅在for循环中使用,则应在此循环中定义它。本着这种精神,您应该删除

my $i;
my $j;
在代码开头的

。另外,请记住,my声明了仅在当前作用域中可见的词法变量(,您只能在当前块中使用它)。例如,

else {
    my $X_branch=$X2;
    my $Y_branch=$Y2;
    my $Z_branch=$Z2;
}

声明在else块之后不存在的3个变量。

第二,my声明一个 new 变量,因此每个变量只能使用一次。如果你写

my $x = 5;
return my $x;

第一行声明一个变量$x,并将其设置为5。第二行声明一个新变量$x(因此遮盖了旧变量),其值是undef,并返回它。您要写的是:

my $x = 5;
return $x;

现在,让我浏览您的代码以指出一些错误/改进之处:

  • $X_list[my $j]应该为$X_list[$j](根据此答案的开头)。

  • find_branch中,您定义的变量范围存在问题(请参阅我的答案的开头)。您应该有类似的内容:

    my ($X_branch, $Y_branch, $Z_branch);
    if (abs($Z1-$Z2) < $rXY) {
        $Z_branch=($Z1+$Z2-$rXY)/2;
        my $a=($Z1-$Z_branch)/$rXY;
        $X_branch=(1-$a)*$X1+$a*$X2;
        $Y_branch=(1-$a)*$Y1+$a*$Y2;
    }
    elsif ($Z1 < $Z2) {
        $X_branch=$X1;
        $Y_branch=$Y1;
        $Z_branch=$Z1;
    }
    else {
        $X_branch=$X2;
        $Y_branch=$Y2;
        $Z_branch=$Z2;
    }
    return ($X_branch,$Y_branch,$Z_branch);
    

    这两个更正应使所有警告均消失。但是,我怀疑您的代码中还有更多出错的地方。

  • find_min_dist中,您不应写my $I = $imy $J = $j,而应写$I = $i$J = $j(仍然是相同的范围界定问题)。 / p>

  • 您的子branch不会执行任何操作:您计算了$rho$theta$phi,但是您没有返回它们(并且您也不要修改参数。)

  • generate_pillars_shape@X_values@Y_values@X@Y中,应全部用my声明。另外,您可以使用@X_values初始化@X_values = grep { $_ % $d == 0 } $_[0] .. $_[1](与@Y_values相同),我发现它比您编写的内容更具可读性。

  • 您应该将代码放入函数或代码块({ ... })中,以使用适当的作用域:尽管$min_X$max_X,{{1 }},$min_Y$max_Y作为全局变量,您绝对不希望在文件的任何地方都定义$distance$min_radian

  • 不要使用$b$a(它们是$b使用的特殊变量;您不想弄乱它们(请参阅{{3} }))。

  • 另外,为了清楚起见,在子sort中,您可以更紧凑地检索参数:

    find_branch

我非常相信您的代码还有其他问题。如果需要更多帮助,请告诉我们您正在尝试做什么以及每个功能应该做什么。