I've written an algorithm that finds the intersection of two lines. I am desperately trying to pass scalar values as arguments to this subroutine from a hash of arrays. Each array contains vertices for a four-sided polygon.
Here's what I got:
$myPolygons = "<tag> <name>A</name> <points>-1.1,2,0 -3.1,4,0 -5.1,6,0 -7.1,8,0 1,2,0</points> <name>C</name> <points>9,-8.1,0 7,-6.1,0 5,-4.1,0 3,-2.1,0 9,-8.1,0</points> </tag>"; while ($myFile =~ m{<tag>(.*?)</tag>}gs) { $tag = $1; if ($tag =~ m{<name>(.*?)</name>}gs) { $name = $1; if ($tag =~ m{<points>(.*)</points>}g) { $points = $1; while ($points =~ m{\G(-?\d*\.?\d*),0*\s*}gs) { push @{$points_by_name{$name}}, $1; } } } }
Each hash key has values in the form of an array reference which stores the associated numbers. Each element contains a single value and the zeros were omitted. I would like to pass these values to the subroutine that accepts eight scalars, each of which are the endpoints of the two lines that are being evaluated.
@_ = ($x0, $y0, $x1, $y1, $x2, $y2, $x3, $y3)
However, in order for the subroutine to work correctly, it can only accept the first four values from this hash:
$x0, $y0, $x1, $y1
How do I step through the first hash, passing only four values from each key at a time? In other words, the following will be passed as arguments to the subroutine:
@{$points_by_name{$key}}[0..3]; @{$points_by_name{$key}}[2..5]; @{$points_by_name{$key}}[4..7]; @{$points_by_name{$key}}[6..9];
...until all the values from the current key have been passed, then on to the next key's array; these values will advance by two until the end of each array that is associated with each key. This is my best attempt:
foreach my $key (keys %points_by_name) { foreach (@{$points_by_name{$key}} { for (my $i=0; $i<=$#{$points_by_name{$key}} $i+=2) { sub(@{$points_by_name{$key}}[$i..$i+3], $x2, $y2, $x3, $y3 +) } } }
Additionally, the last four arguments of the subroutine will be passed from a seperate, but similar hash as the one used above. In order to find an intersection of lines, the first four arguments from the hash above must be measured against ALL values in the other hash's arrays before the first four values may advance to the next two pairs from within each array.
The "other hash" should push its arguments something like the following:
foreach my $key (keys %other_hash) { foreach (@{$other_hash{$key}} { for (my $i=0; $i<=$#{$points_by_name{$key}} $i+=2) { my @temp = @{$other_hash{$key}}[$i..$i+3] foreach (@temp) { sub($x0, $y0, $x1, $y1, @temp) } } } }
The only problem with these approaches (aside from the obvious) is that there is no way to keep track of what key is being evaluated (...I think). The ingestion of the first and last four arguments must start and stop as each key's arrays begin and end. Otherwise, a line will be drawn from the last two points to the first two points of each array.
Any help would be greatly appreciated :)
In reply to Subroutine Subtrefuge by AF_One
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |