Search code examples
perlcountgridcellrepeat

Count number of times an item is placed within a cell


I am randomly populating a grid where the cartesian coordinates are normalized from 0 to 100 (100x100x100 grid) and the "intensity" of each data point within is normalized from 0 to 256. Here is an excerpt from my code in perl:

open(FILE,$file);
while(sysread(FILE,$data,16)) {
    @row=unpack("f>4",$data);   # input file is binary so I had to convert here
    $x=int((($row[0] - $xmin)/($xmax - $xmin)*10) + 0.5); # max and min variables
    $y=int((($row[1] - $ymin)/($ymax - $ymin)*10) + 0.5); # are previously defined
    $z=int((($row[2] - $zmin)/($zmax - $zmin)*10) + 0.5);
    $i=int(($row[3]/62*256) + 0.5);
    $i=255 if ($i>255);

    $out[$x][$y][$z]=$i;   # simply assigns an intensity for each data
                           # point (in random order), only 1 point can be
                           # added to each 1x1x1 cell
}

Some points are too close together and are being placed in the same 1x1x1 cell. When this happens, each intensity added overwrites the previous one. How can I count the number of times that more than one point is placed in a cell?

Thanks in advance!


Solution

  • You can do this pretty easily with another hash, just join all of your keys ($x,$y,$z) together into a single key and set the hash value to true whenever you insert a value.

    my %visited_points; 
    
    open(FILE,$file);
    while(sysread(FILE,$data,16)) {
        @row=unpack("f>4",$data);   # input file is binary so I had to convert here
        $x=int((($row[0] - $xmin)/($xmax - $xmin)*10) + 0.5); # max and min variables
        $y=int((($row[1] - $ymin)/($ymax - $ymin)*10) + 0.5); # are
        $z=int((($row[2] - $zmin)/($zmax - $zmin)*10) + 0.5);
        $i=int(($row[3]/62*256) + 0.5);
        $i=255 if ($i>255);
    
        my $key = "$x$y$z";
        # check if something already occupies this cell
        if( exists( $visited_points{$key} ) ) {
            # take some other action
        }
    
        $out[$x][$y][$z]=$i;   # simply assigns an intensity for each data
                               # point (in random order), only 1 point can be
                               # added to each 1x1x1 cell
    
        # mark that there is something in this cell
        $visited_points{$key} = 1;
    }
    

    If you wanted to count you count easily just increment the value as well.