Patch to speed synopsis example execution time from 2.6 to 0.8s. Can't deny you the pleasure to replace third loop yourself, similarly to 1st and 2nd loops. Accidentally, that fragment (3d loop) isn't run with DateTime picked for synopsis, btw.
--- WorldMap.pm.old Fri Jun 17 10:33:43 2016
+++ WorldMap.pm Tue Dec 13 10:27:14 2022
@@ -501,6 +501,7 @@
my $illumMap = Imager->new(ysize => $height, xsize => $width);
$illumMap = $illumMap->convert(preset => 'addalpha');
my $day = Imager::Color->new(255, 255, 255, 10);
+ my $day_p = pack 'C4', 255, 255, 255, 10;
my ($i, $j, $oh, $nl, $nh);
for ($i = 0; $i < $height; $i++) {
@@ -510,12 +511,10 @@
$oh = ($nh - $nl) + 1;
if (($nl + $oh) > $width) {
- for ($j = $nl; $j < $width; $j++) {
- $illumMap->setpixel(x => $j, y => $i, color => $d
+ay);
- }
- for ($j = 0; $j < ((($nl + $oh) - $width) + 1); $j++)
+ {
- $illumMap->setpixel(x => $j, y => $i, color => $d
+ay);
- }
+ $illumMap->setscanline(x => $nl, y => $i,
+ pixels => $day_p x ($width - $nl - 1));
+ $illumMap->setscanline(x => 0, y => $i,
+ pixels => $day_p x ($nl + $oh - $width));
} else {
for ($j = $nl; $j < (($nl + $oh) + 1); $j++) {
$illumMap->setpixel(x => $j, y => $i, color => $d
+ay);
| [reply] [d/l] |
> Patch to speed synopsis example execution time from 2.6 to 0.8s.
Design flaw indeed. My app does a few other things and was taking nearly
5 seconds, without the Imager hacks. Your technique brings it down to the
0.8s range. This is astonishing! Feels almost instant, except in that third loop, thank you.
> Can't deny you the pleasure to replace third loop yourself, similarly to 1st and 2nd loops.
I barely grasp the original code, scanline is over my head for the time being,
can you help an anonymonk out? This seemed logicalish from the third loop variables
but didn't do enough, or did too much, not that I even know why:
$illumMap->setscanline(x => $nl, y => $i, pixels => $day_p x ($nl + $o
+h));
> Accidentally, that fragment (3d loop) isn't run with DateTime picked for synopsis, btw.
What does that mean? Thanks for your help. It's so much faster 5-6x unbelievable!
Finally, to maximize enjoyment, Ham::Locator transforms latitude and longitude to pixel cooordinates or dots on the Ham::WorldMap:
use Ham::Locator;
use Ham::WorldMap;
my $lat = 40.712778;
my $lon = -74.006111;
my $png = 'worldmap.png';
my $map = Ham::WorldMap->new;
my $loc = Ham::Locator->new;
$loc->set_latlng($lat,$lon);
$map->dotAtLocator($loc->latlng2loc, 12, Imager::Color->new(0,255,0));
$map->drawNightRegions(DateTime->now);
my ($x, $y) = $map->locatorToXY($loc->latlng2loc);
$map->write($png) or die $map->errstr;
print qq[Dot drawn at $x,$y on $png\n];
| [reply] [d/l] [select] |
What does that mean?
Code fragment is only reached if illuminated interval at particular latitude doesn't cross map border. Won't happen at 12 GMT. It also means replacing that loop won't affect time I posted because of 12 GMT chosen for a test.
Looks like I robbed humanity of 45s (24 hours / 1920) of their precious daytime, off by 1 error in patch above. Fixed below.
I also came to significantly faster solution, but have to decide what to do with rounding errors and glitches which are possible very close to equinoxes with maths as implemented in this module. Unseen possible stray pixel with current solution, but unacceptable if polygon lines jump from pole to pole for daytime illumination area. May lead to a few heart attacks among astronomers or geographers etc. But absolutely don't wont to re-do all trigonometry from scratch, need more time for a hack which would seem reliable enough.
--- WorldMap.pm.old Fri Jun 17 10:33:43 2016
+++ WorldMap.pm Wed Dec 14 12:18:17 2022
@@ -500,7 +500,7 @@
my ($wtab, $noon, $width, $height) = @_;
my $illumMap = Imager->new(ysize => $height, xsize => $width);
$illumMap = $illumMap->convert(preset => 'addalpha');
- my $day = Imager::Color->new(255, 255, 255, 10);
+ my $day_p = pack 'C4', 255, 255, 255, 10;
my ($i, $j, $oh, $nl, $nh);
for ($i = 0; $i < $height; $i++) {
@@ -510,16 +510,13 @@
$oh = ($nh - $nl) + 1;
if (($nl + $oh) > $width) {
- for ($j = $nl; $j < $width; $j++) {
- $illumMap->setpixel(x => $j, y => $i, color => $d
+ay);
- }
- for ($j = 0; $j < ((($nl + $oh) - $width) + 1); $j++)
+ {
- $illumMap->setpixel(x => $j, y => $i, color => $d
+ay);
- }
+ $illumMap->setscanline(x => $nl, y => $i,
+ pixels => $day_p x ($width - $nl));
+ $illumMap->setscanline(x => 0, y => $i,
+ pixels => $day_p x ($nl + $oh - $width + 1));
} else {
- for ($j = $nl; $j < (($nl + $oh) + 1); $j++) {
- $illumMap->setpixel(x => $j, y => $i, color => $d
+ay);
- }
+ $illumMap->setscanline(x => $nl, y => $i,
+ pixels => $day_p x ($oh + 1));
}
}
}
| [reply] [d/l] |