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
@@ -0,0 +1,116 @@
{ "type": "FeatureCollection", "properties": {
"bounds": "174.721517,-37.166211,174.721564,-37.166209",
"center": "174.721541,-37.166211,22",
"description": "tests/single-polygons/out/-Z21_-zg_-D10_-d10.json.check.mbtiles",
"format": "pbf",
"generator_options": "./tippecanoe -q -a@ -f -o tests/single-polygons/out/-Z21_-zg_-D10_-d10.json.check.mbtiles -Z21 -zg -D10 -d10 tests/single-polygons/in.json",
"json": "{\"vector_layers\": [ { \"id\": \"in\", \"description\": \"\", \"minzoom\": 21, \"maxzoom\": 22, \"fields\": {\"seq\": \"Number\"} } ],\"tilestats\": {\"layerCount\": 1,\"layers\": [{\"layer\": \"in\",\"count\": 30,\"geometry\": \"Polygon\",\"attributeCount\": 1,\"attributes\": [{\"attribute\": \"seq\",\"count\": 30,\"type\": \"number\",\"values\": [10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,6,7,8,9],\"min\": 6,\"max\": 35}]}]}}",
"maxzoom": "22",
"minzoom": "21",
"name": "tests/single-polygons/out/-Z21_-zg_-D10_-d10.json.check.mbtiles",
"strategies": "[ { }, { }, { }, { }, { }, { }, { }, { }, { }, { }, { }, { }, { }, { }, { }, { }, { }, { }, { }, { }, { }, { \"tiny_polygons\": 27 }, { \"tiny_polygons\": 1 } ]",
"type": "overlay",
"version": "2"
}, "features": [
{ "type": "FeatureCollection", "properties": { "zoom": 21, "x": 2066402, "y": 1282091 }, "features": [
{ "type": "FeatureCollection", "properties": { "layer": "in", "version": 2, "extent": 1024 }, "features": [
{ "type": "Feature", "properties": { "seq": 8 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 174.721518, -37.166209 ], [ 174.721518, -37.166210 ], [ 174.721518, -37.166210 ], [ 174.721518, -37.166209 ], [ 174.721518, -37.166209 ] ] ] } }
,
{ "type": "Feature", "properties": { "seq": 9 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 174.721519, -37.166209 ], [ 174.721519, -37.166210 ], [ 174.721519, -37.166210 ], [ 174.721519, -37.166209 ], [ 174.721519, -37.166209 ] ] ] } }
,
{ "type": "Feature", "properties": { "seq": 10 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 174.721520, -37.166209 ], [ 174.721520, -37.166210 ], [ 174.721520, -37.166210 ], [ 174.721520, -37.166209 ], [ 174.721520, -37.166209 ] ] ] } }
,
{ "type": "Feature", "properties": { "seq": 12 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 174.721522, -37.166209 ], [ 174.721522, -37.166210 ], [ 174.721521, -37.166210 ], [ 174.721521, -37.166209 ], [ 174.721522, -37.166209 ] ] ] } }
,
{ "type": "Feature", "properties": { "seq": 15 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 174.721525, -37.166209 ], [ 174.721525, -37.166210 ], [ 174.721525, -37.166210 ], [ 174.721525, -37.166209 ], [ 174.721525, -37.166209 ] ] ] } }
,
{ "type": "Feature", "properties": { "seq": 17 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 174.721527, -37.166209 ], [ 174.721527, -37.166210 ], [ 174.721526, -37.166210 ], [ 174.721526, -37.166209 ], [ 174.721527, -37.166209 ] ] ] } }
,
{ "type": "Feature", "properties": { "seq": 18 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 174.721533, -37.166210 ], [ 174.721533, -37.166210 ], [ 174.721533, -37.166210 ], [ 174.721533, -37.166210 ], [ 174.721533, -37.166210 ] ] ] } }
,
{ "type": "Feature", "properties": { "seq": 20 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 174.721536, -37.166210 ], [ 174.721536, -37.166210 ], [ 174.721536, -37.166210 ], [ 174.721536, -37.166210 ], [ 174.721536, -37.166210 ] ] ] } }
,
{ "type": "Feature", "properties": { "seq": 22 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 174.721540, -37.166210 ], [ 174.721540, -37.166210 ], [ 174.721540, -37.166210 ], [ 174.721540, -37.166210 ], [ 174.721540, -37.166210 ] ] ] } }
,
{ "type": "Feature", "properties": { "seq": 24 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 174.721542, -37.166210 ], [ 174.721542, -37.166210 ], [ 174.721542, -37.166210 ], [ 174.721542, -37.166210 ], [ 174.721542, -37.166210 ] ] ] } }
,
{ "type": "Feature", "properties": { "seq": 25 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 174.721544, -37.166210 ], [ 174.721544, -37.166210 ], [ 174.721543, -37.166210 ], [ 174.721544, -37.166210 ] ] ] } }
,
{ "type": "Feature", "properties": { "seq": 26 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 174.721545, -37.166210 ], [ 174.721545, -37.166210 ], [ 174.721544, -37.166210 ], [ 174.721544, -37.166210 ], [ 174.721545, -37.166210 ] ] ] } }
,
{ "type": "Feature", "properties": { "seq": 27 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 174.721546, -37.166210 ], [ 174.721546, -37.166211 ], [ 174.721546, -37.166210 ], [ 174.721546, -37.166210 ], [ 174.721546, -37.166210 ] ] ] } }
,
{ "type": "Feature", "properties": { "seq": 29 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 174.721549, -37.166210 ], [ 174.721549, -37.166210 ], [ 174.721548, -37.166210 ], [ 174.721548, -37.166210 ], [ 174.721549, -37.166210 ] ] ] } }
,
{ "type": "Feature", "properties": { "seq": 30 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 174.721549, -37.166210 ], [ 174.721549, -37.166210 ], [ 174.721549, -37.166210 ], [ 174.721549, -37.166210 ], [ 174.721549, -37.166210 ] ] ] } }
,
{ "type": "Feature", "properties": { "seq": 32 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 174.721557, -37.166210 ], [ 174.721557, -37.166211 ], [ 174.721556, -37.166211 ], [ 174.721556, -37.166210 ], [ 174.721557, -37.166210 ] ] ] } }
,
{ "type": "Feature", "properties": { "seq": 34 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 174.721559, -37.166210 ], [ 174.721559, -37.166211 ], [ 174.721559, -37.166211 ], [ 174.721559, -37.166210 ], [ 174.721559, -37.166210 ] ] ] } }
,
{ "type": "Feature", "properties": { "seq": 35 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 174.721564, -37.166210 ], [ 174.721564, -37.166210 ], [ 174.721564, -37.166210 ], [ 174.721564, -37.166210 ], [ 174.721564, -37.166210 ] ] ] } }
] }
] }
,
{ "type": "FeatureCollection", "properties": { "zoom": 22, "x": 4132805, "y": 2564182 }, "features": [
{ "type": "FeatureCollection", "properties": { "layer": "in", "version": 2, "extent": 1024 }, "features": [
{ "type": "Feature", "properties": { "seq": 6 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 174.721517, -37.166209 ], [ 174.721517, -37.166210 ], [ 174.721517, -37.166210 ], [ 174.721517, -37.166209 ], [ 174.721517, -37.166209 ] ] ] } }
,
{ "type": "Feature", "properties": { "seq": 7 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 174.721518, -37.166209 ], [ 174.721518, -37.166210 ], [ 174.721518, -37.166210 ], [ 174.721518, -37.166209 ], [ 174.721518, -37.166209 ] ] ] } }
,
{ "type": "Feature", "properties": { "seq": 8 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 174.721519, -37.166209 ], [ 174.721519, -37.166210 ], [ 174.721518, -37.166210 ], [ 174.721518, -37.166209 ], [ 174.721519, -37.166209 ] ] ] } }
,
{ "type": "Feature", "properties": { "seq": 9 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 174.721520, -37.166210 ], [ 174.721520, -37.166210 ], [ 174.721520, -37.166210 ], [ 174.721519, -37.166210 ], [ 174.721520, -37.166210 ] ] ] } }
,
{ "type": "Feature", "properties": { "seq": 11 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 174.721521, -37.166210 ], [ 174.721521, -37.166210 ], [ 174.721521, -37.166210 ], [ 174.721521, -37.166210 ], [ 174.721521, -37.166210 ] ] ] } }
,
{ "type": "Feature", "properties": { "seq": 10 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 174.721520, -37.166210 ], [ 174.721520, -37.166210 ], [ 174.721520, -37.166210 ], [ 174.721520, -37.166210 ], [ 174.721520, -37.166210 ] ] ] } }
,
{ "type": "Feature", "properties": { "seq": 12 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 174.721522, -37.166210 ], [ 174.721522, -37.166210 ], [ 174.721521, -37.166210 ], [ 174.721521, -37.166210 ], [ 174.721522, -37.166210 ] ] ] } }
,
{ "type": "Feature", "properties": { "seq": 13 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 174.721524, -37.166210 ], [ 174.721524, -37.166210 ], [ 174.721524, -37.166210 ], [ 174.721523, -37.166210 ], [ 174.721524, -37.166210 ] ] ] } }
,
{ "type": "Feature", "properties": { "seq": 14 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 174.721524, -37.166210 ], [ 174.721524, -37.166210 ], [ 174.721524, -37.166210 ], [ 174.721524, -37.166210 ] ] ] } }
,
{ "type": "Feature", "properties": { "seq": 16 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 174.721526, -37.166210 ], [ 174.721526, -37.166210 ], [ 174.721526, -37.166210 ], [ 174.721526, -37.166210 ], [ 174.721526, -37.166210 ] ] ] } }
,
{ "type": "Feature", "properties": { "seq": 17 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 174.721527, -37.166210 ], [ 174.721527, -37.166210 ], [ 174.721527, -37.166210 ], [ 174.721527, -37.166210 ], [ 174.721527, -37.166210 ] ] ] } }
,
{ "type": "Feature", "properties": { "seq": 18 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 174.721534, -37.166210 ], [ 174.721534, -37.166210 ], [ 174.721533, -37.166210 ], [ 174.721533, -37.166210 ], [ 174.721534, -37.166210 ] ] ] } }
,
{ "type": "Feature", "properties": { "seq": 19 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 174.721535, -37.166210 ], [ 174.721535, -37.166210 ], [ 174.721535, -37.166210 ], [ 174.721535, -37.166210 ], [ 174.721535, -37.166210 ] ] ] } }
,
{ "type": "Feature", "properties": { "seq": 20 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 174.721537, -37.166210 ], [ 174.721537, -37.166210 ], [ 174.721536, -37.166210 ], [ 174.721536, -37.166210 ], [ 174.721537, -37.166210 ] ] ] } }
,
{ "type": "Feature", "properties": { "seq": 21 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 174.721538, -37.166210 ], [ 174.721538, -37.166210 ], [ 174.721538, -37.166210 ], [ 174.721538, -37.166210 ], [ 174.721538, -37.166210 ] ] ] } }
,
{ "type": "Feature", "properties": { "seq": 22 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 174.721540, -37.166210 ], [ 174.721540, -37.166210 ], [ 174.721540, -37.166210 ], [ 174.721540, -37.166210 ], [ 174.721540, -37.166210 ] ] ] } }
,
{ "type": "Feature", "properties": { "seq": 23 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 174.721541, -37.166210 ], [ 174.721541, -37.166210 ], [ 174.721541, -37.166210 ], [ 174.721541, -37.166210 ], [ 174.721541, -37.166210 ] ] ] } }
,
{ "type": "Feature", "properties": { "seq": 24 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 174.721542, -37.166210 ], [ 174.721542, -37.166210 ], [ 174.721542, -37.166210 ], [ 174.721542, -37.166210 ] ] ] } }
,
{ "type": "Feature", "properties": { "seq": 25 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 174.721544, -37.166210 ], [ 174.721544, -37.166210 ], [ 174.721544, -37.166210 ], [ 174.721544, -37.166210 ], [ 174.721544, -37.166210 ], [ 174.721543, -37.166210 ], [ 174.721543, -37.166210 ], [ 174.721544, -37.166210 ] ] ] } }
,
{ "type": "Feature", "properties": { "seq": 26 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 174.721545, -37.166210 ], [ 174.721545, -37.166210 ], [ 174.721545, -37.166210 ], [ 174.721545, -37.166210 ], [ 174.721545, -37.166210 ] ] ] } }
,
{ "type": "Feature", "properties": { "seq": 27 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 174.721546, -37.166210 ], [ 174.721546, -37.166211 ], [ 174.721546, -37.166210 ], [ 174.721546, -37.166210 ], [ 174.721546, -37.166210 ] ] ] } }
,
{ "type": "Feature", "properties": { "seq": 28 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 174.721547, -37.166210 ], [ 174.721547, -37.166210 ], [ 174.721547, -37.166210 ], [ 174.721547, -37.166210 ], [ 174.721547, -37.166210 ] ] ] } }
,
{ "type": "Feature", "properties": { "seq": 29 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 174.721549, -37.166210 ], [ 174.721549, -37.166210 ], [ 174.721548, -37.166210 ], [ 174.721548, -37.166210 ], [ 174.721549, -37.166210 ] ] ] } }
,
{ "type": "Feature", "properties": { "seq": 30 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 174.721549, -37.166210 ], [ 174.721549, -37.166210 ], [ 174.721549, -37.166210 ], [ 174.721549, -37.166210 ], [ 174.721549, -37.166210 ] ] ] } }
,
{ "type": "Feature", "properties": { "seq": 31 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 174.721556, -37.166210 ], [ 174.721556, -37.166210 ], [ 174.721556, -37.166210 ], [ 174.721556, -37.166210 ], [ 174.721556, -37.166210 ] ] ] } }
,
{ "type": "Feature", "properties": { "seq": 32 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 174.721557, -37.166210 ], [ 174.721557, -37.166210 ], [ 174.721557, -37.166210 ], [ 174.721557, -37.166210 ], [ 174.721557, -37.166210 ] ] ] } }
,
{ "type": "Feature", "properties": { "seq": 33 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 174.721559, -37.166210 ], [ 174.721559, -37.166210 ], [ 174.721558, -37.166210 ], [ 174.721558, -37.166210 ], [ 174.721559, -37.166210 ] ] ] } }
,
{ "type": "Feature", "properties": { "seq": 34 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 174.721559, -37.166210 ], [ 174.721559, -37.166211 ], [ 174.721559, -37.166211 ], [ 174.721559, -37.166210 ], [ 174.721559, -37.166210 ], [ 174.721559, -37.166210 ] ] ] } }
,
{ "type": "Feature", "properties": { "seq": 35 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 174.721564, -37.166210 ], [ 174.721564, -37.166210 ], [ 174.721564, -37.166211 ], [ 174.721564, -37.166211 ], [ 174.721564, -37.166210 ] ] ] } }
] }
] }
] }