Improve precision of polygon area calculations (#19)

* Improve precision of get_area by using long double

* Trying to get consistent polygon area results between ARM and x86

* Calculate polygon area closer to the origin for better precision

* Update changelog

* Also exercise tiny polygon dust in the ring area test

They previously behaved differently here between x86 and ARM

* On M1 Macs, long double is just double anyway, so don't use it

* Be more careful about overflow: scale the polygon ring down into range

* Fix the bug I just introduced in the scaled area calculation

* Use only the sign from the scaled-down area calculation

Co-authored-by: Roman Karavia <47303530+romankaravia@users.noreply.github.com>
This commit is contained in:
Erica Fischer
2022-10-04 10:04:34 -07:00
committed by GitHub
co-authored by Roman Karavia
parent a6abb0bc30
commit 182093bdc7
9 changed files with 239 additions and 14 deletions
+3 -3
View File
@@ -2289,7 +2289,7 @@ int read_input(std::vector<source> &sources, char *fname, int maxzoom, int minzo
if (maxzoom == 0) {
droprate = 2.5;
} else {
droprate = exp(log((long double) max[0].count / max[maxzoom].count) / (maxzoom));
droprate = exp(log((double) max[0].count / max[maxzoom].count) / (maxzoom));
if (!quiet) {
fprintf(stderr, "Choosing a drop rate of -r%f to get from %lld to %lld in %d zooms\n", droprate, max[maxzoom].count, max[0].count, maxzoom);
}
@@ -2298,7 +2298,7 @@ int read_input(std::vector<source> &sources, char *fname, int maxzoom, int minzo
basezoom = 0;
for (z = 0; z <= maxzoom; z++) {
double zoomdiff = log((long double) max[z].count / max_features) / log(droprate);
double zoomdiff = log((double) max[z].count / max_features) / log(droprate);
if (zoomdiff + z > basezoom) {
basezoom = ceil(zoomdiff + z);
}
@@ -2314,7 +2314,7 @@ int read_input(std::vector<source> &sources, char *fname, int maxzoom, int minzo
double interval = exp(log(droprate) * (basezoom - z));
if (max[z].count / interval >= max_features) {
interval = (long double) max[z].count / max_features;
interval = (double) max[z].count / max_features;
droprate = exp(log(interval) / (basezoom - z));
interval = exp(log(droprate) * (basezoom - z));