├── .clang-format ├── .gitignore ├── .travis.yml ├── CMakeLists.txt ├── CONTRIBUTING.md ├── LICENSE ├── Makefile ├── README.md ├── THIRD-PARTY-NOTICES ├── bench ├── benchmark_out.csv └── run.cpp ├── cmake └── mason.cmake ├── examples ├── basic.cpp ├── triangulate_geojson.cpp └── utils.hpp ├── generate-reference-triangles ├── README.md ├── index.js ├── package-lock.json └── package.json ├── include └── delaunator.hpp ├── scripts ├── format.sh └── setup.sh └── test ├── delaunator.test.cpp ├── main.test.cpp └── test-files ├── map-25p-epsg-3857.geojson ├── osm-nodes-45331-epsg-3857.geojson ├── osm-nodes-45331-triangles.json ├── playgrounds-1356-epsg-3857.geojson └── playgrounds-1356-triangles.json /.clang-format: -------------------------------------------------------------------------------- 1 | Standard: Cpp11 2 | IndentWidth: 4 3 | AccessModifierOffset: -4 4 | UseTab: Never 5 | BinPackParameters: false 6 | BinPackArguments: false 7 | AllowShortIfStatementsOnASingleLine: true 8 | AllowShortLoopsOnASingleLine: false 9 | AllowShortBlocksOnASingleLine: true 10 | AllowShortFunctionsOnASingleLine: false 11 | AllowAllParametersOfDeclarationOnNextLine: true 12 | ConstructorInitializerAllOnOneLineOrOnePerLine: true 13 | AlwaysBreakTemplateDeclarations: true 14 | NamespaceIndentation: None 15 | PointerBindsToType: true 16 | SpacesInParentheses: false 17 | BreakBeforeBraces: Attach 18 | ColumnLimit: 0 19 | Cpp11BracedListStyle: false 20 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | CMakeCache.txt 2 | CMakeFiles 3 | CMakeScripts 4 | Testing 5 | cmake_install.cmake 6 | install_manifest.txt 7 | compile_commands.json 8 | CTestTestfile.cmake 9 | .vscode 10 | cmake-build 11 | .DS_Store 12 | out 13 | node_modules 14 | mason_packages 15 | .toolchain 16 | .mason 17 | local.env 18 | xcode-project -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: generic 2 | 3 | matrix: 4 | include: 5 | # clang-format specific job 6 | - os: linux 7 | sudo: false 8 | env: CLANG_FORMAT 9 | addons: 10 | apt: 11 | sources: [ 'ubuntu-toolchain-r-test' ] 12 | packages: [ 'libstdc++6', 'libstdc++-5-dev' ] 13 | script: 14 | - make format 15 | - os: linux 16 | sudo: false 17 | env: CXX=g++-5 18 | addons: 19 | apt: 20 | sources: [ 'ubuntu-toolchain-r-test' ] 21 | packages: [ 'g++-5' ] 22 | - os: linux 23 | sudo: false 24 | env: CXX=clang++ 25 | addons: 26 | apt: 27 | sources: [ 'ubuntu-toolchain-r-test' ] 28 | packages: [ 'libstdc++6', 'libstdc++-5-dev' ] 29 | # disabled before fixing https://github.com/delfrrr/delaunator-cpp/issues/5 30 | # - os: linux 31 | # sudo: required # workaround https://github.com/mapbox/node-cpp-skel/issues/93 32 | # env: CXXFLAGS="-fsanitize=address,undefined,integer -fno-sanitize-recover=all" 33 | # addons: 34 | # apt: 35 | # sources: [ 'ubuntu-toolchain-r-test' ] 36 | # packages: [ 'libstdc++6', 'libstdc++-5-dev' ] 37 | env: 38 | global: 39 | - CMAKE_VERSION="3.8.2" 40 | 41 | install: 42 | # set up the environment by installing mason and clang++ 43 | - ./scripts/setup.sh --config local.env 44 | # put mason and clang++ on PATH 45 | - source local.env 46 | - mason install cmake ${CMAKE_VERSION} 47 | - mason link cmake ${CMAKE_VERSION} 48 | - which cmake 49 | 50 | script: 51 | - make release 52 | - make test 53 | - make clean 54 | - make debug 55 | - make test 56 | - make clean 57 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.8) 2 | project(delaunator VERSION 0.4.0) 3 | set (CMAKE_CXX_STANDARD 14) 4 | set(CMAKE_CXX_STANDARD_REQUIRED on) 5 | set(CMAKE_EXPORT_COMPILE_COMMANDS ON) 6 | 7 | include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/mason.cmake) 8 | 9 | option(WERROR "Add -Werror flag to build (turns warnings into errors)" ON) 10 | option(BENCHMARK_BIG_O "Calculate Big O in benchmark" OFF) 11 | option(BENCHMARK_100M "Run against 100M points" OFF) 12 | option(BENCHMARK_10M "Run against 100M points" OFF) 13 | 14 | # configure optimization 15 | if (CMAKE_BUILD_TYPE STREQUAL "Debug") 16 | set(OPTIMIZATION_FLAGS "-O0 -DDEBUG") 17 | message("-- Configuring debug build") 18 | else() 19 | set(OPTIMIZATION_FLAGS "-O3 -DNDEBUG") 20 | message("-- Configuring release build") 21 | endif() 22 | 23 | # Enable extra warnings to adhere to https://github.com/mapbox/cpp/issues/37 24 | set(DESIRED_WARNINGS "-Wall -Wextra -Wconversion -Wunreachable-code -Wuninitialized -pedantic-errors -Wold-style-cast -Wno-error=unused-variable -Wshadow -Wfloat-equal -Weffc++") 25 | if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang") 26 | set(DESIRED_WARNINGS "${DESIRED_WARNINGS} -Wmost") 27 | endif() 28 | 29 | # Note: -D_GLIBCXX_USE_CXX11_ABI=0 is needed to support mason packages that are precompiled libs 30 | # Currently we only depend on a header only library, but this will help avoid issues when more libs are added via mason 31 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OPTIMIZATION_FLAGS} -D_GLIBCXX_USE_CXX11_ABI=0 ${DESIRED_WARNINGS}") 32 | 33 | if (WERROR) 34 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Werror") 35 | endif() 36 | 37 | # mason_use is a mason function within the mason.cmake file and provides ready-to-go vars, like "STATIC_LIBS" and "INCLUDE_DIRS" 38 | mason_use(catch VERSION 2.4.0 HEADER_ONLY) 39 | include_directories(SYSTEM ${MASON_PACKAGE_catch_INCLUDE_DIRS}) 40 | 41 | mason_use(rapidjson VERSION 1.1.0 HEADER_ONLY) 42 | include_directories(SYSTEM ${MASON_PACKAGE_rapidjson_INCLUDE_DIRS}) 43 | 44 | mason_use(benchmark VERSION 1.2.0) 45 | include_directories(SYSTEM ${MASON_PACKAGE_benchmark_INCLUDE_DIRS}) 46 | 47 | include_directories("${PROJECT_SOURCE_DIR}/include") 48 | 49 | file(GLOB TEST_SOURCES test/*.cpp) 50 | add_executable(unit-tests ${TEST_SOURCES}) 51 | 52 | # libbenchmark.a supports threads and therefore needs pthread support 53 | find_package(Threads REQUIRED) 54 | file(GLOB BENCH_SOURCES bench/*.cpp) 55 | add_executable(bench-tests ${BENCH_SOURCES}) 56 | if(BENCHMARK_BIG_O) 57 | message("-- BENCHMARK_BIG_O=1") 58 | target_compile_definitions(bench-tests PUBLIC BENCHMARK_BIG_O=1) 59 | endif() 60 | if(BENCHMARK_100M) 61 | message("-- BENCHMARK_100M=1") 62 | target_compile_definitions(bench-tests PUBLIC BENCHMARK_100M=1) 63 | endif() 64 | if(BENCHMARK_10M) 65 | message("-- BENCHMARK_10M=1") 66 | target_compile_definitions(bench-tests PUBLIC BENCHMARK_10M=1) 67 | endif() 68 | 69 | #examples 70 | add_executable(triangulate-geojson examples/triangulate_geojson.cpp) 71 | add_executable(basic examples/basic.cpp) 72 | 73 | 74 | # link benchmark static library to the bench-tests binary so the bench tests know where to find the benchmark impl code 75 | target_link_libraries(bench-tests ${MASON_PACKAGE_benchmark_STATIC_LIBS} ${CMAKE_THREAD_LIBS_INIT}) 76 | 77 | set(CPACK_PROJECT_NAME ${PROJECT_NAME}) 78 | set(CPACK_PROJECT_VERSION ${PROJECT_VERSION}) 79 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # delaunator-cpp 2 | 3 | **c_cpp_properties.json** 4 | 5 | ``` 6 | { 7 | "configurations": [ 8 | { 9 | "name": "CPP Mac", 10 | "includePath": [ 11 | "${workspaceFolder}/**", 12 | "/usr/include/**" 13 | ], 14 | "defines": [], 15 | "macFrameworkPath": [ 16 | "/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.13.sdk/System/Library/Frameworks" 17 | ], 18 | "compilerPath": "/usr/bin/clang", 19 | "cStandard": "c11", 20 | "cppStandard": "c++14", 21 | "intelliSenseMode": "clang-x64", 22 | "compileCommands": "${workspaceFolder}/build/compile_commands.json" 23 | } 24 | ], 25 | "version": 4 26 | } 27 | ``` -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Volodymyr Bilonenko 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | 2 | # Whether to turn compiler warnings into errors 3 | export WERROR ?= true 4 | export BUILD_DIR ?= cmake-build 5 | export XCODE_PROJ_DIR ?= xcode-project 6 | 7 | default: release 8 | 9 | release: 10 | mkdir -p ./$(BUILD_DIR) && cd ./$(BUILD_DIR) && cmake ../ -DCMAKE_BUILD_TYPE=Release -DWERROR=$(WERROR) && VERBOSE=1 cmake --build . 11 | 12 | debug: 13 | mkdir -p ./$(BUILD_DIR) && cd ./$(BUILD_DIR) && cmake ../ -DCMAKE_BUILD_TYPE=Debug -DWERROR=$(WERROR) && VERBOSE=1 cmake --build . 14 | 15 | xcode: 16 | mkdir -p ./$(XCODE_PROJ_DIR) && cd ./$(XCODE_PROJ_DIR) && cmake -G Xcode ../ 17 | 18 | test: 19 | @if [ -f ./$(BUILD_DIR)/unit-tests ]; then ./$(BUILD_DIR)/unit-tests; else echo "Please run 'make release' or 'make debug' first" && exit 1; fi 20 | 21 | bench: 22 | @if [ -f ./$(BUILD_DIR)/bench-tests ]; then ./$(BUILD_DIR)/bench-tests; else echo "Please run 'make release' or 'make debug' first" && exit 1; fi 23 | 24 | tidy: 25 | @echo "not implmented" 26 | 27 | coverage: 28 | @echo "not implmented" 29 | 30 | clean: 31 | rm -rf ./$(BUILD_DIR) 32 | # remove remains from running 'make coverage' 33 | rm -f *.profraw 34 | rm -f *.profdata 35 | @echo "run 'make distclean' to also clear mason_packages, .mason, and .toolchain directories" 36 | 37 | distclean: clean 38 | rm -rf mason_packages 39 | # remove remains from running './scripts/setup.sh' 40 | rm -rf .mason 41 | rm -rf .toolchain 42 | rm -f local.env 43 | 44 | format: 45 | ./scripts/format.sh 46 | 47 | .PHONY: test bench -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # delaunator-cpp 2 | 3 | A really fast C++ library for 4 | [Delaunay triangulation](https://en.wikipedia.org/wiki/Delaunay_triangulation) of 2D points. 5 | 6 | delaunator-cpp is a C++ port from https://github.com/mapbox/delaunator a JavaScript implementation of very fast 2D Delaunay algorithm. 7 | 8 | [![Build Status](https://travis-ci.org/delfrrr/delaunator-cpp.svg?branch=master)](https://travis-ci.org/delfrrr/delaunator-cpp) 9 | [![badge](https://mapbox.s3.amazonaws.com/cpp-assets/hpp-skel-badge_blue.svg)](https://github.com/mapbox/hpp-skel) 10 | 11 | ## Features 12 | 13 | * Probably the fastest C++ open source 2D Delaunay implementation 14 | * Example showing triangulation of GeoJson points 15 | 16 | ## Usage 17 | 18 | `examples/basic.cpp` 19 | 20 | ```CPP 21 | #include 22 | #include 23 | 24 | int main() { 25 | /* x0, y0, x1, y1, ... */ 26 | std::vector coords = {-1, 1, 1, 1, 1, -1, -1, -1}; 27 | 28 | //triangulation happens here 29 | delaunator::Delaunator d(coords); 30 | 31 | for(std::size_t i = 0; i < d.triangles.size(); i+=3) { 32 | printf( 33 | "Triangle points: [[%f, %f], [%f, %f], [%f, %f]]\n", 34 | d.coords[2 * d.triangles[i]], //tx0 35 | d.coords[2 * d.triangles[i] + 1], //ty0 36 | d.coords[2 * d.triangles[i + 1]], //tx1 37 | d.coords[2 * d.triangles[i + 1] + 1],//ty1 38 | d.coords[2 * d.triangles[i + 2]], //tx2 39 | d.coords[2 * d.triangles[i + 2] + 1] //ty2 40 | ); 41 | } 42 | } 43 | ``` 44 | 45 | [See more examples here](./examples) 46 | 47 | ## Benchmarks 48 | 49 | ``` 50 | Run on (4 X 2300 MHz CPU s) 51 | 2018-09-29 09:27:28 52 | ------------------------------------------------------------ 53 | Benchmark Time CPU Iterations 54 | ------------------------------------------------------------ 55 | BM_45K_geojson_nodes 22 ms 22 ms 32 56 | BM_uniform/2000 1 ms 1 ms 982 57 | BM_uniform/100000 63 ms 62 ms 9 58 | BM_uniform/200000 140 ms 140 ms 4 59 | BM_uniform/500000 400 ms 399 ms 2 60 | BM_uniform/1000000 994 ms 993 ms 1 61 | ``` 62 | 63 | Library is ~10% faster then JS version for 1M uniform points ([details](https://github.com/delfrrr/delaunator-cpp/pull/8#issuecomment-422690056)) 64 | -------------------------------------------------------------------------------- /THIRD-PARTY-NOTICES: -------------------------------------------------------------------------------- 1 | Delaunator-cpp is a port of https://github.com/mapbox/delaunator 2 | ISC License 3 | Copyright (c) 2017, Mapbox 4 | 5 | 6 | For development purpose it uses following third parties (not required for library users) 7 | 8 | https://github.com/Tencent/rapidjson 9 | MIT License: 10 | Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. 11 | 12 | BSD License: 13 | Copyright (c) 2006-2013 Alexander Chemeris 14 | 15 | JSON License: 16 | Copyright (c) 2002 JSON.org 17 | 18 | https://github.com/louisdx/cxx-prettyprint 19 | 20 | Boost Software License 21 | Copyright Louis Delacroix 2010 - 2014. 22 | 23 | test-files/* 24 | Open Database License 25 | This is made available under the Open Database License: http://opendatacommons.org/licenses/odbl/1.0/. 26 | Any rights in individual contents of the database are licensed under the Database Contents License: http://opendatacommons.org/licenses/dbcl/1.0/ 27 | 28 | 29 | -------------------------------------------------------------------------------- /bench/benchmark_out.csv: -------------------------------------------------------------------------------- 1 | Run on (4 X 2300 MHz CPU s) 2 | 2018-09-18 07:36:59 3 | name,iterations,real_time,cpu_time,time_unit,bytes_per_second,items_per_second,label,error_occurred,error_message 4 | "BM_45K_geojson_nodes",32,22.7033,22.4578,ms,,,,, 5 | -------------------------------------------------------------------------------- /bench/run.cpp: -------------------------------------------------------------------------------- 1 | #include "../examples/utils.hpp" 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | std::vector generate_uniform(std::size_t n) { 9 | std::vector coords; 10 | coords.reserve(2 * n); 11 | std::srand(350); 12 | double norm = static_cast(RAND_MAX) / 1e3; 13 | for (size_t i = 0; i < n; i++) { 14 | coords.push_back(static_cast(std::rand()) / norm); 15 | coords.push_back(static_cast(std::rand()) / norm); 16 | } 17 | 18 | return coords; 19 | } 20 | 21 | void BM_45K_geojson_nodes(benchmark::State& state) { 22 | std::string points_str = utils::read_file("./test/test-files/osm-nodes-45331-epsg-3857.geojson"); 23 | std::vector coords = utils::get_geo_json_points(points_str); 24 | 25 | while (state.KeepRunning()) { 26 | delaunator::Delaunator delaunator(coords); 27 | } 28 | } 29 | 30 | void BM_uniform(benchmark::State& state) { 31 | std::vector coords = generate_uniform(static_cast(state.range(0))); 32 | while (state.KeepRunning()) { 33 | delaunator::Delaunator delaunator(coords); 34 | } 35 | state.SetComplexityN(state.range(0)); 36 | } 37 | 38 | BENCHMARK(BM_45K_geojson_nodes)->Unit(benchmark::kMillisecond); 39 | BENCHMARK(BM_uniform)->Arg(2000)->Arg(100000)->Arg(200000)->Arg(500000)->Arg(1000000)->Unit(benchmark::kMillisecond); 40 | 41 | #if BENCHMARK_BIG_O 42 | BENCHMARK(BM_uniform)->RangeMultiplier(2)->Range(1 << 12, 1 << 22)->Unit(benchmark::kMillisecond)->Complexity(); 43 | #endif 44 | #if BENCHMARK_10M 45 | BENCHMARK(BM_uniform)->Arg(1000000 * 10)->Unit(benchmark::kMillisecond); 46 | #endif 47 | #if BENCHMARK_100M 48 | BENCHMARK(BM_uniform)->Arg(1000000 * 100)->Unit(benchmark::kMillisecond); 49 | #endif 50 | 51 | BENCHMARK_MAIN() 52 | -------------------------------------------------------------------------------- /cmake/mason.cmake: -------------------------------------------------------------------------------- 1 | string(RANDOM LENGTH 16 MASON_INVOCATION) 2 | 3 | # Directory where Mason packages are located; typically ends with mason_packages 4 | if (NOT MASON_PACKAGE_DIR) 5 | set(MASON_PACKAGE_DIR "${CMAKE_SOURCE_DIR}/mason_packages") 6 | endif() 7 | 8 | # URL prefix of where packages are located. 9 | if (NOT MASON_REPOSITORY) 10 | set(MASON_REPOSITORY "https://mason-binaries.s3.amazonaws.com") 11 | endif() 12 | 13 | # Path to Mason executable 14 | if (NOT MASON_COMMAND) 15 | set(MASON_COMMAND "${CMAKE_SOURCE_DIR}/.mason/mason") 16 | endif() 17 | 18 | # Determine platform 19 | # we call uname -s manually here since 20 | # CMAKE_HOST_SYSTEM_NAME will not be defined before the project() call 21 | execute_process( 22 | COMMAND uname -s 23 | OUTPUT_VARIABLE UNAME_S 24 | OUTPUT_STRIP_TRAILING_WHITESPACE) 25 | 26 | if(NOT MASON_PLATFORM) 27 | if (UNAME_S STREQUAL "Darwin") 28 | set(MASON_PLATFORM "macos") 29 | else() 30 | set(MASON_PLATFORM "linux") 31 | endif() 32 | endif() 33 | 34 | 35 | # Determine platform version string 36 | if(MASON_PLATFORM STREQUAL "ios") 37 | set(MASON_PLATFORM_VERSION "8.0") # Deployment target version 38 | elseif(MASON_PLATFORM STREQUAL "android") 39 | if (ANDROID_ABI STREQUAL "armeabi") 40 | set(MASON_PLATFORM_VERSION "arm-v5-9") 41 | elseif(ANDROID_ABI STREQUAL "arm64-v8a") 42 | set(MASON_PLATFORM_VERSION "arm-v8-21") 43 | elseif(ANDROID_ABI STREQUAL "x86") 44 | set(MASON_PLATFORM_VERSION "x86-9") 45 | elseif(ANDROID_ABI STREQUAL "x86_64") 46 | set(MASON_PLATFORM_VERSION "x86-64-21") 47 | elseif(ANDROID_ABI STREQUAL "mips") 48 | set(MASON_PLATFORM_VERSION "mips-9") 49 | elseif(ANDROID_ABI STREQUAL "mips64") 50 | set(MASON_PLATFORM_VERSION "mips64-21") 51 | else() 52 | set(MASON_PLATFORM_VERSION "arm-v7-9") 53 | endif() 54 | elseif(NOT MASON_PLATFORM_VERSION) 55 | execute_process( 56 | COMMAND uname -m 57 | OUTPUT_VARIABLE MASON_PLATFORM_VERSION 58 | OUTPUT_STRIP_TRAILING_WHITESPACE) 59 | endif() 60 | 61 | if(MASON_PLATFORM STREQUAL "macos") 62 | set(MASON_PLATFORM "osx") 63 | endif() 64 | 65 | set(ENV{MASON_PLATFORM} "${MASON_PLATFORM}") 66 | set(ENV{MASON_PLATFORM_VERSION} "${MASON_PLATFORM_VERSION}") 67 | 68 | include(CMakeParseArguments) 69 | 70 | function(mason_use _PACKAGE) 71 | if(NOT _PACKAGE) 72 | message(FATAL_ERROR "[Mason] No package name given") 73 | endif() 74 | 75 | cmake_parse_arguments("" "HEADER_ONLY" "VERSION" "" ${ARGN}) 76 | 77 | if(_UNPARSED_ARGUMENTS) 78 | message(FATAL_ERROR "[Mason] mason_use() called with unrecognized arguments: ${_UNPARSED_ARGUMENTS}") 79 | endif() 80 | 81 | if(NOT _VERSION) 82 | message(FATAL_ERROR "[Mason] Specifying a version is required") 83 | endif() 84 | 85 | if(MASON_PACKAGE_${_PACKAGE}_INVOCATION STREQUAL "${MASON_INVOCATION}") 86 | # Check that the previous invocation of mason_use didn't select another version of this package 87 | if(NOT MASON_PACKAGE_${_PACKAGE}_VERSION STREQUAL ${_VERSION}) 88 | message(FATAL_ERROR "[Mason] Already using ${_PACKAGE} ${MASON_PACKAGE_${_PACKAGE}_VERSION}. Cannot select version ${_VERSION}.") 89 | endif() 90 | else() 91 | if(_HEADER_ONLY) 92 | set(_PLATFORM_ID "headers") 93 | else() 94 | set(_PLATFORM_ID "${MASON_PLATFORM}-${MASON_PLATFORM_VERSION}") 95 | endif() 96 | 97 | set(_SLUG "${_PLATFORM_ID}/${_PACKAGE}/${_VERSION}") 98 | set(_INSTALL_PATH "${MASON_PACKAGE_DIR}/${_SLUG}") 99 | file(RELATIVE_PATH _INSTALL_PATH_RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}" "${_INSTALL_PATH}") 100 | 101 | if(NOT EXISTS "${_INSTALL_PATH}") 102 | set(_CACHE_PATH "${MASON_PACKAGE_DIR}/.binaries/${_SLUG}.tar.gz") 103 | if (NOT EXISTS "${_CACHE_PATH}") 104 | # Download the package 105 | set(_URL "${MASON_REPOSITORY}/${_SLUG}.tar.gz") 106 | message(STATUS "[Mason] Downloading package ${_URL}...") 107 | 108 | set(_FAILED) 109 | set(_ERROR) 110 | # Note: some CMake versions are compiled without SSL support 111 | get_filename_component(_CACHE_DIR "${_CACHE_PATH}" DIRECTORY) 112 | file(MAKE_DIRECTORY "${_CACHE_DIR}") 113 | execute_process( 114 | COMMAND curl --retry 3 -s -f -S -L "${_URL}" -o "${_CACHE_PATH}.tmp" 115 | RESULT_VARIABLE _FAILED 116 | ERROR_VARIABLE _ERROR) 117 | if(_FAILED) 118 | message(FATAL_ERROR "[Mason] Failed to download ${_URL}: ${_ERROR}") 119 | else() 120 | # We downloaded to a temporary file to prevent half-finished downloads 121 | file(RENAME "${_CACHE_PATH}.tmp" "${_CACHE_PATH}") 122 | endif() 123 | endif() 124 | 125 | # Unpack the package 126 | message(STATUS "[Mason] Unpacking package to ${_INSTALL_PATH_RELATIVE}...") 127 | file(MAKE_DIRECTORY "${_INSTALL_PATH}") 128 | execute_process( 129 | COMMAND ${CMAKE_COMMAND} -E tar xzf "${_CACHE_PATH}" 130 | WORKING_DIRECTORY "${_INSTALL_PATH}") 131 | endif() 132 | 133 | # Create a config file if it doesn't exist in the package 134 | # TODO: remove this once all packages have a mason.ini file 135 | if(NOT EXISTS "${_INSTALL_PATH}/mason.ini") 136 | # Change pkg-config files 137 | file(GLOB_RECURSE _PKGCONFIG_FILES "${_INSTALL_PATH}/*.pc") 138 | foreach(_PKGCONFIG_FILE IN ITEMS ${_PKGCONFIG_FILES}) 139 | file(READ "${_PKGCONFIG_FILE}" _PKGCONFIG_FILE_CONTENT) 140 | string(REGEX REPLACE "(^|\n)prefix=[^\n]*" "\\1prefix=${_INSTALL_PATH}" _PKGCONFIG_FILE_CONTENT "${_PKGCONFIG_FILE_CONTENT}") 141 | file(WRITE "${_PKGCONFIG_FILE}" "${_PKGCONFIG_FILE_CONTENT}") 142 | endforeach() 143 | 144 | if(NOT EXISTS "${MASON_COMMAND}") 145 | message(FATAL_ERROR "[Mason] Could not find Mason command at ${MASON_COMMAND}") 146 | endif() 147 | 148 | set(_FAILED) 149 | set(_ERROR) 150 | execute_process( 151 | COMMAND ${MASON_COMMAND} config ${_PACKAGE} ${_VERSION} 152 | WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} 153 | OUTPUT_FILE "${_INSTALL_PATH}/mason.ini" 154 | RESULT_VARIABLE _FAILED 155 | ERROR_VARIABLE _ERROR) 156 | if(_FAILED) 157 | message(FATAL_ERROR "[Mason] Could not get configuration for package ${_PACKAGE} ${_VERSION}: ${_ERROR}") 158 | endif() 159 | endif() 160 | 161 | set(MASON_PACKAGE_${_PACKAGE}_PREFIX "${_INSTALL_PATH}" CACHE STRING "${_PACKAGE} ${_INSTALL_PATH}" FORCE) 162 | mark_as_advanced(MASON_PACKAGE_${_PACKAGE}_PREFIX) 163 | 164 | # Load the configuration from the ini file 165 | file(STRINGS "${_INSTALL_PATH}/mason.ini" _CONFIG_FILE) 166 | foreach(_LINE IN LISTS _CONFIG_FILE) 167 | string(REGEX MATCH "^([a-z_]+) *= *" _KEY "${_LINE}") 168 | if (_KEY) 169 | string(LENGTH "${_KEY}" _KEY_LENGTH) 170 | string(SUBSTRING "${_LINE}" ${_KEY_LENGTH} -1 _VALUE) 171 | string(REGEX REPLACE ";.*$" "" _VALUE "${_VALUE}") # Trim trailing commas 172 | string(REPLACE "{prefix}" "${_INSTALL_PATH}" _VALUE "${_VALUE}") 173 | string(STRIP "${_VALUE}" _VALUE) 174 | string(REPLACE "=" "" _KEY "${_KEY}") 175 | string(STRIP "${_KEY}" _KEY) 176 | string(TOUPPER "${_KEY}" _KEY) 177 | if(_KEY STREQUAL "INCLUDE_DIRS" OR _KEY STREQUAL "STATIC_LIBS" ) 178 | separate_arguments(_VALUE) 179 | endif() 180 | set(MASON_PACKAGE_${_PACKAGE}_${_KEY} "${_VALUE}" CACHE STRING "${_PACKAGE} ${_KEY}" FORCE) 181 | mark_as_advanced(MASON_PACKAGE_${_PACKAGE}_${_KEY}) 182 | endif() 183 | endforeach() 184 | 185 | # Compare version in the package to catch errors early on 186 | if(NOT _VERSION STREQUAL MASON_PACKAGE_${_PACKAGE}_VERSION) 187 | message(FATAL_ERROR "[Mason] Package at ${_INSTALL_PATH_RELATIVE} has version '${MASON_PACKAGE_${_PACKAGE}_VERSION}', but required '${_VERSION}'") 188 | endif() 189 | 190 | if(NOT _PACKAGE STREQUAL MASON_PACKAGE_${_PACKAGE}_NAME) 191 | message(FATAL_ERROR "[Mason] Package at ${_INSTALL_PATH_RELATIVE} has name '${MASON_PACKAGE_${_PACKAGE}_NAME}', but required '${_NAME}'") 192 | endif() 193 | 194 | if(NOT _HEADER_ONLY) 195 | if(NOT MASON_PLATFORM STREQUAL MASON_PACKAGE_${_PACKAGE}_PLATFORM) 196 | message(FATAL_ERROR "[Mason] Package at ${_INSTALL_PATH_RELATIVE} has platform '${MASON_PACKAGE_${_PACKAGE}_PLATFORM}', but required '${MASON_PLATFORM}'") 197 | endif() 198 | 199 | if(NOT MASON_PLATFORM_VERSION STREQUAL MASON_PACKAGE_${_PACKAGE}_PLATFORM_VERSION) 200 | message(FATAL_ERROR "[Mason] Package at ${_INSTALL_PATH_RELATIVE} has platform version '${MASON_PACKAGE_${_PACKAGE}_PLATFORM_VERSION}', but required '${MASON_PLATFORM_VERSION}'") 201 | endif() 202 | endif() 203 | 204 | # Concatenate the static libs and libraries 205 | set(_LIBRARIES) 206 | list(APPEND _LIBRARIES ${MASON_PACKAGE_${_PACKAGE}_STATIC_LIBS} ${MASON_PACKAGE_${_PACKAGE}_LDFLAGS}) 207 | set(MASON_PACKAGE_${_PACKAGE}_LIBRARIES "${_LIBRARIES}" CACHE STRING "${_PACKAGE} _LIBRARIES" FORCE) 208 | mark_as_advanced(MASON_PACKAGE_${_PACKAGE}_LIBRARIES) 209 | 210 | if(NOT _HEADER_ONLY) 211 | string(REGEX MATCHALL "(^| +)-L *([^ ]+)" MASON_PACKAGE_${_PACKAGE}_LIBRARY_DIRS "${MASON_PACKAGE_${_PACKAGE}_LDFLAGS}") 212 | string(REGEX REPLACE "(^| +)-L *" "\\1" MASON_PACKAGE_${_PACKAGE}_LIBRARY_DIRS "${MASON_PACKAGE_${_PACKAGE}_LIBRARY_DIRS}") 213 | set(MASON_PACKAGE_${_PACKAGE}_LIBRARY_DIRS "${MASON_PACKAGE_${_PACKAGE}_LIBRARY_DIRS}" CACHE STRING "${_PACKAGE} ${MASON_PACKAGE_${_PACKAGE}_LIBRARY_DIRS}" FORCE) 214 | mark_as_advanced(MASON_PACKAGE_${_PACKAGE}_LIBRARY_DIRS) 215 | endif() 216 | 217 | # Store invocation ID to prevent different versions of the same package in one invocation 218 | set(MASON_PACKAGE_${_PACKAGE}_INVOCATION "${MASON_INVOCATION}" CACHE INTERNAL "${_PACKAGE} invocation ID" FORCE) 219 | endif() 220 | endfunction() 221 | 222 | macro(target_add_mason_package _TARGET _VISIBILITY _PACKAGE) 223 | if (NOT MASON_PACKAGE_${_PACKAGE}_INVOCATION) 224 | message(FATAL_ERROR "[Mason] Package ${_PACKAGE} has not been initialized yet") 225 | endif() 226 | 227 | target_include_directories(${_TARGET} ${_VISIBILITY} "${MASON_PACKAGE_${_PACKAGE}_INCLUDE_DIRS}") 228 | target_compile_definitions(${_TARGET} ${_VISIBILITY} "${MASON_PACKAGE_${_PACKAGE}_DEFINITIONS}") 229 | target_compile_options(${_TARGET} ${_VISIBILITY} "${MASON_PACKAGE_${_PACKAGE}_OPTIONS}") 230 | target_link_libraries(${_TARGET} ${_VISIBILITY} "${MASON_PACKAGE_${_PACKAGE}_LIBRARIES}") 231 | endmacro() 232 | -------------------------------------------------------------------------------- /examples/basic.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main() { 5 | /* x0, y0, x1, y1, ... */ 6 | std::vector coords = {-1, 1, 1, 1, 1, -1, -1, -1}; 7 | 8 | //triangulation happens here 9 | delaunator::Delaunator d(coords); 10 | 11 | for(std::size_t i = 0; i < d.triangles.size(); i+=3) { 12 | printf( 13 | "Triangle points: [[%f, %f], [%f, %f], [%f, %f]]\n", 14 | d.coords[2 * d.triangles[i]], //tx0 15 | d.coords[2 * d.triangles[i] + 1], //ty0 16 | d.coords[2 * d.triangles[i + 1]], //tx1 17 | d.coords[2 * d.triangles[i + 1] + 1],//ty1 18 | d.coords[2 * d.triangles[i + 2]], //tx2 19 | d.coords[2 * d.triangles[i + 2] + 1] //ty2 20 | ); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /examples/triangulate_geojson.cpp: -------------------------------------------------------------------------------- 1 | #include "rapidjson/document.h" 2 | #include "rapidjson/prettywriter.h" 3 | #include 4 | #include "./utils.hpp" 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | std::string serialize_to_json(delaunator::Delaunator const& delaunator) { 12 | rapidjson::StringBuffer sb; 13 | rapidjson::PrettyWriter writer(sb); 14 | writer.StartObject(); 15 | writer.String("type"); writer.String("FeatureCollection"); 16 | writer.String("crs"); 17 | writer.StartObject(); 18 | writer.String("type"); writer.String("name"); 19 | writer.String("properties"); 20 | writer.StartObject(); 21 | writer.String("name"); writer.String("urn:ogc:def:crs:EPSG::900913"); 22 | writer.EndObject(); 23 | writer.EndObject(); 24 | writer.String("features"); 25 | writer.StartArray(); 26 | for(std::size_t i = 0; i < delaunator.triangles.size(); i+=3) { 27 | writer.StartObject(); 28 | writer.String("type"); writer.String("Feature"); 29 | writer.String("properties"); writer.StartObject(); writer.EndObject(); 30 | writer.String("geometry"); 31 | writer.StartObject(); 32 | writer.String("type"); writer.String("Polygon"); 33 | writer.String("coordinates"); 34 | writer.StartArray(); 35 | writer.StartArray(); 36 | writer.StartArray(); 37 | writer.Double(delaunator.coords[2 * delaunator.triangles[i]]); 38 | writer.Double(delaunator.coords[2 * delaunator.triangles[i] + 1]); 39 | writer.EndArray(); 40 | writer.StartArray(); 41 | writer.Double(delaunator.coords[2 * delaunator.triangles[i + 1]]); 42 | writer.Double(delaunator.coords[2 * delaunator.triangles[i + 1] + 1]); 43 | writer.EndArray(); 44 | writer.StartArray(); 45 | writer.Double(delaunator.coords[2 * delaunator.triangles[i + 2]]); 46 | writer.Double(delaunator.coords[2 * delaunator.triangles[i + 2] + 1]); 47 | writer.EndArray(); 48 | writer.StartArray(); 49 | writer.Double(delaunator.coords[2 * delaunator.triangles[i]]); 50 | writer.Double(delaunator.coords[2 * delaunator.triangles[i] + 1]); 51 | writer.EndArray(); 52 | writer.EndArray(); 53 | writer.EndArray(); 54 | writer.EndObject(); 55 | writer.EndObject(); 56 | } 57 | writer.EndArray(); 58 | writer.EndObject(); 59 | return std::string(sb.GetString()); 60 | } 61 | 62 | int main(int, char* argv[]) { 63 | const char* filename = argv[1]; 64 | const char* output = argv[2]; 65 | std::string json = utils::read_file(filename); 66 | std::vector coords = utils::get_geo_json_points(json); 67 | delaunator::Delaunator delaunator(coords); 68 | const char* out_json = serialize_to_json(delaunator).c_str(); 69 | 70 | if (output) { 71 | printf("Writing to file %s", output); 72 | std::ofstream stream; 73 | stream.open(output); 74 | stream << out_json; 75 | stream.close(); 76 | } else { 77 | std::puts(out_json); 78 | } 79 | return 0; 80 | } 81 | -------------------------------------------------------------------------------- /examples/utils.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include "rapidjson/document.h" 8 | 9 | namespace utils { 10 | 11 | inline std::string read_file(const char* filename) { 12 | std::ifstream input_file(filename); 13 | if(input_file.good()) { 14 | std::string json_str( 15 | (std::istreambuf_iterator(input_file)), 16 | std::istreambuf_iterator() 17 | ); 18 | return json_str; 19 | } else { 20 | printf("Error reading file %s", filename); 21 | throw std::runtime_error("Error reading file"); 22 | } 23 | } 24 | 25 | inline std::vector< double> get_geo_json_points(std::string const& json) { 26 | rapidjson::Document document; 27 | if(document.Parse(json.c_str()).HasParseError()) { 28 | throw std::runtime_error("Cannot parse JSON"); 29 | } 30 | const rapidjson::Value& features = document["features"]; 31 | std::vector coords; 32 | // vector y_vector; 33 | for(rapidjson::SizeType i = 0; i < features.Size(); i++) { 34 | const rapidjson::Value& coordinates = features[i]["geometry"]["coordinates"]; 35 | const double x = coordinates[0].GetDouble(); 36 | const double y = coordinates[1].GetDouble(); 37 | coords.push_back(x); 38 | coords.push_back(y); 39 | } 40 | return coords; 41 | } 42 | 43 | template 44 | inline T get_json_value(const rapidjson::Value &v); 45 | 46 | template <> 47 | inline double get_json_value(const rapidjson::Value &v) { 48 | return v.GetDouble(); 49 | } 50 | 51 | template <> 52 | inline size_t get_json_value(const rapidjson::Value &v) { 53 | return static_cast(v.GetUint64()); 54 | } 55 | 56 | template 57 | inline std::vector get_array_points(std::string const& json) { 58 | std::vector points; 59 | rapidjson::Document document; 60 | if(document.Parse(json.c_str()).HasParseError()) { 61 | throw std::runtime_error("Cannot parse JSON"); 62 | } 63 | if(!document.IsArray()) { 64 | throw std::runtime_error("It's not JSON Array"); 65 | } 66 | points.reserve(static_cast(document.Size())); 67 | for(rapidjson::SizeType i = 0; i < document.Size(); i++) { 68 | // points.push_back(document[i].GetDouble()); 69 | points.push_back(get_json_value(document[i])); 70 | } 71 | return points; 72 | } 73 | 74 | } // end ns utils 75 | -------------------------------------------------------------------------------- /generate-reference-triangles/README.md: -------------------------------------------------------------------------------- 1 | 2 | Generating reference datasets using original https://github.com/mapbox/delaunator 3 | 4 | ## Usage 5 | 6 | ``` 7 | npm i 8 | ./index.js ../test/test-files/playgrounds-1356-epsg-3857.geojson ../test/test-files/playgrounds-1356-triangles.json 9 | ``` 10 | -------------------------------------------------------------------------------- /generate-reference-triangles/index.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | /** 4 | * generates triangles indices from delaunator; 5 | */ 6 | 7 | const {readFileSync, writeFileSync} = require('fs'); 8 | const Delaunator = require('delaunator'); 9 | const inputFile = process.argv[2]; 10 | const outputFile = process.argv[3]; 11 | const geoJson = JSON.parse(readFileSync(inputFile)); 12 | 13 | const n = geoJson.features.length; 14 | const coords = new Float64Array(n * 2); 15 | for(let i = 0; i < n; i++) { 16 | const f = geoJson.features[i]; 17 | coords[2 * i] = f.geometry.coordinates[0]; 18 | coords[2 * i + 1] = f.geometry.coordinates[1]; 19 | } 20 | 21 | const start = Date.now(); 22 | const delaunator = new Delaunator(coords); 23 | const end = Date.now(); 24 | 25 | console.log('points =', coords.length / 2); 26 | console.log('milliseconds =', end - start); 27 | console.log('triangles =', delaunator.triangles.length); 28 | 29 | if (outputFile) { 30 | console.log('Saving to', outputFile) 31 | const trianglesAr = Array.from(delaunator.triangles); 32 | writeFileSync(outputFile, JSON.stringify(trianglesAr)); 33 | } 34 | 35 | -------------------------------------------------------------------------------- /generate-reference-triangles/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "generate-reference-triangles", 3 | "requires": true, 4 | "lockfileVersion": 1, 5 | "dependencies": { 6 | "delaunator": { 7 | "version": "3.0.1", 8 | "resolved": "https://registry.npmjs.org/delaunator/-/delaunator-3.0.1.tgz", 9 | "integrity": "sha512-UDOXpkVpycXOQyGQajsyz72MfTMJfkWZ7/cfElX08MNtes1TkZVFKow6BxzNba4TU7Y56nnG2Ajr/+wpeS4y8Q==" 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /generate-reference-triangles/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "generate-reference-triangles", 3 | "private": true, 4 | "main": "index.js", 5 | "dependencies": { 6 | "delaunator": "3.0.1" 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /include/delaunator.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | namespace delaunator { 13 | 14 | //@see https://stackoverflow.com/questions/33333363/built-in-mod-vs-custom-mod-function-improve-the-performance-of-modulus-op/33333636#33333636 15 | inline size_t fast_mod(const size_t i, const size_t c) { 16 | return i >= c ? i % c : i; 17 | } 18 | 19 | // Kahan and Babuska summation, Neumaier variant; accumulates less FP error 20 | inline double sum(const std::vector& x) { 21 | double sum = x[0]; 22 | double err = 0.0; 23 | 24 | for (size_t i = 1; i < x.size(); i++) { 25 | const double k = x[i]; 26 | const double m = sum + k; 27 | err += std::fabs(sum) >= std::fabs(k) ? sum - m + k : k - m + sum; 28 | sum = m; 29 | } 30 | return sum + err; 31 | } 32 | 33 | inline double dist( 34 | const double ax, 35 | const double ay, 36 | const double bx, 37 | const double by) { 38 | const double dx = ax - bx; 39 | const double dy = ay - by; 40 | return dx * dx + dy * dy; 41 | } 42 | 43 | inline double circumradius( 44 | const double ax, 45 | const double ay, 46 | const double bx, 47 | const double by, 48 | const double cx, 49 | const double cy) { 50 | const double dx = bx - ax; 51 | const double dy = by - ay; 52 | const double ex = cx - ax; 53 | const double ey = cy - ay; 54 | 55 | const double bl = dx * dx + dy * dy; 56 | const double cl = ex * ex + ey * ey; 57 | const double d = dx * ey - dy * ex; 58 | 59 | const double x = (ey * bl - dy * cl) * 0.5 / d; 60 | const double y = (dx * cl - ex * bl) * 0.5 / d; 61 | 62 | if ((bl > 0.0 || bl < 0.0) && (cl > 0.0 || cl < 0.0) && (d > 0.0 || d < 0.0)) { 63 | return x * x + y * y; 64 | } else { 65 | return std::numeric_limits::max(); 66 | } 67 | } 68 | 69 | inline bool orient( 70 | const double px, 71 | const double py, 72 | const double qx, 73 | const double qy, 74 | const double rx, 75 | const double ry) { 76 | return (qy - py) * (rx - qx) - (qx - px) * (ry - qy) < 0.0; 77 | } 78 | 79 | inline std::pair circumcenter( 80 | const double ax, 81 | const double ay, 82 | const double bx, 83 | const double by, 84 | const double cx, 85 | const double cy) { 86 | const double dx = bx - ax; 87 | const double dy = by - ay; 88 | const double ex = cx - ax; 89 | const double ey = cy - ay; 90 | 91 | const double bl = dx * dx + dy * dy; 92 | const double cl = ex * ex + ey * ey; 93 | const double d = dx * ey - dy * ex; 94 | 95 | const double x = ax + (ey * bl - dy * cl) * 0.5 / d; 96 | const double y = ay + (dx * cl - ex * bl) * 0.5 / d; 97 | 98 | return std::make_pair(x, y); 99 | } 100 | 101 | struct compare { 102 | 103 | std::vector const& coords; 104 | double cx; 105 | double cy; 106 | 107 | bool operator()(std::size_t i, std::size_t j) { 108 | const double d1 = dist(coords[2 * i], coords[2 * i + 1], cx, cy); 109 | const double d2 = dist(coords[2 * j], coords[2 * j + 1], cx, cy); 110 | const double diff1 = d1 - d2; 111 | const double diff2 = coords[2 * i] - coords[2 * j]; 112 | const double diff3 = coords[2 * i + 1] - coords[2 * j + 1]; 113 | 114 | if (diff1 > 0.0 || diff1 < 0.0) { 115 | return diff1 < 0; 116 | } else if (diff2 > 0.0 || diff2 < 0.0) { 117 | return diff2 < 0; 118 | } else { 119 | return diff3 < 0; 120 | } 121 | } 122 | }; 123 | 124 | inline bool in_circle( 125 | const double ax, 126 | const double ay, 127 | const double bx, 128 | const double by, 129 | const double cx, 130 | const double cy, 131 | const double px, 132 | const double py) { 133 | const double dx = ax - px; 134 | const double dy = ay - py; 135 | const double ex = bx - px; 136 | const double ey = by - py; 137 | const double fx = cx - px; 138 | const double fy = cy - py; 139 | 140 | const double ap = dx * dx + dy * dy; 141 | const double bp = ex * ex + ey * ey; 142 | const double cp = fx * fx + fy * fy; 143 | 144 | return (dx * (ey * cp - bp * fy) - 145 | dy * (ex * cp - bp * fx) + 146 | ap * (ex * fy - ey * fx)) < 0.0; 147 | } 148 | 149 | constexpr double EPSILON = std::numeric_limits::epsilon(); 150 | constexpr std::size_t INVALID_INDEX = std::numeric_limits::max(); 151 | 152 | inline bool check_pts_equal(double x1, double y1, double x2, double y2) { 153 | return std::fabs(x1 - x2) <= EPSILON && 154 | std::fabs(y1 - y2) <= EPSILON; 155 | } 156 | 157 | // monotonically increases with real angle, but doesn't need expensive trigonometry 158 | inline double pseudo_angle(const double dx, const double dy) { 159 | const double p = dx / (std::abs(dx) + std::abs(dy)); 160 | return (dy > 0.0 ? 3.0 - p : 1.0 + p) / 4.0; // [0..1) 161 | } 162 | 163 | struct DelaunatorPoint { 164 | std::size_t i; 165 | double x; 166 | double y; 167 | std::size_t t; 168 | std::size_t prev; 169 | std::size_t next; 170 | bool removed; 171 | }; 172 | 173 | class Delaunator { 174 | 175 | public: 176 | std::vector const& coords; 177 | std::vector triangles; 178 | std::vector halfedges; 179 | std::vector hull_prev; 180 | std::vector hull_next; 181 | std::vector hull_tri; 182 | std::size_t hull_start; 183 | 184 | Delaunator(std::vector const& in_coords); 185 | 186 | double get_hull_area(); 187 | 188 | private: 189 | std::vector m_hash; 190 | double m_center_x; 191 | double m_center_y; 192 | std::size_t m_hash_size; 193 | std::vector m_edge_stack; 194 | 195 | std::size_t legalize(std::size_t a); 196 | std::size_t hash_key(double x, double y) const; 197 | std::size_t add_triangle( 198 | std::size_t i0, 199 | std::size_t i1, 200 | std::size_t i2, 201 | std::size_t a, 202 | std::size_t b, 203 | std::size_t c); 204 | void link(std::size_t a, std::size_t b); 205 | }; 206 | 207 | Delaunator::Delaunator(std::vector const& in_coords) 208 | : coords(in_coords), 209 | triangles(), 210 | halfedges(), 211 | hull_prev(), 212 | hull_next(), 213 | hull_tri(), 214 | hull_start(), 215 | m_hash(), 216 | m_center_x(), 217 | m_center_y(), 218 | m_hash_size(), 219 | m_edge_stack() { 220 | std::size_t n = coords.size() >> 1; 221 | 222 | double max_x = std::numeric_limits::min(); 223 | double max_y = std::numeric_limits::min(); 224 | double min_x = std::numeric_limits::max(); 225 | double min_y = std::numeric_limits::max(); 226 | std::vector ids; 227 | ids.reserve(n); 228 | 229 | for (std::size_t i = 0; i < n; i++) { 230 | const double x = coords[2 * i]; 231 | const double y = coords[2 * i + 1]; 232 | 233 | if (x < min_x) min_x = x; 234 | if (y < min_y) min_y = y; 235 | if (x > max_x) max_x = x; 236 | if (y > max_y) max_y = y; 237 | 238 | ids.push_back(i); 239 | } 240 | const double cx = (min_x + max_x) / 2; 241 | const double cy = (min_y + max_y) / 2; 242 | double min_dist = std::numeric_limits::max(); 243 | 244 | std::size_t i0 = INVALID_INDEX; 245 | std::size_t i1 = INVALID_INDEX; 246 | std::size_t i2 = INVALID_INDEX; 247 | 248 | // pick a seed point close to the centroid 249 | for (std::size_t i = 0; i < n; i++) { 250 | const double d = dist(cx, cy, coords[2 * i], coords[2 * i + 1]); 251 | if (d < min_dist) { 252 | i0 = i; 253 | min_dist = d; 254 | } 255 | } 256 | 257 | const double i0x = coords[2 * i0]; 258 | const double i0y = coords[2 * i0 + 1]; 259 | 260 | min_dist = std::numeric_limits::max(); 261 | 262 | // find the point closest to the seed 263 | for (std::size_t i = 0; i < n; i++) { 264 | if (i == i0) continue; 265 | const double d = dist(i0x, i0y, coords[2 * i], coords[2 * i + 1]); 266 | if (d < min_dist && d > 0.0) { 267 | i1 = i; 268 | min_dist = d; 269 | } 270 | } 271 | 272 | double i1x = coords[2 * i1]; 273 | double i1y = coords[2 * i1 + 1]; 274 | 275 | double min_radius = std::numeric_limits::max(); 276 | 277 | // find the third point which forms the smallest circumcircle with the first two 278 | for (std::size_t i = 0; i < n; i++) { 279 | if (i == i0 || i == i1) continue; 280 | 281 | const double r = circumradius( 282 | i0x, i0y, i1x, i1y, coords[2 * i], coords[2 * i + 1]); 283 | 284 | if (r < min_radius) { 285 | i2 = i; 286 | min_radius = r; 287 | } 288 | } 289 | 290 | if (!(min_radius < std::numeric_limits::max())) { 291 | throw std::runtime_error("not triangulation"); 292 | } 293 | 294 | double i2x = coords[2 * i2]; 295 | double i2y = coords[2 * i2 + 1]; 296 | 297 | if (orient(i0x, i0y, i1x, i1y, i2x, i2y)) { 298 | std::swap(i1, i2); 299 | std::swap(i1x, i2x); 300 | std::swap(i1y, i2y); 301 | } 302 | 303 | std::tie(m_center_x, m_center_y) = circumcenter(i0x, i0y, i1x, i1y, i2x, i2y); 304 | 305 | // sort the points by distance from the seed triangle circumcenter 306 | std::sort(ids.begin(), ids.end(), compare{ coords, m_center_x, m_center_y }); 307 | 308 | // initialize a hash table for storing edges of the advancing convex hull 309 | m_hash_size = static_cast(std::llround(std::ceil(std::sqrt(n)))); 310 | m_hash.resize(m_hash_size); 311 | std::fill(m_hash.begin(), m_hash.end(), INVALID_INDEX); 312 | 313 | // initialize arrays for tracking the edges of the advancing convex hull 314 | hull_prev.resize(n); 315 | hull_next.resize(n); 316 | hull_tri.resize(n); 317 | 318 | hull_start = i0; 319 | 320 | size_t hull_size = 3; 321 | 322 | hull_next[i0] = hull_prev[i2] = i1; 323 | hull_next[i1] = hull_prev[i0] = i2; 324 | hull_next[i2] = hull_prev[i1] = i0; 325 | 326 | hull_tri[i0] = 0; 327 | hull_tri[i1] = 1; 328 | hull_tri[i2] = 2; 329 | 330 | m_hash[hash_key(i0x, i0y)] = i0; 331 | m_hash[hash_key(i1x, i1y)] = i1; 332 | m_hash[hash_key(i2x, i2y)] = i2; 333 | 334 | std::size_t max_triangles = n < 3 ? 1 : 2 * n - 5; 335 | triangles.reserve(max_triangles * 3); 336 | halfedges.reserve(max_triangles * 3); 337 | add_triangle(i0, i1, i2, INVALID_INDEX, INVALID_INDEX, INVALID_INDEX); 338 | double xp = std::numeric_limits::quiet_NaN(); 339 | double yp = std::numeric_limits::quiet_NaN(); 340 | for (std::size_t k = 0; k < n; k++) { 341 | const std::size_t i = ids[k]; 342 | const double x = coords[2 * i]; 343 | const double y = coords[2 * i + 1]; 344 | 345 | // skip near-duplicate points 346 | if (k > 0 && check_pts_equal(x, y, xp, yp)) continue; 347 | xp = x; 348 | yp = y; 349 | 350 | // skip seed triangle points 351 | if ( 352 | check_pts_equal(x, y, i0x, i0y) || 353 | check_pts_equal(x, y, i1x, i1y) || 354 | check_pts_equal(x, y, i2x, i2y)) continue; 355 | 356 | // find a visible edge on the convex hull using edge hash 357 | std::size_t start = 0; 358 | 359 | size_t key = hash_key(x, y); 360 | for (size_t j = 0; j < m_hash_size; j++) { 361 | start = m_hash[fast_mod(key + j, m_hash_size)]; 362 | if (start != INVALID_INDEX && start != hull_next[start]) break; 363 | } 364 | 365 | start = hull_prev[start]; 366 | size_t e = start; 367 | size_t q; 368 | 369 | while (q = hull_next[e], !orient(x, y, coords[2 * e], coords[2 * e + 1], coords[2 * q], coords[2 * q + 1])) { //TODO: does it works in a same way as in JS 370 | e = q; 371 | if (e == start) { 372 | e = INVALID_INDEX; 373 | break; 374 | } 375 | } 376 | 377 | if (e == INVALID_INDEX) continue; // likely a near-duplicate point; skip it 378 | 379 | // add the first triangle from the point 380 | std::size_t t = add_triangle( 381 | e, 382 | i, 383 | hull_next[e], 384 | INVALID_INDEX, 385 | INVALID_INDEX, 386 | hull_tri[e]); 387 | 388 | hull_tri[i] = legalize(t + 2); 389 | hull_tri[e] = t; 390 | hull_size++; 391 | 392 | // walk forward through the hull, adding more triangles and flipping recursively 393 | std::size_t next = hull_next[e]; 394 | while ( 395 | q = hull_next[next], 396 | orient(x, y, coords[2 * next], coords[2 * next + 1], coords[2 * q], coords[2 * q + 1])) { 397 | t = add_triangle(next, i, q, hull_tri[i], INVALID_INDEX, hull_tri[next]); 398 | hull_tri[i] = legalize(t + 2); 399 | hull_next[next] = next; // mark as removed 400 | hull_size--; 401 | next = q; 402 | } 403 | 404 | // walk backward from the other side, adding more triangles and flipping 405 | if (e == start) { 406 | while ( 407 | q = hull_prev[e], 408 | orient(x, y, coords[2 * q], coords[2 * q + 1], coords[2 * e], coords[2 * e + 1])) { 409 | t = add_triangle(q, i, e, INVALID_INDEX, hull_tri[e], hull_tri[q]); 410 | legalize(t + 2); 411 | hull_tri[q] = t; 412 | hull_next[e] = e; // mark as removed 413 | hull_size--; 414 | e = q; 415 | } 416 | } 417 | 418 | // update the hull indices 419 | hull_prev[i] = e; 420 | hull_start = e; 421 | hull_prev[next] = i; 422 | hull_next[e] = i; 423 | hull_next[i] = next; 424 | 425 | m_hash[hash_key(x, y)] = i; 426 | m_hash[hash_key(coords[2 * e], coords[2 * e + 1])] = e; 427 | } 428 | } 429 | 430 | double Delaunator::get_hull_area() { 431 | std::vector hull_area; 432 | size_t e = hull_start; 433 | do { 434 | hull_area.push_back((coords[2 * e] - coords[2 * hull_prev[e]]) * (coords[2 * e + 1] + coords[2 * hull_prev[e] + 1])); 435 | e = hull_next[e]; 436 | } while (e != hull_start); 437 | return sum(hull_area); 438 | } 439 | 440 | std::size_t Delaunator::legalize(std::size_t a) { 441 | std::size_t i = 0; 442 | std::size_t ar = 0; 443 | m_edge_stack.clear(); 444 | 445 | // recursion eliminated with a fixed-size stack 446 | while (true) { 447 | const size_t b = halfedges[a]; 448 | 449 | /* if the pair of triangles doesn't satisfy the Delaunay condition 450 | * (p1 is inside the circumcircle of [p0, pl, pr]), flip them, 451 | * then do the same check/flip recursively for the new pair of triangles 452 | * 453 | * pl pl 454 | * /||\ / \ 455 | * al/ || \bl al/ \a 456 | * / || \ / \ 457 | * / a||b \ flip /___ar___\ 458 | * p0\ || /p1 => p0\---bl---/p1 459 | * \ || / \ / 460 | * ar\ || /br b\ /br 461 | * \||/ \ / 462 | * pr pr 463 | */ 464 | const size_t a0 = 3 * (a / 3); 465 | ar = a0 + (a + 2) % 3; 466 | 467 | if (b == INVALID_INDEX) { 468 | if (i > 0) { 469 | i--; 470 | a = m_edge_stack[i]; 471 | continue; 472 | } else { 473 | //i = INVALID_INDEX; 474 | break; 475 | } 476 | } 477 | 478 | const size_t b0 = 3 * (b / 3); 479 | const size_t al = a0 + (a + 1) % 3; 480 | const size_t bl = b0 + (b + 2) % 3; 481 | 482 | const std::size_t p0 = triangles[ar]; 483 | const std::size_t pr = triangles[a]; 484 | const std::size_t pl = triangles[al]; 485 | const std::size_t p1 = triangles[bl]; 486 | 487 | const bool illegal = in_circle( 488 | coords[2 * p0], 489 | coords[2 * p0 + 1], 490 | coords[2 * pr], 491 | coords[2 * pr + 1], 492 | coords[2 * pl], 493 | coords[2 * pl + 1], 494 | coords[2 * p1], 495 | coords[2 * p1 + 1]); 496 | 497 | if (illegal) { 498 | triangles[a] = p1; 499 | triangles[b] = p0; 500 | 501 | auto hbl = halfedges[bl]; 502 | 503 | // edge swapped on the other side of the hull (rare); fix the halfedge reference 504 | if (hbl == INVALID_INDEX) { 505 | std::size_t e = hull_start; 506 | do { 507 | if (hull_tri[e] == bl) { 508 | hull_tri[e] = a; 509 | break; 510 | } 511 | e = hull_next[e]; 512 | } while (e != hull_start); 513 | } 514 | link(a, hbl); 515 | link(b, halfedges[ar]); 516 | link(ar, bl); 517 | std::size_t br = b0 + (b + 1) % 3; 518 | 519 | if (i < m_edge_stack.size()) { 520 | m_edge_stack[i] = br; 521 | } else { 522 | m_edge_stack.push_back(br); 523 | } 524 | i++; 525 | 526 | } else { 527 | if (i > 0) { 528 | i--; 529 | a = m_edge_stack[i]; 530 | continue; 531 | } else { 532 | break; 533 | } 534 | } 535 | } 536 | return ar; 537 | } 538 | 539 | inline std::size_t Delaunator::hash_key(const double x, const double y) const { 540 | const double dx = x - m_center_x; 541 | const double dy = y - m_center_y; 542 | return fast_mod( 543 | static_cast(std::llround(std::floor(pseudo_angle(dx, dy) * static_cast(m_hash_size)))), 544 | m_hash_size); 545 | } 546 | 547 | std::size_t Delaunator::add_triangle( 548 | std::size_t i0, 549 | std::size_t i1, 550 | std::size_t i2, 551 | std::size_t a, 552 | std::size_t b, 553 | std::size_t c) { 554 | std::size_t t = triangles.size(); 555 | triangles.push_back(i0); 556 | triangles.push_back(i1); 557 | triangles.push_back(i2); 558 | link(t, a); 559 | link(t + 1, b); 560 | link(t + 2, c); 561 | return t; 562 | } 563 | 564 | void Delaunator::link(const std::size_t a, const std::size_t b) { 565 | std::size_t s = halfedges.size(); 566 | if (a == s) { 567 | halfedges.push_back(b); 568 | } else if (a < s) { 569 | halfedges[a] = b; 570 | } else { 571 | throw std::runtime_error("Cannot link edge"); 572 | } 573 | if (b != INVALID_INDEX) { 574 | std::size_t s2 = halfedges.size(); 575 | if (b == s2) { 576 | halfedges.push_back(a); 577 | } else if (b < s2) { 578 | halfedges[b] = a; 579 | } else { 580 | throw std::runtime_error("Cannot link edge"); 581 | } 582 | } 583 | } 584 | 585 | } //namespace delaunator 586 | -------------------------------------------------------------------------------- /scripts/format.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -eu 4 | set -o pipefail 5 | 6 | : ' 7 | 8 | Runs clang-format on the code in include/ 9 | 10 | Return `1` if there are files to be formatted, and automatically formats them. 11 | 12 | Returns `0` if everything looks properly formatted. 13 | 14 | ' 15 | # Set up the environment by installing mason and clang++ 16 | ./scripts/setup.sh --config local.env 17 | source local.env 18 | 19 | # Add clang-format as a dep 20 | mason install clang-format ${MASON_LLVM_RELEASE} 21 | mason link clang-format ${MASON_LLVM_RELEASE} 22 | 23 | # Run clang-format on all cpp and hpp files in the /src directory 24 | find include/ bench/ test/ -type f -name '*.hpp' -or -name '*.cpp' \ 25 | | xargs -I{} clang-format -i -style=file {} 26 | 27 | # Print list of modified files 28 | dirty=$(git ls-files --modified include/ bench/ test/) 29 | 30 | if [[ $dirty ]]; then 31 | echo "The following files have been modified:" 32 | echo $dirty 33 | exit 1 34 | else 35 | exit 0 36 | fi -------------------------------------------------------------------------------- /scripts/setup.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -eu 4 | set -o pipefail 5 | 6 | export MASON_RELEASE="${_MASON_RELEASE:-v0.18.0}" 7 | export MASON_LLVM_RELEASE="${_MASON_LLVM_RELEASE:-5.0.1}" 8 | 9 | PLATFORM=$(uname | tr A-Z a-z) 10 | if [[ ${PLATFORM} == 'darwin' ]]; then 11 | PLATFORM="osx" 12 | fi 13 | 14 | MASON_URL="https://s3.amazonaws.com/mason-binaries/${PLATFORM}-$(uname -m)" 15 | 16 | llvm_toolchain_dir="$(pwd)/.toolchain" 17 | 18 | function run() { 19 | local config=${1} 20 | # unbreak bash shell due to rvm bug on osx: https://github.com/direnv/direnv/issues/210#issuecomment-203383459 21 | # this impacts any usage of scripts that are source'd (like this one) 22 | if [[ "${TRAVIS_OS_NAME:-}" == "osx" ]]; then 23 | echo 'shell_session_update() { :; }' > ~/.direnvrc 24 | fi 25 | 26 | # 27 | # COMPILER TOOLCHAIN 28 | # 29 | 30 | # We install clang++ without the mason client for a couple reasons: 31 | # 1) decoupling makes it viable to use a custom branch of mason that might 32 | # modify the upstream s3 bucket in a such a way that does not give 33 | # it access to build tools like clang++ 34 | # 2) Allows us to short-circuit and use a global clang++ install if it 35 | # is available to save space for local builds. 36 | GLOBAL_CLANG="${HOME}/.mason/mason_packages/${PLATFORM}-$(uname -m)/clang++/${MASON_LLVM_RELEASE}" 37 | GLOBAL_LLVM="${HOME}/.mason/mason_packages/${PLATFORM}-$(uname -m)/llvm/${MASON_LLVM_RELEASE}" 38 | if [[ -d ${GLOBAL_LLVM} ]]; then 39 | echo "Detected '${GLOBAL_LLVM}/bin/clang++', using it" 40 | local llvm_toolchain_dir=${GLOBAL_LLVM} 41 | elif [[ -d ${GLOBAL_CLANG} ]]; then 42 | echo "Detected '${GLOBAL_CLANG}/bin/clang++', using it" 43 | local llvm_toolchain_dir=${GLOBAL_CLANG} 44 | elif [[ -d ${GLOBAL_CLANG} ]]; then 45 | echo "Detected '${GLOBAL_CLANG}/bin/clang++', using it" 46 | local llvm_toolchain_dir=${GLOBAL_CLANG} 47 | elif [[ ! -d ${llvm_toolchain_dir} ]]; then 48 | BINARY="${MASON_URL}/clang++/${MASON_LLVM_RELEASE}.tar.gz" 49 | echo "Downloading ${BINARY}" 50 | mkdir -p ${llvm_toolchain_dir} 51 | curl -sSfL ${BINARY} | tar --gunzip --extract --strip-components=1 --directory=${llvm_toolchain_dir} 52 | fi 53 | 54 | # 55 | # MASON 56 | # 57 | 58 | function setup_mason() { 59 | local install_dir=${1} 60 | local mason_release=${2} 61 | mkdir -p ${install_dir} 62 | curl -sSfL https://github.com/mapbox/mason/archive/${mason_release}.tar.gz | tar --gunzip --extract --strip-components=1 --directory=${install_dir} 63 | } 64 | 65 | setup_mason $(pwd)/.mason ${MASON_RELEASE} 66 | 67 | # 68 | # ENV SETTINGS 69 | # 70 | 71 | echo "export PATH=${llvm_toolchain_dir}/bin:$(pwd)/.mason:$(pwd)/mason_packages/.link/bin:"'${PATH}' > ${config} 72 | echo "export CXX=${CXX:-${llvm_toolchain_dir}/bin/clang++}" >> ${config} 73 | echo "export MASON_RELEASE=${MASON_RELEASE}" >> ${config} 74 | echo "export MASON_LLVM_RELEASE=${MASON_LLVM_RELEASE}" >> ${config} 75 | # https://github.com/google/sanitizers/wiki/AddressSanitizerAsDso 76 | RT_BASE=${llvm_toolchain_dir}/lib/clang/${MASON_LLVM_RELEASE}/lib/$(uname | tr A-Z a-z)/libclang_rt 77 | if [[ $(uname -s) == 'Darwin' ]]; then 78 | RT_PRELOAD=${RT_BASE}.asan_osx_dynamic.dylib 79 | else 80 | RT_PRELOAD=${RT_BASE}.asan-x86_64.so 81 | fi 82 | echo "export MASON_LLVM_RT_PRELOAD=${RT_PRELOAD}" >> ${config} 83 | SUPPRESSION_FILE="/tmp/leak_suppressions.txt" 84 | # Add suppressions as needed 85 | #echo "leak:__strdup" > ${SUPPRESSION_FILE} 86 | echo "export ASAN_SYMBOLIZER_PATH=${llvm_toolchain_dir}/bin/llvm-symbolizer" >> ${config} 87 | echo "export MSAN_SYMBOLIZER_PATH=${llvm_toolchain_dir}/bin/llvm-symbolizer" >> ${config} 88 | echo "export UBSAN_OPTIONS=print_stacktrace=1" >> ${config} 89 | if [[ -f ${SUPPRESSION_FILE} ]]; then 90 | echo "export LSAN_OPTIONS=suppressions=${SUPPRESSION_FILE}" >> ${config} 91 | fi 92 | echo "export ASAN_OPTIONS=symbolize=1:abort_on_error=1:detect_container_overflow=1:check_initialization_order=1:detect_stack_use_after_return=1" >> ${config} 93 | echo 'export MASON_SANITIZE="-fsanitize=address,undefined -fno-sanitize=vptr,function"' >> ${config} 94 | echo 'export MASON_SANITIZE_CXXFLAGS="${MASON_SANITIZE} -fno-sanitize=vptr,function -fsanitize-address-use-after-scope -fno-omit-frame-pointer -fno-common"' >> ${config} 95 | echo 'export MASON_SANITIZE_LDFLAGS="${MASON_SANITIZE}"' >> ${config} 96 | 97 | exit 0 98 | } 99 | 100 | function usage() { 101 | >&2 echo "Usage" 102 | >&2 echo "" 103 | >&2 echo "$ ./scripts/setup.sh --config local.env" 104 | >&2 echo "$ source local.env" 105 | >&2 echo "" 106 | exit 1 107 | } 108 | 109 | if [[ ! ${1:-} ]]; then 110 | usage 111 | fi 112 | 113 | # https://stackoverflow.com/questions/192249/how-do-i-parse-command-line-arguments-in-bash 114 | for i in "$@" 115 | do 116 | case $i in 117 | --config) 118 | if [[ ! ${2:-} ]]; then 119 | usage 120 | fi 121 | shift 122 | run $@ 123 | ;; 124 | -h | --help) 125 | usage 126 | shift 127 | ;; 128 | *) 129 | usage 130 | ;; 131 | esac 132 | done 133 | -------------------------------------------------------------------------------- /test/delaunator.test.cpp: -------------------------------------------------------------------------------- 1 | #include "../examples/utils.hpp" 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | namespace { 8 | 9 | constexpr double EPSILON = std::numeric_limits::epsilon(); 10 | 11 | inline void validate(const std::vector& coords, const double e) { 12 | delaunator::Delaunator d(coords); 13 | 14 | // validate halfedges 15 | for (std::size_t i = 0; i < d.halfedges.size(); i++) { 16 | const auto i2 = d.halfedges[i]; 17 | REQUIRE(!static_cast( 18 | (i2 != delaunator::INVALID_INDEX) && (d.halfedges[i2] != i))); 19 | } 20 | 21 | //validate triangulation 22 | double hull_area = d.get_hull_area(); 23 | std::vector triangles_areas; 24 | 25 | for (size_t i = 0; i < d.triangles.size(); i += 3) { 26 | const double ax = coords[2 * d.triangles[i]]; 27 | const double ay = coords[2 * d.triangles[i] + 1]; 28 | const double bx = coords[2 * d.triangles[i + 1]]; 29 | const double by = coords[2 * d.triangles[i + 1] + 1]; 30 | const double cx = coords[2 * d.triangles[i + 2]]; 31 | const double cy = coords[2 * d.triangles[i + 2] + 1]; 32 | triangles_areas.push_back(std::fabs((by - ay) * (cx - bx) - (bx - ax) * (cy - by))); 33 | } 34 | double triangles_area = delaunator::sum(triangles_areas); 35 | // printf("comparing %f == %f \n", triangles_area, hull_area); 36 | REQUIRE(triangles_area == Approx(hull_area).epsilon(e)); 37 | } 38 | 39 | inline void validate(const std::vector& coords) { 40 | validate(coords, EPSILON); 41 | } 42 | 43 | struct multiply { 44 | double factor; 45 | double operator()(double el) { 46 | return el * factor; 47 | } 48 | }; 49 | 50 | } // namespace 51 | 52 | TEST_CASE("triangles match JS version ouput", "[Delaunator]") { 53 | std::string points_str = utils::read_file("./test/test-files/playgrounds-1356-epsg-3857.geojson"); 54 | std::string triangles_str = utils::read_file("./test/test-files/playgrounds-1356-triangles.json"); 55 | std::vector coords = utils::get_geo_json_points(points_str); 56 | std::vector triangles = utils::get_array_points(triangles_str); 57 | delaunator::Delaunator delaunator(coords); 58 | 59 | SECTION("length of triangles is the same") { 60 | REQUIRE(delaunator.triangles.size() == triangles.size()); 61 | } 62 | 63 | SECTION("values are the same") { 64 | for (std::size_t i = 0; i < triangles.size(); i++) { 65 | REQUIRE(delaunator.triangles[i] == triangles[i]); 66 | } 67 | } 68 | } 69 | 70 | TEST_CASE("produces correct triangulation", "[Delaunator]") { 71 | std::vector coords = { 168, 180, 168, 178, 168, 179, 168, 181, 168, 183, 167, 183, 167, 184, 165, 184, 162, 186, 164, 188, 161, 188, 160, 191, 158, 193, 156, 193, 152, 195, 152, 198, 150, 198, 147, 198, 148, 205, 150, 210, 148, 210, 148, 208, 145, 206, 142, 206, 140, 206, 138, 206, 135, 206, 135, 209, 131, 209, 131, 211, 127, 211, 124, 210, 120, 207, 120, 204, 120, 202, 124, 201, 123, 201, 125, 198, 125, 194, 127, 194, 127, 191, 130, 191, 132, 189, 134, 189, 134, 186, 136, 184, 134, 182, 134, 179, 134, 176, 136, 174, 139, 174, 141, 177, 142, 176, 144, 176, 147, 178, 148, 176, 151, 178, 154, 178, 153, 175, 152, 174, 152, 170, 152, 168, 150, 166, 148, 166, 147, 165, 145, 162, 146, 160, 146, 157, 146, 155, 144, 155, 142, 152, 140, 150, 138, 150, 138, 148, 140, 145, 140, 142, 140, 138, 139, 138, 137, 138, 135, 138, 133, 135, 132, 132, 129, 132, 128, 132, 124, 132, 124, 130, 123, 130, 118, 126, 116, 124, 112, 122, 109, 122, 105, 122, 102, 124, 100, 124, 97, 124, 95, 126, 92, 127, 89, 127, 88, 130, 85, 132, 80, 134, 72, 134, 69, 134, 65, 138, 64, 138, 58, 137, 56, 133, 52, 133, 51, 133, 48, 133, 44, 133, 41, 131, 38, 130, 35, 130, 32, 127, 30, 127, 27, 127, 24, 127, 24, 126, 23, 124, 20, 122, 17, 122, 16, 118, 15, 116, 15, 110, 18, 108, 20, 102, 24, 97, 28, 102, 28, 98, 26, 97, 28, 94, 27, 85, 29, 79, 32, 76, 39, 70, 44, 66, 48, 65, 53, 61, 53, 58, 51, 54, 54, 54, 52, 48, 51, 43, 48, 42, 49, 38, 48, 34, 51, 30, 53, 33, 58, 30, 61, 30, 60, 27, 64, 26, 68, 24, 74, 24, 80, 24, 85, 26, 92, 26, 96, 29, 103, 32, 109, 33, 112, 37, 116, 37, 120, 37, 124, 35, 126, 35, 128, 38, 132, 38, 134, 41, 138, 38, 140, 36, 142, 40, 144, 43, 145, 41, 149, 41, 155, 41, 159, 41, 161, 46, 165, 46, 164, 42, 164, 39, 164, 34, 167, 30, 173, 24, 178, 24, 184, 24, 189, 26, 195, 21, 195, 20, 199, 20, 203, 20, 207, 17, 211, 17, 216, 17, 218, 16, 222, 22, 225, 27, 228, 31, 226, 34, 224, 34, 226, 39, 228, 43, 230, 46, 236, 46, 242, 46, 243, 50, 245, 50, 247, 54, 247, 56, 248, 60, 248, 65, 253, 66, 255, 64, 260, 64, 264, 67, 268, 71, 272, 66, 275, 66, 281, 61, 285, 66, 286, 70, 292, 74, 294, 74, 296, 74, 296, 71, 301, 74, 307, 74, 311, 78, 315, 74, 315, 77, 319, 77, 322, 82, 328, 82, 331, 81, 331, 84, 333, 86, 333, 90, 330, 95, 326, 98, 328, 99, 332, 98, 333, 101, 331, 104, 329, 104, 327, 106, 329, 111, 332, 116, 333, 119, 333, 122, 332, 126, 332, 130, 327, 130, 321, 130, 317, 130, 315, 134, 312, 134, 308, 138, 306, 138, 306, 144, 306, 149, 306, 152, 301, 152, 297, 154, 295, 154, 292, 154, 292, 158, 288, 158, 283, 162, 281, 164, 279, 163, 276, 163, 273, 166, 272, 169, 268, 168, 265, 170, 260, 172, 256, 176, 252, 176, 248, 181, 246, 182, 246, 189, 246, 194, 248, 197, 250, 198, 252, 200, 252, 203, 254, 205, 260, 205, 264, 202, 267, 202, 269, 202, 272, 199, 280, 199, 278, 202, 278, 207, 278, 211, 276, 211, 272, 213, 268, 213, 265, 213, 264, 211, 262, 210, 260, 210, 257, 212, 257, 214, 255, 217, 253, 217, 253, 221, 249, 220, 247, 220, 243, 222, 240, 223, 239, 226, 234, 231, 229, 231, 224, 231, 219, 227, 220, 227, 222, 224, 222, 222, 222, 219, 224, 217, 222, 214, 220, 212, 217, 210, 215, 210, 211, 209, 208, 206, 202, 209, 202, 205, 206, 202, 211, 198, 216, 195, 220, 192, 224, 192, 221, 186, 218, 186, 214, 185, 208, 185, 204, 186, 200, 186, 193, 183, 190, 182, 188, 182, 190, 178, 186, 178, 184, 174, 182, 171, 178, 171, 173, 174, 169, 174, 169, 175, 169, 179, 167, 182, 164, 186, 160, 192, 155, 195, 152, 198, 150, 198, 148, 198, 148, 202, 151, 208, 148, 210, 146, 208, 144, 205, 140, 205, 137, 208, 132, 208, 132, 210, 127, 210, 124, 210, 120, 206, 120, 202, 123, 202, 124, 201, 124, 198, 128, 195, 131, 191, 133, 187, 135, 183, 130, 203, 129, 208, 123, 203, 129, 203, 129, 198, 133, 198, 136, 200, 142, 200, 143, 199, 143, 197, 137, 196, 136, 194, 133, 194, 136, 186, 136, 182, 141, 186, 144, 186, 150, 186, 150, 190, 155, 190, 159, 188, 156, 182, 151, 182, 144, 182, 164, 176, 161, 177, 157, 177, 166, 176, 168, 165, 175, 167, 180, 167, 188, 159, 195, 164, 195, 162, 187, 162, 178, 163, 173, 166, 168, 170, 156, 170, 157, 165, 164, 165, 164, 161, 170, 159, 167, 158, 159, 154, 149, 151, 145, 145, 145, 138, 152, 138, 152, 146, 159, 146, 165, 153, 176, 153, 180, 153, 187, 153, 194, 153, 202, 153, 202, 158, 197, 158, 193, 158, 193, 142, 180, 142, 171, 142, 163, 135, 176, 135, 186, 139, 201, 139, 206, 139, 205, 147, 205, 160, 198, 160, 206, 174, 205, 178, 196, 178, 196, 182, 202, 182, 206, 181, 209, 181, 215, 181, 222, 181, 230, 177, 238, 175, 241, 175, 237, 175, 237, 168, 237, 161, 232, 156, 231, 162, 225, 166, 217, 169, 210, 173, 224, 173, 227, 173, 235, 175, 237, 178, 228, 192, 222, 199, 216, 199, 211, 204, 205, 206, 219, 207, 222, 211, 229, 214, 236, 214, 244, 211, 247, 211, 268, 206, 277, 201, 279, 201, 281, 202, 278, 202, 242, 178, 236, 170, 236, 162, 255, 162, 251, 156, 240, 156, 253, 152, 261, 152, 277, 157, 268, 151, 255, 143, 260, 142, 267, 145, 271, 149, 273, 154, 258, 146, 257, 131, 256, 134, 248, 137, 260, 137, 260, 134, 271, 137, 276, 138, 276, 144, 289, 144, 285, 150, 294, 150, 298, 149, 301, 145, 292, 145, 282, 134, 276, 134, 283, 127, 282, 116, 277, 113, 283, 113, 288, 106, 296, 106, 297, 113, 297, 118, 298, 118, 310, 122, 310, 128, 300, 130, 300, 140, 292, 129, 292, 114, 283, 122, 289, 122, 299, 122, 299, 134, 294, 134, 288, 124, 314, 121, 311, 113, 308, 110, 304, 96, 299, 90, 299, 82, 305, 87, 309, 94, 311, 101, 312, 102, 314, 107, 320, 112, 320, 115, 326, 116, 323, 109, 321, 102, 321, 94, 321, 90, 328, 90, 328, 88, 316, 88, 316, 84, 307, 84, 290, 77, 289, 88, 289, 97, 278, 97, 268, 106, 268, 110, 261, 105, 255, 103, 244, 103, 252, 100, 252, 91, 252, 82, 242, 78, 252, 78, 259, 78, 264, 87, 267, 92, 272, 91, 272, 83, 264, 83, 260, 79, 276, 79, 283, 84, 283, 94, 289, 94, 284, 86, 272, 77, 253, 110, 248, 110, 239, 110, 234, 114, 222, 125, 219, 127, 219, 131, 219, 138, 219, 141, 224, 139, 224, 135, 225, 130, 232, 136, 240, 138, 237, 131, 237, 118, 248, 120, 256, 122, 262, 127, 255, 118, 245, 110, 207, 129, 199, 134, 195, 134, 188, 130, 180, 130, 165, 129, 156, 129, 165, 128, 173, 125, 185, 126, 193, 126, 201, 124, 204, 123, 208, 116, 214, 114, 207, 114, 196, 114, 183, 121, 183, 111, 189, 117, 196, 112, 172, 126, 164, 126, 159, 114, 174, 106, 186, 106, 192, 105, 184, 105, 184, 96, 173, 96, 163, 111, 159, 110, 152, 110, 168, 110, 171, 106, 183, 98, 193, 101, 219, 96, 225, 97, 225, 104, 232, 92, 240, 92, 237, 86, 229, 86, 216, 88, 214, 79, 203, 79, 203, 75, 212, 75, 221, 75, 229, 80, 230, 89, 217, 88, 217, 77, 228, 77, 228, 69, 235, 71, 240, 71, 244, 66, 236, 54, 236, 62, 232, 68, 229, 61, 216, 61, 212, 58, 212, 47, 212, 39, 214, 28, 215, 48, 225, 55, 236, 55, 202, 65, 202, 54, 202, 44, 202, 24, 198, 32, 199, 38, 192, 38, 185, 38, 174, 42, 174, 48, 178, 51, 184, 51, 194, 55, 191, 68, 182, 68, 174, 69, 167, 67, 153, 59, 153, 49, 147, 49, 152, 58, 152, 74, 154, 83, 161, 83, 165, 88, 153, 97, 153, 89, 152, 82, 168, 88, 168, 101, 156, 102, 156, 119, 173, 110, 184, 110, 177, 106, 160, 106, 145, 125, 137, 122, 131, 120, 124, 120, 122, 118, 113, 118, 114, 111, 129, 111, 140, 110, 143, 106, 137, 102, 127, 102, 119, 98, 126, 93, 139, 93, 139, 99, 141, 95, 128, 89, 118, 74, 128, 76, 135, 76, 141, 83, 141, 71, 137, 61, 137, 50, 129, 50, 118, 50, 109, 52, 112, 61, 123, 60, 134, 60, 129, 76, 121, 67, 124, 76, 123, 76, 111, 74, 128, 73, 109, 83, 109, 94, 105, 103, 102, 118, 92, 113, 98, 105, 99, 93, 94, 93, 94, 81, 99, 81, 100, 73, 100, 89, 100, 60, 100, 55, 105, 37, 101, 34, 93, 37, 90, 37, 90, 49, 99, 49, 88, 68, 80, 68, 78, 64, 88, 62, 86, 77, 76, 89, 71, 91, 71, 106, 78, 106, 82, 118, 84, 110, 71, 104, 76, 103, 76, 91, 78, 83, 85, 89, 83, 103, 83, 119, 76, 130, 62, 130, 68, 127, 74, 126, 83, 123, 62, 123, 56, 123, 59, 129, 59, 120, 49, 110, 46, 106, 56, 100, 62, 94, 62, 109, 72, 112, 67, 112, 57, 112, 61, 122, 60, 102, 52, 125, 44, 121, 36, 114, 32, 110, 20, 110, 22, 118, 35, 118, 44, 124, 32, 119, 22, 111, 44, 96, 36, 106, 36, 94, 32, 94, 35, 83, 44, 91, 52, 91, 52, 80, 59, 80, 62, 76, 62, 70, 47, 78, 55, 75, 64, 71, 64, 60, 58, 53, 58, 43, 65, 43, 65, 60, 76, 52, 73, 38, 76, 36, 93, 48, 89, 39, 99, 40, 98, 50, 94, 63, 117, 63, 131, 67, 131, 74, 142, 78, 140, 61, 124, 58, 124, 48, 136, 55, 236, 200, 228, 200, 226, 192, 232, 198, 238, 210, 248, 210, 236, 220, 230, 223, 230, 213, 175, 32, 172, 32, 171, 38, 184, 30 }; 72 | validate(coords); 73 | } 74 | 75 | TEST_CASE("mapbox/delaunator/issues/11", "[Delaunator]") { 76 | std::vector coords = { 516, 661, 369, 793, 426, 539, 273, 525, 204, 694, 747, 750, 454, 390 }; 77 | validate(coords); 78 | } 79 | 80 | TEST_CASE("mapbox/delaunator/issues/24", "[Delaunator]") { 81 | std::vector coords = { 382, 302, 382, 328, 382, 205, 623, 175, 382, 188, 382, 284, 623, 87, 623, 341, 141, 227 }; 82 | validate(coords); 83 | } 84 | 85 | TEST_CASE("mapbox/delaunator/issues/13", "[Delaunator]") { 86 | std::vector coords = { 4, 1, 3.7974166882130675, 2.0837249985614585, 3.2170267516619773, 3.0210869309396715, 2.337215067329615, 3.685489874065187, 1.276805078389906, 3.9872025288851036, 0.17901102978375127, 3.885476929518457, -0.8079039091377689, 3.3940516818407187, -1.550651407188842, 2.5792964886320684, -1.9489192990517052, 1.5512485534497125, -1.9489192990517057, 0.44875144655029087, -1.5506514071888438, -0.5792964886320653, -0.8079039091377715, -1.394051681840717, 0.17901102978374794, -1.8854769295184561, 1.276805078389902, -1.987202528885104, 2.337215067329611, -1.6854898740651891, 3.217026751661974, -1.021086930939675, 3.7974166882130653, -0.08372499856146409 }; 87 | validate(coords); 88 | } 89 | 90 | TEST_CASE("robustness", "[Delaunator]") { 91 | std::vector coords = { 66.103648384371410, 68.588612471664760, 146.680713462100413, 121.680713462100428, 128.868896560467447, 117.261797559041411, 66.103648384371439, 68.588612471664774, 169.552139667571992, 146.133776538276890, 126.629392246050883, 181.111404660392082, 74.434448280233709, 78.630898779520691, 121.111404660392054, 153.370607753949116, 98.888595339607888, 186.629392246050855, 52.660668968140221, 63.178539267712423, 85.321337936280443, 86.357078535424832, 129.615705608064615, 173.901806440322616, 91.522409349774278, 162.346331352698143, 137.240951282800551, 112.240951282800537, 93.370607753949116, 158.888595339607917, 175, 150, 124.142135623730908, 184.142135623730979, 96.208227592327205, 94.083258291328988, 98.888595339607988, 153.370607753949059, 117.982006904420700, 109.535617803137270, 116.194470264303831, 108.267043413376910, 54.324378061245710, 62.306334965997713, 30.886889656046740, 47.726179755904141, 107.095117248373952, 101.809438047233129, 38.892261948632665, 52.594841299088443, 146.680713462100413, 121.680713462100399, 95.857864376269077, 155.857864376269020, 54.324378061245703, 62.306334965997706, 137.240951282800551, 112.240951282800551, 161.529565528607690, 140.440336826753821, 90.384294391935398, 166.098193559677383, 113.220729676874285, 93.717722494332946, 77.882918707497154, 74.870889977331813, 50, 60, 85.321337936280457, 86.357078535424847, 41.773779312093481, 55.452359511808289, 89.662189030622869, 81.153167482998867, 101.441459353748570, 87.435444988665906, 124.142135623730965, 155.857864376269048, 172.416455184654381, 148.166516582657948, 63.547558624186912, 70.904719023616522, 150.642675872560943, 132.714157070849694, 109.999999999999928, 190, 128.477590650225721, 177.653668647301827, 90, 169.999999999999943, 128.477590650225749, 162.346331352698200, 156.120475641400275, 131.120475641400275, 90.384294391935384, 173.901806440322502, 95.857864376268992, 184.142135623730894, 77.882918707497140, 74.870889977331799, 139.755786216514195, 124.987977314945553, 130, 170, 102.346331352698129, 188.477590650225693, 41.773779312093481, 55.452359511808282, 91.522409349774235, 177.653668647301714, 27.784523897265298, 45.189682598176865, 126.629392246050912, 158.888595339607974, 106.098193559677355, 189.615705608064587, 52.660668968140200, 63.178539267712395, 74.434448280233681, 78.630898779520677, 106.098193559677469, 150.384294391935384, 117.653668647301728, 188.477590650225749, 125, 100, 38.892261948632565, 52.594841299088379, 52.660668968140228, 63.178539267712416, 129.615705608064615, 166.098193559677440, 20, 40, 117.653668647301813, 151.522409349774278, 161.529565528607662, 140.440336826753821, 63.547558624186969, 70.904719023616564, 127.801189103500675, 102.801189103500675, 89.662189030622840, 81.153167482998853, 102.346331352698243, 151.522409349774250, 93.370607753949059, 181.111404660391968, 113.901806440322502, 189.615705608064615, 121.111404660391997, 186.629392246050940, 113.901806440322587, 150.384294391935384, 110.000000000000028, 150, 165.560237820700137, 140.560237820700137 }; 92 | 93 | std::vector coords_result; 94 | coords_result.resize(coords.size()); 95 | 96 | validate(coords); 97 | 98 | std::transform(coords.begin(), coords.end(), coords_result.begin(), multiply{ 1e-2 }); 99 | validate(coords_result); 100 | 101 | std::transform(coords.begin(), coords.end(), coords_result.begin(), multiply{ 1e-9 }); 102 | validate(coords_result); 103 | 104 | std::transform(coords.begin(), coords.end(), coords_result.begin(), multiply{ 1e2 }); 105 | validate(coords_result, EPSILON * 2.0); //TODO: missing triangle? 106 | 107 | std::transform(coords.begin(), coords.end(), coords_result.begin(), multiply{ 1e9 }); 108 | validate(coords_result); 109 | 110 | std::vector coords1 = { 66.103648384371410, 68.588612471664760, 146.680713462100413, 121.680713462100428, 128.868896560467447, 117.261797559041411, 66.103648384371439, 68.588612471664774, 169.552139667571992, 146.133776538276890, 126.629392246050883, 181.111404660392082, 74.434448280233709, 78.630898779520691, 121.111404660392054, 153.370607753949116, 98.888595339607888, 186.629392246050855, 52.660668968140221, 63.178539267712423, 85.321337936280443, 86.357078535424832, 129.615705608064615, 173.901806440322616, 91.522409349774278, 162.346331352698143, 137.240951282800551, 112.240951282800537, 93.370607753949116, 158.888595339607917, 175, 150, 124.142135623730908, 184.142135623730979, 96.208227592327205, 94.083258291328988, 98.888595339607988, 153.370607753949059, 117.982006904420700, 109.535617803137270, 116.194470264303831, 108.267043413376910, 54.324378061245710, 62.306334965997713, 30.886889656046740, 47.726179755904141, 107.095117248373952, 101.809438047233129, 38.892261948632665, 52.594841299088443, 146.680713462100413, 121.680713462100399, 95.857864376269077, 155.857864376269020, 54.324378061245703, 62.306334965997706, 137.240951282800551, 112.240951282800551, 161.529565528607690, 140.440336826753821, 90.384294391935398, 166.098193559677383, 113.220729676874285, 93.717722494332946, 77.882918707497154, 74.870889977331813, 50, 60, 85.321337936280457, 86.357078535424847, 41.773779312093481, 55.452359511808289, 89.662189030622869, 81.153167482998867, 101.441459353748570, 87.435444988665906, 124.142135623730965, 155.857864376269048, 172.416455184654381, 148.166516582657948, 63.547558624186912, 70.904719023616522, 150.642675872560943, 132.714157070849694, 109.999999999999928, 190, 128.477590650225721, 177.653668647301827, 90, 169.999999999999943, 128.477590650225749, 162.346331352698200, 156.120475641400275, 131.120475641400275, 90.384294391935384, 173.901806440322502, 95.857864376268992, 184.142135623730894, 77.882918707497140, 74.870889977331799, 139.755786216514195, 124.987977314945553, 130, 170, 102.346331352698129, 188.477590650225693, 41.773779312093481, 55.452359511808282, 91.522409349774235, 177.653668647301714, 27.784523897265298, 45.189682598176865, 126.629392246050912, 158.888595339607974, 106.098193559677355, 189.615705608064587, 52.660668968140200, 63.178539267712395, 74.434448280233681, 78.630898779520677, 106.098193559677469, 150.384294391935384, 117.653668647301728, 188.477590650225749, 125, 100, 38.892261948632565, 52.594841299088379, 52.660668968140228, 63.178539267712416, 129.615705608064615, 166.098193559677440, 20, 40, 117.653668647301813, 151.522409349774278, 161.529565528607662, 140.440336826753821, 63.547558624186969, 70.904719023616564, 127.801189103500675, 102.801189103500675, 89.662189030622840, 81.153167482998853, 102.346331352698243, 151.522409349774250, 93.370607753949059, 181.111404660391968, 113.901806440322502, 189.615705608064615, 121.111404660391997, 186.629392246050940, 113.901806440322587, 150.384294391935384, 110.000000000000028, 150, 165.560237820700137, 140.560237820700137 }; 111 | validate(coords1); 112 | 113 | std::vector coords2 = { 0.226270008640849, -0.5484478681473859, 0.22627000864084906, -0.5484478681473857, 0.766192698520777, -0.06114560279536302, 0.7661926985207771, -0.06114560279536302, 0.40151121510492016, 0.08616979557470032, 0.40151121510492027, 0.08616979557470034, -0.41675996433129736, -0.5902787491305856, -0.4167599643312972, -0.5902787491305853, -0.2479064469635639, -0.7472011647497873, -0.24790644696356384, -0.7472011647497872, 0.6078988481689899, -0.8087190266174613, 0.6078988481689901, -0.808719026617461, 0.6844238681986647, -0.22229148851718702, 0.6844238681986647, -0.222291488517187, 0.6486832941181451, 0.3706194950394349, 0.6486832941181452, 0.3706194950394349, -0.5361048842131249, -0.16765691382574804, -0.5361048842131245, -0.167656913825748, 0.4588358986737203, -0.9000280551977525, 0.4588358986737205, -0.9000280551977525, 0.3960651926938643, 0.19117525930527385, 0.39606519269386437, 0.1911752593052739, 0.30699987842448867, -0.4067155996580057, 0.3069998784244887, -0.4067155996580056, 0.47811583559881354, 0.4551485080955586, 0.47811583559881354, 0.4551485080955586, 0.5569494202770435, 0.3174275448747843, 0.5569494202770439, 0.3174275448747845, -0.4277027605175392, 0.09695587866512022, -0.4277027605175391, 0.09695587866512025, -0.5748114807265807, -0.03838218657575568, -0.5748114807265806, -0.03838218657575567, -1.0317070883952917, -0.5245256032470283, -1.031707088395291, -0.5245256032470283, 0.14712374452633492, 0.33141471681448986, 0.147123744526335, 0.33141471681448986, -0.2834737219004291, -0.9271587984120542, -0.2834737219004289, -0.9271587984120538, -0.6098149486946731, 0.5553773725836295, -0.6098149486946729, 0.5553773725836295, 1.1206314478250745, 0.3921423623286639, 1.1206314478250745, 0.39214236232866406, 0.4477538973665876, -0.04256704865570235, 0.4477538973665877, -0.04256704865570235, -0.6156635308889042, -0.10817302193016937, -0.6156635308889041, -0.10817302193016932, 0.17897362794557034, -0.04224227852769616, 0.17897362794557034, -0.04224227852769614, -0.9646885789850332, -1.4563419829050452, -0.9646885789850331, -1.456341982905045, 0.2911613415160255, 0.015655417967490592, 0.29116134151602563, 0.015655417967490596, -0.3698918540831971, 0.6983267205999204, -0.3698918540831969, 0.6983267205999205, 1.4056553730213062, -0.41615789580202767, 1.4056553730213066, -0.41615789580202767, 0.34141990921721344, -0.5679551502988661, 0.3414199092172136, -0.5679551502988661, 0.2957318137669341, 0.8416499601535058, 0.29573181376693425, 0.841649960153506, 0.035141462612931273, -0.45835970615650135, 0.03514146261293129, -0.45835970615650123, -1.3263110033694971, 0.8223290351908346, -1.326311003369497, 0.8223290351908346, -0.18787969354847422, 1.4601214758378256, -0.18787969354847417, 1.4601214758378258, -0.5421684590742957, -0.5196118080038157, -0.5421684590742956, -0.5196118080038157, -0.15415956428809274, 0.2553265483092856, -0.15415956428809266, 0.25532654830928564, 0.24744639466303925, 0.36561549310806263, 0.24744639466303933, 0.36561549310806274, -0.007949225522230624, -0.4463313570187974, -0.00794922552223062, -0.4463313570187972, 0.4314282749865176, 0.6907165244683744, 0.4314282749865177, 0.6907165244683744, 0.22721916356346672, -1.145924985720078, 0.22721916356346675, -1.1459249857200775, 0.11627266697915434, 0.5679584977485386, 0.11627266697915438, 0.5679584977485389, -0.004760241854834868, 1.341758406463988, -0.004760241854834866, 1.3417584064639887, 0.34070213758085, -0.4524446934513693, 0.3407021375808501, -0.45244469345136923, 0.8842875090593054, -0.4369329059094983, 0.8842875090593055, -0.43693290590949824, 0.1514286184534766, -0.17725085421066233, 0.15142861845347666, -0.17725085421066225, -0.4255258812089902, -0.48986352859695054, -0.42552588120899015, -0.4898635285969505, 0.9377261482762783, -0.1443481348548356, 0.9377261482762784, -0.14434813485483552, 0.04260345503852292, 0.951377045867543, 0.04260345503852292, 0.951377045867543, 0.305243584013604, -0.3875472629266138, 0.305243584013604, -0.3875472629266138, 0.03603755940893599, 0.34504467425927055, 0.036037559408936, 0.34504467425927055, 0.7432869522329792, -0.7836440067269177, 0.7432869522329795, -0.7836440067269175, -0.2963957383054346, -0.8541077824286829, -0.2963957383054344, -0.8541077824286829, -0.5957774790480242, -0.600709712349726, -0.5957774790480241, -0.6007097123497258, -0.16224562470708315, 0.34537414926581733, -0.16224562470708306, 0.34537414926581733, -0.7424662163367453, -0.41130625924230096, -0.742466216336745, -0.41130625924230085, -0.3624590396531042, -0.10563984421746442, -0.3624590396531041, -0.10563984421746442, -0.5392904110560361, -0.08518185259429017, -0.5392904110560358, -0.08518185259429016, -0.6778672159722301, 0.3431673449069855, -0.6778672159722301, 0.3431673449069856, 0.36715717958832705, -0.5910728761089766, 0.36715717958832716, -0.5910728761089764, -0.025023155416355747, 0.049551540818041445, -0.025023155416355747, 0.04955154081804146, -0.24819669042158904, 1.551076727423892, -0.24819669042158898, 1.5510767274238921, 0.567193157662795, 0.11906741314152564, 0.567193157662795, 0.11906741314152564, -0.040143445247768667, 0.26972252794743534, -0.04014344524776866, 0.26972252794743534, -0.2625294670890006, -0.9866393501381076, -0.2625294670890005, -0.9866393501381073, 0.44843907219373064, 0.8048081754922025, 0.44843907219373064, 0.8048081754922027, 0.0645600537587031, 1.0817638655728792, 0.06456005375870313, 1.0817638655728798, 0.7675432088110417, -0.8812717114610312, 0.7675432088110417, -0.8812717114610309, -0.08286494268897, -0.4289421536808215, -0.08286494268896998, -0.42894215368082134, -0.41612370586918423, 0.4886715855834002, -0.41612370586918423, 0.48867158558340035, 0.19771717248920714, -0.1094932114101852, 0.19771717248920723, -0.10949321141018517, 0.3325743770435765, 0.3050059606614455, 0.3325743770435766, 0.3050059606614456, -0.6076675750885592, -0.2488880571567846, -0.6076675750885588, -0.24888805715678455, -0.13216710101702264, -0.5066473875502346, -0.13216710101702256, -0.5066473875502345, 0.8513876721292416, -0.5489241609365357, 0.8513876721292416, -0.5489241609365356, -0.382289175026138, -0.47285448091622573, -0.38228917502613796, -0.4728544809162256, -0.22454842691828375, 0.6151379112650053, -0.22454842691828367, 0.6151379112650056, -0.8646014175536286, -0.42386569643498184, -0.8646014175536284, -0.4238656964349818, 0.3117316226386966, 0.2627613357418179, 0.3117316226386967, 0.262761335741818, -0.15249103914387663, 0.4395379613315442, -0.15249103914387657, 0.4395379613315443, -0.8535303948590758, -0.5171136892316436, -0.8535303948590756, -0.5171136892316435, 0.5548908499705427, 0.7505471621260598, 0.5548908499705427, 0.7505471621260601, -0.06051133138765111, 0.10241755750407933, -0.0605113313876511, 0.10241755750407933, 0.5337288423213871, -0.4674709006951539, 0.5337288423213873, -0.4674709006951539, 0.05432726705458686, 0.7404240043361822, 0.054327267054586875, 0.7404240043361824, 0.18755513858332273, -0.33846461008241124, 0.1875551385833228, -0.33846461008241124, -0.8591170242442958, 0.10096092456106642, -0.8591170242442956, 0.10096092456106642, -0.6532878500824677, 0.06191743854152687, -0.6532878500824675, 0.06191743854152687, -0.8539614587215372, -0.7324824009962402, -0.8539614587215372, -0.7324824009962402, -0.5863802667964559, -1.056546154929931, -0.5863802667964556, -1.0565461549299304, -0.1790469166305501, 0.2959320232236789, -0.17904691663055006, 0.2959320232236789, -0.1360834565364501, -0.11972427421383847, -0.13608345653645007, -0.11972427421383845, 1.000279652308404, 0.5677840712010568, 1.0002796523084043, 0.5677840712010568, -0.2539417014734854, -0.24824262411661902, -0.2539417014734853, -0.24824262411661896, -0.5513314210236925, 0.164455936053998, -0.5513314210236921, 0.16445593605399808, -0.35669084505120763, -0.5579365995173293, -0.3566908450512076, -0.557936599517329, -0.00479028693868494, 0.5747959597699825, -0.004790286938684939, 0.5747959597699829, 0.9274618857336762, 0.3137388167061812, 0.9274618857336765, 0.3137388167061813, -0.1582654462645559, 0.08532244403569378, -0.1582654462645559, 0.08532244403569382, -0.7338606250043278, 0.03884536523072413, -0.7338606250043278, 0.038845365230724134, 0.441630546674704, -0.4757978998267975, 0.4416305466747042, -0.4757978998267975, -0.340639188849867, -0.016461235375619054, -0.340639188849867, -0.01646123537561905, 0.6944973204450795, -0.05127049077067958, 0.6944973204450798, -0.051270490770679564, 0.05692195764635159, -0.4860234898913355, 0.05692195764635161, -0.4860234898913355, -0.34909544551668503, 0.07925987763994416, -0.3490954455166849, 0.07925987763994416, 0.020842670418798892, -0.18962128485770935, 0.020842670418798902, -0.1896212848577093, -0.24296262993119017, -0.7557062436624338, -0.24296262993119008, -0.7557062436624334, 0.07767785036524773, -0.0756745138376198, 0.07767785036524774, -0.0756745138376198, -0.5383587124935423, 0.3149908402335876, -0.538358712493542, 0.3149908402335876, -0.3672547557130592, 0.8497352282145765, -0.3672547557130592, 0.8497352282145768, 1.0306858576839981, 0.6132170100848149, 1.0306858576839986, 0.6132170100848152, 0.026403641820751278, -0.11123958700346126, 0.02640364182075129, -0.11123958700346125, -0.39673068933170313, 0.7365210212380586, -0.3967306893317031, 0.7365210212380586, -0.273859110739041, 0.15083421880672626, -0.2738591107390409, 0.15083421880672626, -0.7502503591118193, -0.6273750425323015, -0.7502503591118191, -0.6273750425323014, 1.040458273889268, 0.3592162639445413, 1.0404582738892683, 0.3592162639445414, -0.30951481303178596, -0.7990197975684153, -0.30951481303178585, -0.7990197975684152, -0.3049861667890695, 1.6737307580052914, -0.30498616678906937, 1.673730758005292, 0.601935475297747, 1.1660575124169412, 0.601935475297747, 1.1660575124169419, 0.8838992370838099, 0.2656415636074353, 0.8838992370838102, 0.2656415636074353, -0.5085727248068516, -0.23584500534815295, -0.5085727248068515, -0.2358450053481529, 0.5396217328637709, -0.39810497658583466, 0.5396217328637712, -0.39810497658583466, 0.8665494841240842, 0.11624211166929022, 0.8665494841240843, 0.11624211166929023, -0.51942267345288, 0.5395224235439922, -0.5194226734528796, 0.5395224235439922, 0.19088288221197763, -0.4663336215970121, 0.19088288221197763, -0.4663336215970119, -0.23194847381262582, 0.21901474700861162, -0.23194847381262573, 0.21901474700861162, 0.8359436402369345, -0.2679779650730807, 0.8359436402369346, -0.2679779650730805, 0.4468309121482219, 0.724738511770195, 0.4468309121482219, 0.7247385117701953, 0.5963791684457523, 0.8746079737915003, 0.5963791684457525, 0.8746079737915007, -0.16268657840268694, -0.10458689278692812, -0.16268657840268685, -0.10458689278692809, 0.15167543844454376, 0.3810633395493045, 0.1516754384445438, 0.3810633395493046, 0.3175047149330903, -0.4680659139099735, 0.31750471493309046, -0.4680659139099735, 0.24518019737678892, 0.14105859064554405, 0.24518019737678892, 0.1410585906455441, 0.1337014618382204, 0.216053384319761, 0.1337014618382205, 0.21605338431976104, -0.5196743788563577, -0.24381508621133063, -0.5196743788563577, -0.24381508621133063, 0.16145768845022127, -0.18548235309792105, 0.16145768845022135, -0.18548235309792097, 0.5267956022472777, -0.07806817831728718, 0.5267956022472777, -0.07806817831728716, 0.2690528801662905, 0.007775444056135339, 0.2690528801662905, 0.00777544405613534, 0.7565821160819859, -0.3047749278545374, 0.7565821160819859, -0.30477492785453736, -0.7016467625353928, 0.04470959700747512, -0.7016467625353925, 0.04470959700747514, 0.2415239307661166, 0.2972238198129453, 0.24152393076611664, 0.2972238198129453, 0.2284592008150542, -0.6608245027366711, 0.2284592008150542, -0.6608245027366711, 0.2123088556780684, 0.01782161739519142, 0.21230885567806848, 0.017821617395191426, -0.14619514581307758, -0.8833238459080084, -0.14619514581307758, -0.8833238459080082, 0.1989466009909055, -0.6118402241082294, 0.1989466009909055, -0.6118402241082291, 0.49059993119084305, -0.16493514201871323, 0.4905999311908431, -0.1649351420187132, -0.4129648372506063, -0.05944366961592451, -0.4129648372506062, -0.059443669615924496, 0.586485692893329, 0.3271185970911774, 0.5864856928933292, 0.32711859709117747, -0.06023227911161408, -0.7107842875157466, -0.06023227911161407, -0.7107842875157466, 0.6310359079249456, 0.29992699270395096, 0.6310359079249456, 0.29992699270395107, -0.6703089300986523, 0.6107470941705689, -0.670308930098652, 0.6107470941705689, 0.5005957282133777, 0.01407262429060302, 0.500595728213378, 0.014072624290603021, -0.18934890988546538, -0.9372780070318394, -0.1893489098854653, -0.9372780070318394, -0.2863087126284564, -0.40444718862380247, -0.28630871262845636, -0.4044471886238023, 1.190084782443751, 0.5322874598725964, 1.1900847824437517, 0.5322874598725967, 0.1341442916393324, -0.8420626196661292, 0.13414429163933247, -0.8420626196661289, -0.7649861084427345, -0.7071073574041574, -0.7649861084427344, -0.7071073574041573, -0.362881463482392, 0.4530261596665785, -0.3628814634823919, 0.45302615966657866, 0.13437240869925704, 0.0763221848731111, 0.13437240869925712, 0.0763221848731111, 1.0481657649638807, -0.004257185833033583, 1.0481657649638814, -0.004257185833033581, -0.7474948815245823, -0.9786844358659653, -0.7474948815245823, -0.9786844358659653, 0.12735871993303205, -0.3185548367971229, 0.12735871993303208, -0.31855483679712276, 0.36855220211615, -0.5588123239347687, 0.36855220211615003, -0.5588123239347685, -0.18314335566244416, -0.5442250179734792, -0.18314335566244408, -0.544225017973479, 0.08693873231351551, -0.6447286294698766, 0.08693873231351551, -0.6447286294698766, -0.05481436374055537, 0.20956141264894845, -0.05481436374055537, 0.2095614126489485, -0.27114580055426557, 0.12928945128646963, -0.2711458005542655, 0.12928945128646968, -0.4451760474692624, 0.46862844610576626, -0.4451760474692623, 0.4686284461057663, 0.1341730804119372, -0.5079494612186458, 0.13417308041193723, -0.5079494612186456, 0.3257440025696646, 0.4153507171529827, 0.3257440025696647, 0.4153507171529827, -1.2231311278955395, 0.5704928559937266, -1.223131127895539, 0.5704928559937269, -0.07375248343426033, -0.5524759317685063, -0.0737524834342603, -0.5524759317685063, -0.6413383012441964, -0.3892879515624541, -0.6413383012441963, -0.38928795156245405, -0.000884182358095037, -0.003185720596142992, -0.0008841823580950368, -0.003185720596142991, 0.737566803637365, -0.7615040446353664, 0.7375668036373654, -0.761504044635366, 0.23446047289831606, 0.19035505393365781, 0.23446047289831606, 0.19035505393365784, -0.07211988377390469, -0.13169854040950443, -0.07211988377390469, -0.13169854040950443, 0.18143877838398617, 1.132013860293268, 0.18143877838398625, 1.1320138602932683, -0.22066292105815377, -0.19117568196580417, -0.22066292105815372, -0.19117568196580417, -0.4347453028054331, 0.5888401578252912, -0.43474530280543294, 0.5888401578252915, 0.24005504098930414, 0.8021441938204985, 0.24005504098930416, 0.8021441938204986, -0.34929799898447755, -0.261775797658851, -0.34929799898447744, -0.26177579765885084, 0.3490077668059596, -0.007752337813972554, 0.3490077668059597, -0.0077523378139725515, -0.6025788068137587, 0.46068756636034236, -0.6025788068137585, 0.4606875663603424, -0.7122333712891852, 0.26308462754739115, -0.7122333712891852, 0.26308462754739115, 0.15764425398809745, 0.18964163728856187, 0.15764425398809748, 0.18964163728856193, 0.1853787174021873, -0.6789040209134625, 0.18537871740218737, -0.6789040209134621, 0.634911453390334, 0.13339968677329644, 0.6349114533903343, 0.13339968677329647, -1.2578415170869763, 0.2517963788258869, -1.2578415170869757, 0.2517963788258869, 0.1400845593846478, 0.40593141307431857, 0.14008455938464787, 0.4059314130743186, -0.7095485725512902, 0.8225233205642902, -0.7095485725512899, 0.8225233205642903, -1.1960848307098382, 0.17404679607890605, -1.196084830709838, 0.17404679607890608, 0.21828979413603433, -0.3280264848946596, 0.2182897941360344, -0.3280264848946595, 0.2662387358530971, 0.3568929623829047, 0.26623873585309726, 0.3568929623829048, 0.24305026107578037, -0.23724020319018074, 0.24305026107578043, -0.23724020319018066, -0.3433832627650342, 0.3389417719770061, -0.34338326276503406, 0.3389417719770061, -0.0437269904343551, 0.5869495454659391, -0.04372699043435508, 0.5869495454659392, -0.12109570623011018, -0.8772834803160542, -0.12109570623011016, -0.8772834803160542, 0.09631218123471452, -0.12108887934946555, 0.09631218123471456, -0.12108887934946555, -0.41811390046020547, 0.8465092639539217, -0.4181139004602053, 0.8465092639539218, -0.34396631561394114, 0.8358904797678759, -0.343966315613941, 0.8358904797678759, 0.43085589801084057, -0.16054297058369527, 0.4308558980108406, -0.1605429705836952, -0.19787245165430847, 0.8949780141072381, -0.19787245165430842, 0.8949780141072381, -0.5907860100454578, 0.18974221311023962, -0.5907860100454575, 0.18974221311023964, -0.5306691342020886, -0.7275053842709899, -0.5306691342020886, -0.7275053842709899, -0.345074608245379, 1.207589321519286, -0.34507460824537883, 1.207589321519286, -0.32302823411726667, 0.08250252511437048, -0.32302823411726667, 0.0825025251143705, -0.1000939664088763, -1.056428113867832, -0.10009396640887627, -1.056428113867832, 0.0057223538613018765, -0.07997801149692216, 0.005722353861301878, -0.07997801149692216, -1.0232923766303312, 0.22905472765407248, -1.0232923766303312, 0.22905472765407253, -0.04071787429636753, 0.03839904161757046, -0.04071787429636751, 0.03839904161757047, -0.5114614823431506, -0.0673439850879256, -0.5114614823431503, -0.06734398508792559, -0.033395285925899576, -0.25197193535594753, -0.03339528592589957, -0.2519719353559475, -1.3238866550876203, -0.34335648499193994, -1.3238866550876196, -0.3433564849919398, 0.3098949809621799, -0.692558554406312, 0.30989498096218, -0.6925585544063119, -0.7778172969650805, -0.7251725696504421, -0.7778172969650804, -0.7251725696504421, 0.5832467520992983, -0.0005585979375463679, 0.5832467520992983, -0.0005585979375463677, 0.6402717430536337, -0.24460516745019825, 0.6402717430536337, -0.24460516745019825, 0.3744231501345624, 0.23752933224278633, 0.37442315013456257, 0.23752933224278638, -0.5526534599107001, 0.2959174882702319, -0.5526534599106999, 0.29591748827023195, 0.0870980709703463, 0.011155933053077993, 0.08709807097034632, 0.011155933053077997, 0.10294466025799387, 0.6246279155358483, 0.10294466025799387, 0.6246279155358484, 0.7907530514131953, 0.7968130944966136, 0.7907530514131955, 0.796813094496614, -0.06771348768905705, -0.19742894579933645, -0.06771348768905704, -0.19742894579933642, 1.7336246702438183, -0.08111369728186346, 1.7336246702438185, -0.08111369728186343, 0.39279504341227045, -0.2803428186493195, 0.39279504341227056, -0.2803428186493194, -0.3837990187335033, 0.5817465996045292, -0.38379901873350314, 0.5817465996045292, -0.15897299229161954, 0.2123178635236439, -0.15897299229161949, 0.21231786352364398, 1.2871753315186103, -0.2936546706485327, 1.2871753315186105, -0.2936546706485326, -0.28157817609809926, 0.015215204873323618, -0.28157817609809926, 0.015215204873323621, -0.8407785771058587, 0.11715953275528568, -0.8407785771058583, 0.11715953275528568, 0.057427665729494065, 0.17741033446395021, 0.057427665729494086, 0.17741033446395027, -0.3919333534914909, -0.8777063099779623, -0.3919333534914909, -0.8777063099779623, 1.046062759037447, 0.12566529633175702, 1.0460627590374476, 0.1256652963317571, 0.05208282489856039, 0.23074154552008772, 0.05208282489856039, 0.23074154552008772, 0.3090093991217477, -0.28949051651550656, 0.3090093991217478, -0.2894905165155065, -0.903992079888195, -0.08968028913527537, -0.903992079888195, -0.08968028913527537, 0.1114034542194284, -0.1420055490952354, 0.11140345421942845, -0.1420055490952354, 0.49928483909803145, -1.031860401303775, 0.49928483909803145, -1.031860401303775, -0.25021332122685536, -0.23430348924020267, -0.2502133212268553, -0.23430348924020258, 0.45788605189844944, 0.008986832993373578, 0.45788605189844944, 0.008986832993373583, 0.9922986143818168, -0.3970601247358978, 0.9922986143818171, -0.3970601247358978, 0.3242247399299542, 0.00883592005445788, 0.3242247399299542, 0.008835920054457881, 0.6104748391149722, -0.1588370496187479, 0.6104748391149722, -0.15883704961874784, -0.2328772934092499, -0.28654852459626834, -0.23287729340924987, -0.28654852459626823, 0.2591579326588679, -0.48250620169929226, 0.2591579326588679, -0.4825062016992922, 0.030769057057074042, -0.6677902182695195, 0.030769057057074042, -0.6677902182695192, 0.5724668628416123, 0.17684659209108886, 0.5724668628416124, 0.17684659209108886, -0.1936816938025718, 0.017884183939394893, -0.19368169380257177, 0.017884183939394897, 0.3927424946727771, -0.3589320240798228, 0.3927424946727773, -0.35893202407982266, -0.13217719866296695, 0.4509072577920714, -0.13217719866296687, 0.4509072577920715, 0.7771200989698435, 0.07094000492318109, 0.7771200989698438, 0.07094000492318112, -0.043208921594939775, -0.7058014850795868, -0.043208921594939755, -0.7058014850795865, -0.44161734737621083, 0.17508260808335738, -0.44161734737621083, 0.17508260808335738, 0.3111521947954433, 0.5211230285003844, 0.3111521947954433, 0.5211230285003846, -0.5089025606249975, -0.08897969566205755, -0.5089025606249975, -0.08897969566205753, -0.785274533858358, 0.2966023384405856, -0.785274533858358, 0.2966023384405857, 0.13643734685972797, -0.5487534801505365, 0.136437346859728, -0.5487534801505362, -0.5113536157192956, -0.38818343681854633, -0.5113536157192953, -0.3881834368185463, 0.6482527388360249, -0.3660801422494009, 0.6482527388360252, -0.3660801422494007, 0.1219550825441264, 0.2636220365395331, 0.12195508254412644, 0.2636220365395332, 0.830646565838305, 0.05595258169938715, 0.8306465658383052, 0.055952581699387154, 0.02087272912166732, -0.2757601788166507, 0.02087272912166733, -0.2757601788166507, -0.8969757534742673, -1.0096320440536182, -0.8969757534742671, -1.0096320440536182, 0.281470556211261, -0.5392051870077439, 0.281470556211261, -0.5392051870077438, 0.09939015666169382, -0.0010699511947921958, 0.09939015666169386, -0.0010699511947921952, -0.002256115172019346, -0.04020319566150099, -0.0022561151720193458, -0.04020319566150097, 0.4504785560293585, 0.373102472756903, 0.4504785560293585, 0.3731024727569031, 0.5231672603524817, 0.16985255790851625, 0.5231672603524821, 0.16985255790851628, -0.7514640400004967, 0.07080018087746165, -0.7514640400004965, 0.07080018087746165, 0.13303832542382837, 0.2602273203264872, 0.1330383254238284, 0.2602273203264874, 0.19343395931079577, -0.5502548672222486, 0.1934339593107958, -0.5502548672222483, -0.20823169078587966, -0.925945416171643, -0.20823169078587964, -0.925945416171643, -1.0354112179615744, 0.9009086420084467, -1.035411217961574, 0.9009086420084467, -0.13833287790394402, 0.33595123313495734, -0.13833287790394397, 0.3359512331349575, -0.48681401106341476, 0.012840401303908289, -0.4868140110634147, 0.012840401303908292, -0.38580806564875847, -0.3414309718415358, -0.3858080656487583, -0.3414309718415357, -0.387387928447792, 0.3363647167396555, -0.387387928447792, 0.3363647167396555, -0.7289577885281368, 0.11000344782305926, -0.7289577885281364, 0.11000344782305929, 0.5996652640170703, -0.3788676471009784, 0.5996652640170704, -0.37886764710097826, 0.1184108904136601, -0.36481788339618465, 0.11841089041366011, -0.36481788339618465, -0.030883796635844396, -0.2470002368704879, -0.030883796635844393, -0.24700023687048783, 0.003754694361758959, -0.19869298401291166, 0.0037546943617589594, -0.1986929840129116, 0.11693502055240339, 0.2098964093295748, 0.11693502055240342, 0.20989640932957487, -0.44372931923544234, 0.056472315155220026, -0.44372931923544234, 0.05647231515522005, -0.2835673309912712, -0.5631986234801009, -0.2835673309912712, -0.5631986234801006, 0.6006827467154858, -0.5932750105917384, 0.6006827467154859, -0.593275010591738, 0.24363277450292076, -0.14517064380485928, 0.24363277450292084, -0.14517064380485925, -0.4381173292277971, 0.8515765445495456, -0.4381173292277971, 0.8515765445495457, -0.4772264554892779, -0.4558040067081244, -0.4772264554892779, -0.4558040067081244, 0.42511520260261526, -0.11760098022868892, 0.4251152026026154, -0.11760098022868892, -0.317536469473846, -0.6047699984659938, -0.31753646947384584, -0.6047699984659937, -0.47946248289928994, -0.6870741625598951, -0.47946248289928994, -0.6870741625598947, 0.24756054302633185, 0.738575212829874, 0.24756054302633188, 0.738575212829874, 0.30991707565082616, -0.1730076242522987, 0.3099170756508263, -0.17300762425229868, 0.1762415438802143, -0.45603299469545666, 0.17624154388021437, -0.4560329946954566, -0.5684090790521096, -0.5323520385817601, -0.5684090790521092, -0.5323520385817597, 1.1773067064626908, -0.31618798230516987, 1.177306706462691, -0.3161879823051697, -0.2853416740347503, -0.7541701445620144, -0.28534167403475025, -0.7541701445620143, -0.3324739283651593, -0.041138670378205386, -0.33247392836515915, -0.041138670378205386, 1.2664180977863824, -0.7401911722318033, 1.2664180977863828, -0.740191172231803, 0.4182693143279388, -0.7039334975576141, 0.41826931432793885, -0.703933497557614, 0.3813359912592416, -1.0453256669790556, 0.3813359912592416, -1.0453256669790554, 0.6509129030314083, -0.5412696201327558, 0.6509129030314084, -0.5412696201327558, 0.12018094767199916, 0.5279211204926886, 0.12018094767199916, 0.5279211204926887, -0.45305717081196895, 0.008198588994697165, -0.45305717081196883, 0.008198588994697166, 1.1671283999119613, -0.15065449704305311, 1.167128399911962, -0.1506544970430531, -0.9008096320814036, 0.1402761647761295, -0.9008096320814036, 0.14027616477612953, -0.33154219658246964, 0.2612070104089204, -0.3315421965824696, 0.2612070104089204, -0.03280139984795011, -0.46647401981355685, -0.032801399847950094, -0.46647401981355685, 0.01502591710973531, -0.5159959791954403, 0.015025917109735313, -0.51599597919544, 0.08126445056757484, -0.059451961687364746, 0.08126445056757486, -0.05945196168736473, -0.4257412994811337, -0.20546840486340784, -0.4257412994811336, -0.20546840486340776, 0.38799639318217627, 0.3512270928822726, 0.3879963931821764, 0.35122709288227266, 0.21154693848150546, -0.03634275654418231, 0.21154693848150552, -0.0363427565441823, -0.23511045964865424, -0.3182820554745927, -0.23511045964865424, -0.3182820554745926, -0.27930734350964126, -0.34019779603069944, -0.27930734350964115, -0.3401977960306993, -0.7191434211894179, 0.018581718879366438, -0.7191434211894179, 0.018581718879366448, -0.020348708221664874, -0.11541476308320475, -0.020348708221664864, -0.11541476308320471, -0.869130537954744, 0.5168791425703672, -0.8691305379547439, 0.5168791425703672, -0.30797478551715907, 0.16894312777393505, -0.30797478551715896, 0.16894312777393514, -0.3412253953512523, -0.13703919671643483, -0.3412253953512523, -0.1370391967164348, -0.2363788997551411, 0.020160959823633195, -0.2363788997551411, 0.020160959823633202, -1.1342573157600304, -1.0490903515949865, -1.1342573157600302, -1.0490903515949863, -0.7951801524174422, -0.39048765852721024, -0.7951801524174421, -0.39048765852721024, -0.37682393173602985, -0.7154876526440125, -0.37682393173602974, -0.7154876526440123, -0.7261698499159233, 0.25576182656428276, -0.7261698499159229, 0.25576182656428287, 0.6047122068958138, 0.3531321759458359, 0.604712206895814, 0.35313217594583596, -0.3347865534686024, -0.44639370766792674, -0.3347865534686024, -0.4463937076679267, -0.3162737402922597, -0.6054254978296343, -0.3162737402922597, -0.6054254978296342, -0.38296113359720985, 1.055727844318872, -0.38296113359720985, 1.0557278443188722, -0.002541168924166004, -0.08959542143473792, -0.0025411689241660036, -0.08959542143473788, -0.46847678028199197, 0.3128229066138286, -0.4684767802819919, 0.3128229066138288, -0.7474510887594696, -0.11273520921655422, -0.7474510887594695, -0.11273520921655422, -0.10138857243233154, 0.6540514477632215, -0.10138857243233154, 0.6540514477632217, 0.7025815823095183, -0.6472293123262207, 0.7025815823095184, -0.6472293123262207, 0.7918249248447928, -0.19424553454596438, 0.7918249248447932, -0.19424553454596438, 0.054665259285737594, -0.1426160884627486, 0.05466525928573761, -0.14261608846274854, 0.8678958225451003, 0.7680573370722297, 0.8678958225451004, 0.7680573370722298, 0.2527320686719843, -0.10300747956510839, 0.25273206867198444, -0.10300747956510836, 0.013030931888632663, 0.2996259196764839, 0.013030931888632665, 0.2996259196764839, 1.2101948699429645, 0.7680276029628541, 1.210194869942965, 0.7680276029628543, 0.001739080834353146, 0.7050842932559666, 0.0017390808343531463, 0.7050842932559666, 0.7920805263720672, -0.5649631474553106, 0.7920805263720672, -0.5649631474553105, 0.25575043599568525, 0.0889317006762374, 0.25575043599568525, 0.08893170067623742, 0.09261316731698108, 0.2703067174076892, 0.0926131673169811, 0.27030671740768925, -0.5747802180771169, 0.08613851106223658, -0.5747802180771168, 0.08613851106223662, 0.40507673833837643, -0.8945358512704514, 0.40507673833837643, -0.8945358512704511, 0.3856111747477545, -0.11976774680260635, 0.3856111747477546, -0.11976774680260632, -0.25578702556512617, 0.3677566511805598, -0.255787025565126, 0.36775665118055983, -0.20976738975410314, 0.6671667928732408, -0.20976738975410314, 0.6671667928732408, -0.21007992057543357, 0.11101431938197523, -0.21007992057543348, 0.11101431938197523, -0.5538419739084758, -0.050566470413442005, -0.5538419739084757, -0.05056647041344199, -0.26983745787555147, -0.005254721629673997, -0.2698374578755514, -0.0052547216296739965, -0.31654388864740896, 0.4356887820490702, -0.3165438886474089, 0.43568878204907036, -0.6124922582532396, -0.22656761299178974, -0.6124922582532395, -0.22656761299178974, 0.5136728866074527, -0.14672923625352396, 0.513672886607453, -0.14672923625352388, -0.06100014188022765, -0.07483055132359873, -0.06100014188022765, -0.07483055132359868, 0.0632389321030824, -0.3727037315430909, 0.06323893210308244, -0.3727037315430909, -0.6239765829480394, -0.43378186506793615, -0.6239765829480394, -0.43378186506793603, -0.2962023614106011, -0.24082492622254642, -0.296202361410601, -0.24082492622254636, -0.08363974045743232, 0.4635673337808054, -0.08363974045743229, 0.4635673337808054, -0.07869730556773968, 0.7594146318238462, -0.07869730556773967, 0.7594146318238463, 0.559161552723403, 0.26005051714491845, 0.5591615527234033, 0.2600505171449186, 0.009099193447173748, -0.8925628969298484, 0.00909919344717375, -0.892562896929848, -0.01551647656911137, -0.38885814801603924, -0.015516476569111365, -0.38885814801603924, -0.01567035614455939, -0.3579485826040038, -0.015670356144559385, -0.35794858260400375, 0.446781462990565, -0.052239411468506664, 0.446781462990565, -0.05223941146850665, 1.0710389841912518, -0.2731132034289364, 1.0710389841912522, -0.2731132034289364, 0.23533790163003582, -0.23476194158747798, 0.23533790163003585, -0.23476194158747793, 0.07915424936926652, 0.6036539628377416, 0.07915424936926652, 0.6036539628377419, 0.6311044368999582, -0.6562564634414947, 0.6311044368999585, -0.6562564634414947, -0.21077148265812098, 0.032523815759867236, -0.2107714826581209, 0.03252381575986725, -0.7231240597670221, -0.006544627251553192, -0.7231240597670221, -0.006544627251553192, -0.08060584759784664, 0.13336777305165762, -0.08060584759784663, 0.13336777305165762, 0.48597827619774187, -0.6069162101181359, 0.48597827619774203, -0.6069162101181359, -0.4507483055292626, 0.19434862886898324, -0.4507483055292625, 0.19434862886898324, 0.2827195867383647, -0.22519487430374507, 0.2827195867383647, -0.22519487430374502, -0.8215093346304647, -0.03268014435976413, -0.8215093346304647, -0.03268014435976413, -0.11933763497114419, 0.25235131805383626, -0.11933763497114419, 0.25235131805383626, -0.050641541900826315, -0.05481336786080909, -0.05064154190082631, -0.05481336786080908, 0.37639163137503584, -0.04913023720926801, 0.37639163137503595, -0.049130237209268006, 0.2754899163868257, -1.2892018379461803, 0.27548991638682585, -1.28920183794618, 0.19113786193208002, -0.49992907513642937, 0.1911378619320801, -0.4999290751364293, -0.18408107881733532, -0.6738283284096425, -0.18408107881733524, -0.6738283284096425, 0.26736586776080096, 0.35645201936711196, 0.2673658677608011, 0.35645201936711196, 1.1765511302564113, -0.5480893596413949, 1.176551130256412, -0.5480893596413949, 1.1542398998705217, -0.3147952918363603, 1.1542398998705217, -0.3147952918363603, -0.6689853024562176, 0.8040377543458188, -0.6689853024562172, 0.804037754345819, 0.24120212235388105, -0.07423471553787372, 0.2412021223538811, -0.0742347155378737, 0.5689391732853385, -0.4334628652354342, 0.5689391732853388, -0.43346286523543415, -0.4229071860412019, 0.11827577249881677, -0.4229071860412019, 0.11827577249881677, -0.5721332694193333, 0.26812444739865027, -0.5721332694193333, 0.26812444739865043, -0.14648803653271852, 0.4305316791577641, -0.1464880365327185, 0.43053167915776425, 0.05374623984152754, -0.4459959249147729, 0.053746239841527564, -0.4459959249147729, 0.5896530144495327, 0.07735649659442079, 0.589653014449533, 0.07735649659442081, -0.25257596915203095, -0.1831343633500895, -0.2525759691520309, -0.18313436335008942, 0.6519199000082152, 0.8113502122689806, 0.6519199000082153, 0.811350212268981, -0.20987680281715365, 0.31018961232143716, -0.2098768028171536, 0.3101896123214372, 0.488852615545995, -0.7694857263920457, 0.488852615545995, -0.7694857263920457, 0.32498664525642773, 0.35466894818618966, 0.3249866452564279, 0.3546689481861898, -0.21867254773101694, 0.33653237135631914, -0.21867254773101685, 0.3365323713563192, -0.1628632057456908, 0.12513912098254698, -0.16286320574569077, 0.12513912098254704, -0.2482127546806861, 0.054592620932045616, -0.24821275468068604, 0.05459262093204564, 0.19972864932719311, 0.48470032915534, 0.19972864932719311, 0.4847003291553401, 0.5194203708908046, 0.6086898891039105, 0.519420370890805, 0.6086898891039109, 0.19766219439600413, -0.624494348335875, 0.1976621943960042, -0.6244943483358748, -0.6659766058933296, 0.5642507949642299, -0.6659766058933294, 0.56425079496423, 0.6380303702196312, 0.7911458327140173, 0.6380303702196312, 0.7911458327140173, -0.2639580944341406, 1.0973674142268384, -0.26395809443414053, 1.0973674142268388, -0.013043068475538544, -0.18048505417693753, -0.013043068475538539, -0.1804850541769375, -0.6177459783187123, -0.2779905668540201, -0.6177459783187123, -0.27799056685401996, 0.6541020344580163, 0.582124792529954, 0.6541020344580166, 0.5821247925299543, -1.0384774049322054, 0.8009193618277922, -1.0384774049322048, 0.8009193618277922, -0.1554306169575903, 0.44885645072316704, -0.15543061695759022, 0.4488564507231671, -0.21901225075291414, 0.029572470395186623, -0.21901225075291408, 0.029572470395186626, 0.06665349581693292, 0.2278463140029154, 0.06665349581693296, 0.22784631400291547, -0.18730209014152358, -0.44204961843797247, -0.1873020901415235, -0.44204961843797247, -0.8954194222707068, -0.09622762051569644, -0.8954194222707068, -0.09622762051569644, 0.6876813467148475, -0.1006745035590906, 0.6876813467148476, -0.10067450355909059, 0.8020144882556199, -0.4557444532553835, 0.80201448825562, -0.4557444532553834, 0.11678579588295551, 0.4778013596576872, 0.11678579588295553, 0.4778013596576872, -0.6173779479953273, -0.1463086195272349, -0.6173779479953271, -0.1463086195272348, 0.04109570275886973, -0.38022576288843984, 0.04109570275886973, -0.3802257628884398, 0.8314003498756972, -0.48166469434786263, 0.8314003498756976, -0.4816646943478625, -0.3417449594665635, 0.2351852756985343, -0.34174495946656336, 0.23518527569853434, -0.747231864230736, -0.05533196936496787, -0.7472318642307357, -0.055331969364967856, 0.44786515872763016, -0.8581662077619436, 0.4478651587276303, -0.8581662077619435, 0.2394196493059546, 0.5685962507505915, 0.23941964930595466, 0.5685962507505915, -0.47370747024486054, -0.518217306207919, -0.4737074702448605, -0.5182173062079186, -0.24686466238928517, 0.5140980999371543, -0.24686466238928517, 0.5140980999371544, 0.4465869335283311, -0.37822156772624715, 0.4465869335283311, -0.378221567726247, 0.7216840280411014, -0.12155234552799939, 0.7216840280411017, -0.12155234552799934, 0.015204864396908546, 0.6376683618342354, 0.015204864396908548, 0.6376683618342357, -0.42393694982300156, -0.5218089477315881, -0.42393694982300145, -0.5218089477315878, 0.07415078821601045, 0.6371956908817733, 0.07415078821601047, 0.6371956908817734, -0.1903574628038755, -0.38684400671343444, -0.19035746280387544, -0.38684400671343444, -0.3773559131237457, 0.0068579608273421355, -0.3773559131237457, 0.006857960827342137, 0.08501466839094085, 0.27421860297639405, 0.08501466839094089, 0.2742186029763941, 1.3703190609240201, -0.6705242349995242, 1.3703190609240201, -0.6705242349995238, 0.22067502222484947, -0.42972719575427676, 0.22067502222484955, -0.4297271957542766, 0.4496324731373458, -0.5997904924904096, 0.44963247313734583, -0.5997904924904094, 0.4606769016215748, -0.4028663766293615, 0.4606769016215748, -0.4028663766293614, 0.20461881450521396, 0.23845839738985905, 0.20461881450521396, 0.2384583973898591, -0.177021903697815, 0.0017472361069717779, -0.17702190369781493, 0.0017472361069717785, 0.33088666738271627, 0.39635242461181414, 0.33088666738271644, 0.39635242461181425, -0.5126793030962896, -0.9816818891160128, -0.5126793030962894, -0.9816818891160127, -0.20315580021343643, 0.25993483522132416, -0.2031558002134364, 0.2599348352213242, 0.01157315314252727, -0.0752286580183012, 0.011573153142527272, -0.07522865801830117, -0.2122874953702656, 1.0455265018271471, -0.2122874953702656, 1.0455265018271478, -0.4118959539781374, 0.2565463745780656, -0.41189595397813733, 0.2565463745780657, -0.40504807761153394, -0.826767279687959, -0.40504807761153383, -0.8267672796879587, 0.8728370056581523, -0.8489146211330629, 0.8728370056581523, -0.8489146211330626, -0.15484731030271964, 0.2978543674333216, -0.15484731030271962, 0.2978543674333217, 0.9598395979151622, -0.021475535817715843, 0.9598395979151622, -0.021475535817715833, -0.3813769756912948, 0.7192828208488169, -0.38137697569129464, 0.719282820848817, 0.21951101473819934, 0.6480843500744788, 0.21951101473819934, 0.6480843500744791, -0.3113427744080721, 0.045948715073330315, -0.31134277440807195, 0.045948715073330336, -0.16009981684527497, -0.17250123317199526, -0.16009981684527497, -0.17250123317199526, 0.25568807750253153, 0.30423782531372767, 0.2556880775025317, 0.30423782531372784, 0.2534978588720535, 0.41258202395216825, 0.25349785887205356, 0.4125820239521684, -0.22823188438717018, 0.3555909158613313, -0.22823188438717018, 0.3555909158613314, -0.043847734475191566, 0.546988883272136, -0.04384773447519155, 0.5469888832721362, 0.0022848127328267687, 0.16581911916150355, 0.0022848127328267695, 0.16581911916150358, -0.9664510167365821, 0.5772556019222926, -0.9664510167365818, 0.5772556019222929, 0.19331577714046103, 0.16819098929912168, 0.1933157771404611, 0.16819098929912168, 0.880938028512706, 1.3996876457175011, 0.8809380285127063, 1.3996876457175018, -0.6403207225525454, 0.2297596920614577, -0.640320722552545, 0.22975969206145774, -0.926993144927124, -0.7404608887419831, -0.9269931449271237, -0.7404608887419828, -0.30368277421537726, -0.5055446699316368, -0.3036827742153772, -0.5055446699316366, 0.5466694604144853, 0.07004761038909013, 0.5466694604144854, 0.07004761038909016, 0.25500851421300097, -0.29367076034138706, 0.25500851421300114, -0.29367076034138695, 0.15138727668563495, -0.0049418965549759275, 0.151387276685635, -0.004941896554975927, -0.43887856303510187, 0.8136477342030863, -0.4388785630351018, 0.8136477342030866, -0.33880265875092413, -0.31551224415527107, -0.33880265875092397, -0.315512244155271, 1.377423681456482, 0.012704561359672462, 1.377423681456482, 0.012704561359672462, -0.041263422421853435, 0.4035844851267748, -0.041263422421853414, 0.40358448512677497, -0.08610165644909173, -0.7986737010728233, -0.08610165644909172, -0.7986737010728232, 0.3836918938530838, 0.8390085156051033, 0.38369189385308383, 0.8390085156051033, -0.17307936456124118, -0.06474709047756155, -0.1730793645612411, -0.06474709047756153, -0.02753475823767776, -0.15870621273858665, -0.02753475823767775, -0.15870621273858657, -0.5116996522331295, -0.4553457116638264, -0.5116996522331294, -0.45534571166382637, 0.6086269804673172, 0.015815755110900165, 0.6086269804673176, 0.015815755110900165, -0.3066696359213093, -0.6490796718967194, -0.3066696359213093, -0.6490796718967194, 0.2573582808012723, 0.49429943061451787, 0.25735828080127243, 0.4942994306145179, -0.5573569025227104, 0.10864971359925568, -0.5573569025227101, 0.1086497135992557, 0.10100854569812368, -0.5775400700305715, 0.10100854569812368, -0.5775400700305712, 0.16011849083924728, -0.5182501761924749, 0.1601184908392473, -0.5182501761924749, 1.1626364195660153, -0.027141868869618918, 1.162636419566016, -0.027141868869618915, -0.45286020053725284, 0.46618578082394724, -0.4528602005372528, 0.4661857808239473, 0.32258327609642495, -0.2102016160014837, 0.3225832760964251, -0.21020161600148368, -0.4469041249092892, -0.30385833257152894, -0.4469041249092891, -0.30385833257152894, 0.8377224062973287, -0.5225876068528582, 0.8377224062973289, -0.5225876068528581, -0.35063350958529577, -0.44521824304962737, -0.3506335095852957, -0.44521824304962726, 0.042917945172412694, -0.2699072536318396, 0.0429179451724127, -0.2699072536318395, 0.28617439894992625, -0.6241441143108587, 0.28617439894992625, -0.6241441143108584, -0.21331655993940007, 1.1315954154549954, -0.21331655993940002, 1.1315954154549959, -0.7071603986591413, -0.0587365030909921, -0.7071603986591409, -0.0587365030909921, -0.43104678259786616, -0.4031905103539523, -0.4310467825978661, -0.40319051035395215, 0.479647329346727, -0.6208557999362405, 0.47964732934672716, -0.6208557999362404, -0.27104983788326825, 0.005338803231299233, -0.2710498378832682, 0.0053388032312992354, -0.0041329173810210895, 0.3935166528530436, -0.004132917381021089, 0.39351665285304366 }; 114 | validate(coords2); 115 | } 116 | -------------------------------------------------------------------------------- /test/main.test.cpp: -------------------------------------------------------------------------------- 1 | #define CATCH_CONFIG_MAIN 2 | #include 3 | -------------------------------------------------------------------------------- /test/test-files/map-25p-epsg-3857.geojson: -------------------------------------------------------------------------------- 1 | { 2 | "type": "FeatureCollection", 3 | "name": "map-25p", 4 | "crs": { "type": "name", "properties": { "name": "urn:ogc:def:crs:EPSG::3857" } }, 5 | "features": [ 6 | { "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 1464686.336000547511503, 6917398.185751880519092 ] } }, 7 | { "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 1479667.993544442113489, 6923360.273958121426404 ] } }, 8 | { "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 1487617.444486100459471, 6904556.76499997638166 ] } }, 9 | { "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 1524612.966176125919446, 6893702.70698347967118 ] } }, 10 | { "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 1522472.729384140809998, 6916328.067355887033045 ] } }, 11 | { "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 1506573.827500824118033, 6909448.734810220077634 ] } }, 12 | { "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 1486088.703920396743342, 6888963.61122979503125 ] } }, 13 | { "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 1500917.487407721113414, 6881931.404627557843924 ] } }, 14 | { "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 1469731.179867369355634, 6898900.424906868487597 ] } }, 15 | { "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 1502751.976086565293372, 6896913.062171457335353 ] } }, 16 | { "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 1484101.34118498233147, 6877498.056987018324435 ] } }, 17 | { "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 1463310.469491414260119, 6878568.175383010879159 ] } }, 18 | { "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 1511771.545424216194078, 6883613.019249833188951 ] } }, 19 | { "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 1489910.555334655800834, 6869395.731988795101643 ] } }, 20 | { "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 1495261.147314618108794, 6909601.608866788446903 ] } }, 21 | { "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 1465756.454396540066227, 6868937.109819080680609 ] } }, 22 | { "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 1505656.583161402028054, 6871077.346611065790057 ] } }, 23 | { "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 1501223.235520861810073, 6924277.518297546543181 ] } }, 24 | { "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 1516204.893064756412059, 6908072.868301087059081 ] } }, 25 | { "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 1460252.988360007293522, 6894161.329153183847666 ] } }, 26 | { "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 1476916.260526175843552, 6867255.495196804404259 ] } }, 27 | { "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 1497095.635993462288752, 6865115.25840481929481 ] } }, 28 | { "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 1512841.663820208515972, 6919691.296600436791778 ] } }, 29 | { "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 1496484.139767180895433, 6907767.120187944732606 ] } }, 30 | { "type": "Feature", "properties": { }, "geometry": { "type": "Point", "coordinates": [ 1476610.512413035146892, 6920914.289053001441061 ] } } 31 | ] 32 | } 33 | -------------------------------------------------------------------------------- /test/test-files/playgrounds-1356-triangles.json: -------------------------------------------------------------------------------- 1 | [935,53,798,935,931,53,47,743,53,53,755,798,798,936,935,743,927,53,743,49,927,1325,936,798,931,1012,53,743,47,49,48,47,53,1012,48,53,1012,926,48,931,354,1012,1012,354,926,755,53,927,1233,1234,931,49,755,927,354,1190,926,926,1238,48,755,1325,798,755,563,1325,697,829,354,354,829,1190,1238,926,585,988,1238,585,48,1238,47,47,310,49,49,574,755,563,349,1325,1325,349,936,536,349,563,1234,242,931,931,242,354,1238,310,47,599,203,310,310,203,49,930,536,563,242,697,354,1233,935,1266,1233,931,935,242,705,697,1266,935,936,379,761,1233,1233,761,1234,1234,1291,242,700,699,706,697,699,829,706,699,697,699,700,829,930,563,755,349,451,936,298,705,242,705,706,697,985,988,585,1238,599,310,706,698,700,700,698,829,985,986,988,988,987,1238,926,1190,585,988,986,987,987,599,1238,451,1266,936,574,930,755,585,1190,541,598,599,987,536,451,349,379,1291,761,761,1291,1234,705,704,706,706,704,698,660,1173,1266,1266,1173,1233,598,987,638,203,574,49,638,987,986,985,638,986,754,762,573,599,762,203,541,1190,829,985,33,638,1173,379,1233,442,298,1291,1291,298,242,298,704,705,754,574,762,762,574,203,1265,660,1266,1173,660,379,2,1265,451,451,1265,1266,701,703,704,704,703,698,1147,541,829,298,701,704,701,702,703,703,918,698,585,33,985,638,577,598,573,762,599,570,2,1268,1265,2,660,1227,918,1097,701,918,702,702,918,703,458,829,698,585,380,33,573,599,598,574,1249,930,918,458,698,401,573,717,554,1249,574,930,569,536,570,339,2,339,340,2,2,340,660,660,970,379,34,380,585,717,573,598,573,401,754,754,554,574,577,638,33,1097,918,701,918,1227,458,442,1097,298,298,1097,701,2,451,1268,340,970,660,570,341,339,339,341,340,1147,199,541,541,34,585,458,1147,829,588,200,450,199,200,541,817,321,1249,1249,569,930,200,34,541,380,578,33,1227,1226,458,458,333,1147,1097,1226,1227,774,451,536,341,970,340,442,857,1097,1226,923,458,570,970,341,717,554,401,401,554,754,321,569,1249,200,588,34,450,200,199,569,772,536,588,578,34,34,578,380,1147,450,199,853,577,578,1194,774,772,772,774,536,1194,772,569,0,921,321,321,921,569,853,578,1257,578,577,33,577,717,598,817,0,321,1075,54,774,774,54,451,54,1268,451,570,1071,970,817,1249,554,921,1194,569,1250,817,554,73,1250,554,717,73,554,957,958,857,1226,958,923,923,653,458,1147,333,450,958,1226,857,857,1226,1097,854,853,1257,577,886,717,538,226,73,1256,1194,921,442,1291,379,1257,578,588,853,856,577,856,855,854,854,855,853,1258,856,854,855,856,853,450,1257,588,1259,1258,1257,1257,1258,854,1268,1071,570,970,442,379,450,1259,1257,1258,1259,856,383,5,0,0,5,921,383,0,817,857,663,957,957,663,958,958,653,923,226,817,1250,507,383,817,648,653,958,553,597,1259,1231,886,856,856,886,577,876,442,970,873,858,663,1076,1075,452,1194,1075,774,54,198,1268,1268,513,1071,538,73,717,73,226,1250,873,663,857,663,647,958,647,648,958,553,1259,450,1259,597,856,858,647,663,452,1075,1194,1075,1076,54,493,921,5,1256,452,1194,747,873,857,858,215,647,226,507,817,383,1148,5,1077,198,54,507,1148,383,648,708,653,653,333,458,215,708,648,1191,708,197,146,1077,1076,1076,1077,54,1066,876,970,605,747,857,1196,876,1066,1187,333,653,1251,1245,886,886,1245,717,226,571,507,1245,538,717,149,1153,198,198,1223,1268,1224,1223,1153,1153,1223,198,19,493,5,452,146,1076,149,1224,1153,1223,1224,1268,493,1256,921,1066,970,1071,876,1196,442,625,396,538,538,396,226,1303,1187,653,333,553,450,1148,19,5,493,1255,1256,1077,149,198,1162,149,1077,19,1255,493,1256,1255,452,597,1231,856,605,857,442,873,747,858,471,884,1196,1196,884,442,513,1066,1071,1262,1251,886,1245,625,538,1261,553,333,125,1229,1231,1246,146,452,1231,1262,886,625,1245,1251,825,571,396,396,571,226,507,712,1148,1148,712,19,976,513,1224,1224,513,1268,877,605,442,215,648,647,146,938,1077,149,1182,1224,1172,604,108,605,604,747,1335,1182,149,1162,1335,149,938,1162,1077,1160,1161,1162,1162,1161,1335,471,1150,884,884,1150,442,877,1150,471,938,1160,1162,1161,1349,1335,586,712,507,448,1246,826,632,938,146,632,1350,938,215,858,747,708,1191,653,908,1261,1187,1187,1261,333,1146,215,747,1319,684,1262,1262,684,1251,1246,452,1255,938,1350,1160,1160,1084,1161,1335,1349,1182,1246,1255,826,206,1262,1231,969,1319,1262,632,1084,1350,1350,1084,1160,1182,976,1224,215,197,708,304,295,712,712,295,19,1229,206,1231,125,1231,126,959,632,146,1084,1349,1161,1247,969,206,206,969,1262,622,625,684,684,625,1251,215,1112,197,197,1112,1191,1146,1112,215,1180,1303,1191,1191,1303,653,1112,1180,1191,1348,1349,1084,487,1348,1084,1349,356,1182,1231,597,124,126,1231,124,1230,1247,206,76,908,1187,1261,359,553,124,597,564,909,1247,1230,959,1339,632,632,487,1084,911,684,1319,571,586,507,462,1334,1118,1339,487,632,537,586,571,625,825,396,861,359,860,860,359,1261,359,239,553,206,1229,1230,969,911,1319,304,279,295,295,279,19,564,597,523,126,124,125,1230,1229,880,1247,909,969,880,1229,125,908,860,1261,861,239,359,586,304,712,863,239,861,462,356,1348,1348,356,1349,31,976,1182,513,1046,1066,863,862,860,860,862,861,976,1046,513,360,863,469,862,863,861,1172,747,604,1172,1146,747,225,940,1180,487,462,1348,1040,1041,893,462,487,1334,959,146,1246,686,911,1310,1230,911,909,909,911,969,725,724,825,304,284,279,279,280,19,628,284,304,537,186,586,586,186,304,284,280,279,108,604,605,186,628,304,284,178,280,31,1182,356,976,1041,1046,471,1196,355,826,1255,19,621,619,625,859,537,571,1118,1058,462,462,1058,356,178,305,628,628,305,284,1334,487,1339,355,1066,1046,1150,877,442,859,571,825,165,178,628,893,1041,976,1041,1040,1046,622,621,625,725,825,625,911,622,684,448,959,1246,181,620,621,621,620,619,1118,1117,1058,1058,31,356,1165,1117,1118,959,1334,1339,1120,1059,1117,1117,1059,1058,523,597,553,124,880,125,826,449,448,448,449,959,1318,1165,1334,1334,1165,1118,1318,1334,959,725,619,620,725,625,619,726,725,620,376,523,239,239,523,553,225,1112,1146,225,1180,1112,1180,940,1303,1303,76,1187,787,225,1146,852,218,1172,1172,218,1146,461,1058,1059,461,31,1058,1239,893,976,355,1196,1066,1355,1318,959,1165,1120,1117,153,726,620,725,726,724,724,726,825,1045,1039,893,893,1039,1040,686,1163,911,911,1163,622,622,1163,621,1043,1046,1040,788,835,218,1119,461,1059,1044,1045,188,153,859,726,726,859,825,1166,1355,1167,1318,1120,1165,1045,1043,1039,1039,1043,1040,218,835,1146,1355,1120,1318,750,565,564,564,55,124,667,911,1230,1163,181,621,1167,1355,959,1355,1166,1120,979,473,386,225,473,940,940,473,1303,789,786,835,835,786,1146,1175,1167,959,1166,1168,1120,1239,976,31,1119,1107,461,1167,1168,1166,1127,1168,1123,788,789,835,786,787,1146,788,218,400,178,826,280,280,826,19,476,1175,959,1119,1059,1120,461,1177,31,750,55,565,565,55,564,1152,1119,1127,1070,1177,1107,1107,1177,461,108,605,877,789,787,786,788,787,789,476,959,449,1127,1119,1120,188,1045,893,1045,1044,1043,1043,355,1046,398,476,449,468,1174,1175,1175,1174,1167,1119,1129,1107,1310,181,686,686,181,1163,375,967,123,1127,1120,1168,1053,1239,31,1123,1168,1167,1124,1123,1167,1127,1126,1152,1174,1124,1167,1123,1126,1127,1125,1126,1123,1128,1129,1152,1152,1129,1119,523,750,564,55,566,124,476,468,1175,1007,1106,1124,1124,1125,1123,398,468,476,165,628,186,305,178,284,165,186,537,1106,1125,1124,1126,1125,1152,375,355,967,355,392,471,1053,31,1177,967,355,1043,1158,1128,1152,1129,1070,1107,1086,188,641,1239,188,893,1062,1070,237,1128,1070,1129,181,153,620,408,165,71,750,566,55,967,1049,1038,375,392,355,967,1043,1049,172,165,408,979,998,473,473,998,1303,469,863,860,1244,190,1295,788,388,787,1106,1152,1125,237,1070,1063,1070,1062,1177,76,1037,908,863,376,239,523,250,750,1007,1124,1174,237,1053,1062,1062,1053,1177,1063,1070,1128,131,880,566,566,880,124,1248,131,407,407,131,566,131,1248,880,1063,1237,237,237,1237,1053,1053,1178,1239,1049,1043,1044,967,948,123,1049,1044,1050,132,881,880,667,1310,911,822,821,153,1064,1063,1158,1159,1151,1347,1106,1151,1152,1050,1044,1086,998,76,1303,667,1230,880,1248,132,880,881,667,880,731,132,661,165,537,71,165,172,178,525,486,826,398,1174,468,1049,266,1038,1038,266,967,22,392,375,1158,1063,1128,1063,238,1237,1237,1178,1053,1042,948,967,1181,1158,1151,1151,1158,1152,386,473,225,120,119,76,1159,1181,1151,1065,238,1064,84,1042,266,266,1042,967,108,852,1172,787,453,225,1304,1244,1295,108,189,852,108,190,1244,1065,1064,1158,1064,238,1063,469,908,1037,469,860,908,750,407,566,982,469,1037,108,877,922,1244,189,108,1086,1044,188,1049,84,266,238,1178,1237,922,877,495,1304,1305,1244,22,375,123,1007,1151,1106,1181,1159,1158,238,1065,1178,398,449,826,1159,1065,1158,317,863,360,317,376,863,318,317,360,190,1305,1295,1295,1305,1304,376,25,523,317,533,376,533,318,360,990,398,826,731,667,132,132,667,881,495,877,471,641,188,1239,1050,84,1049,1110,1239,1178,399,400,879,852,400,218,922,190,108,1305,189,1244,120,76,78,76,119,1037,469,533,360,879,400,852,400,388,788,78,76,998,119,982,1037,524,990,826,398,1007,1174,1253,479,1065,640,189,1305,189,97,852,1110,479,1254,1065,479,1178,822,153,181,153,821,859,822,181,1310,74,250,25,25,250,523,74,25,376,156,388,399,399,388,400,44,822,1310,68,537,859,1200,74,1202,209,533,469,318,533,317,1253,1065,1159,479,1110,1178,749,495,471,922,955,190,190,107,1305,1201,250,1200,1201,1198,250,250,1198,750,1156,22,948,948,22,123,392,749,471,1156,948,1155,98,878,979,979,878,998,495,955,922,879,852,97,407,132,1248,667,910,1310,84,948,1042,22,21,392,831,407,750,879,156,399,945,98,979,879,97,568,228,831,1198,1198,831,750,568,97,567,641,748,1086,1086,748,1050,1156,21,22,955,107,190,748,84,1050,1263,1155,948,1156,1155,21,661,910,731,731,910,667,990,1007,398,1007,1347,1151,1347,1253,1159,1110,114,1239,52,1254,1253,1253,1254,479,639,107,109,639,640,107,107,640,1305,109,107,955,567,97,1020,113,78,878,878,78,998,1242,1202,1353,110,109,1193,639,110,640,109,955,184,1200,250,74,831,315,407,68,859,1085,525,826,178,137,1347,1007,837,114,1110,748,85,84,114,641,1239,1202,74,376,97,189,1020,879,32,156,1220,1198,1201,1220,228,1198,62,1220,1201,1197,1199,228,228,1199,831,220,661,132,1020,189,110,568,32,879,69,68,848,1085,859,821,68,71,537,848,68,236,68,70,71,1200,61,1201,227,1197,228,69,70,68,71,514,408,234,228,1220,1199,315,831,110,189,640,567,420,568,62,1219,1220,1020,420,567,1219,234,1220,61,62,1201,1219,227,234,60,62,61,220,132,407,1085,821,824,221,220,407,453,388,720,453,787,388,847,72,70,70,72,71,32,388,156,1202,60,1200,1200,60,61,59,227,1219,234,227,228,821,822,824,69,848,70,848,847,70,72,514,71,982,119,120,533,1202,376,59,62,60,59,1219,62,1197,315,1199,229,59,60,137,1252,1347,1347,1252,1253,837,1006,114,137,1007,1016,824,822,735,848,514,847,524,1007,990,975,32,568,719,386,453,453,386,225,184,955,495,109,110,639,1020,975,420,719,720,32,427,315,1197,137,52,1252,1252,52,1253,945,1036,98,98,1036,878,78,345,120,837,1110,1254,114,559,641,824,236,1085,1085,236,68,32,720,388,719,32,1072,1061,837,1254,113,345,78,525,464,550,525,178,172,137,1016,52,486,230,826,230,524,826,144,982,120,386,945,979,1036,113,878,579,945,841,482,525,550,486,219,230,230,480,524,579,113,1036,220,222,661,661,222,910,221,222,220,525,172,464,525,482,486,112,981,982,982,981,469,112,982,144,44,1310,910,482,219,486,315,221,407,483,550,484,481,480,219,514,72,847,52,1061,1254,837,253,1006,559,114,1006,559,960,641,641,85,748,84,474,948,144,120,345,981,209,469,749,392,21,676,184,495,6,514,236,236,514,848,253,559,1006,184,1193,109,110,1192,1020,481,219,482,219,480,230,524,1016,1007,1260,965,964,483,481,550,550,481,482,576,144,345,945,579,1036,113,576,345,841,945,386,975,568,420,720,719,453,59,229,227,227,427,1197,315,427,221,1202,229,60,1111,229,1202,484,1113,485,481,1114,480,484,550,1113,253,965,1260,1061,253,837,483,1114,481,484,485,483,1113,464,1116,782,783,559,559,783,960,960,85,641,1113,550,464,485,1114,483,177,1192,110,302,841,154,205,576,113,506,85,960,1155,1263,21,1242,1111,1202,229,427,227,913,1263,474,464,172,408,1113,1114,485,443,1016,524,1115,1114,1113,216,782,559,783,506,960,603,1115,1116,1116,1115,1113,1192,975,1020,1263,749,21,358,678,749,749,676,495,678,191,749,175,177,1193,358,81,678,678,81,191,191,676,749,80,676,191,1054,466,1192,735,44,736,689,44,910,1104,1105,514,358,80,81,81,80,191,154,841,386,841,302,579,154,386,719,753,358,665,80,679,676,253,216,559,782,506,783,1111,427,229,736,44,916,675,679,80,177,110,1193,353,184,352,1192,466,975,975,1072,32,910,222,689,44,735,822,465,464,408,1115,603,1114,464,603,1116,1114,758,480,980,506,1013,474,1263,948,361,154,1149,247,113,579,689,222,221,735,736,824,974,465,408,464,166,603,474,84,85,665,358,749,1029,13,679,679,13,676,1013,506,782,506,971,85,680,675,358,358,675,80,352,676,13,352,184,676,135,352,13,680,677,675,675,677,679,1104,6,548,514,1105,408,1260,1013,216,216,1013,782,1260,216,253,1013,972,980,980,971,506,1329,1327,1326,972,971,980,175,1193,184,12,1054,1192,1149,154,719,352,135,353,353,1026,184,802,135,13,135,1026,353,465,166,464,603,166,1114,549,166,465,753,680,358,677,1029,679,1353,1202,1352,1111,1313,427,362,1026,135,362,1027,1026,1026,1027,184,1243,1241,1242,1242,1241,1111,209,981,112,1352,1202,533,1353,1243,1242,1241,1243,1111,1105,974,408,177,180,1192,185,180,177,665,749,1263,680,1029,677,240,1029,680,1027,175,184,913,665,1263,753,240,680,665,664,753,548,6,7,1121,1122,974,247,579,302,208,209,112,1329,85,971,1329,474,85,913,778,665,1329,971,1327,208,112,1341,1072,975,466,154,361,302,180,12,1192,23,1072,466,740,12,180,23,466,1054,1341,112,144,710,176,504,175,176,177,504,711,673,1327,971,1328,1329,1326,474,1328,971,500,1326,1328,474,176,185,177,500,971,972,1327,1328,1326,709,1352,533,1353,1324,1243,1312,1313,1324,1243,1313,1111,542,95,427,427,95,221,1324,1313,1243,1313,542,427,196,618,224,778,240,664,576,1341,144,437,1030,209,209,1030,533,710,504,673,176,710,185,185,11,180,278,3,1072,1016,1061,52,1013,1260,972,872,1324,1353,1312,542,1313,778,664,665,664,240,753,808,802,13,176,175,504,710,11,185,1121,974,518,974,968,465,1122,968,974,23,1054,771,1072,3,719,758,1114,166,443,524,929,771,1054,12,504,175,1027,673,11,710,1311,542,1312,1035,66,18,1122,1121,968,549,758,166,518,974,517,914,689,688,142,689,221,1104,514,6,549,465,968,746,247,361,361,247,302,444,437,432,808,13,1029,101,221,95,689,572,44,802,807,135,1121,549,968,809,808,1029,802,799,807,240,809,1029,804,799,802,805,809,806,437,209,208,23,278,1072,1149,746,361,556,278,23,733,683,1352,1352,683,1353,1316,1311,1312,914,572,689,803,799,804,807,362,135,572,916,44,683,872,1353,806,809,240,809,805,808,804,802,808,799,803,807,866,806,240,805,804,808,800,804,866,1316,1312,1324,210,196,224,192,778,913,204,196,210,801,807,803,801,362,807,1284,95,542,1277,101,95,914,690,572,965,253,1092,1260,500,972,618,913,224,1092,253,1061,517,974,548,1121,600,549,549,1215,758,192,913,618,800,803,804,800,801,803,804,805,866,913,474,224,196,204,618,965,281,964,964,281,1260,540,281,965,504,1035,711,711,11,673,1035,504,66,866,805,806,548,974,1105,518,600,1121,771,556,23,278,556,3,872,1316,1324,1317,1316,872,929,524,480,1016,1092,1061,224,607,606,204,194,618,1287,542,1289,1287,1288,542,1030,709,533,683,1317,872,1290,142,101,101,142,221,572,695,916,1289,542,1311,1288,1284,542,1035,11,711,773,1289,944,1287,1286,1288,1289,1286,1287,773,1284,1286,1286,1284,1288,608,195,210,210,195,204,66,504,1027,1035,18,11,66,1027,682,682,490,491,195,194,204,6,824,329,1104,548,1105,1209,1215,1214,758,929,480,1215,1206,1213,29,740,11,11,740,180,944,1289,1279,1289,773,1286,1284,1277,95,224,474,607,195,193,194,740,771,12,994,1317,683,1316,1317,1311,865,866,240,800,865,801,865,240,781,1270,1277,1274,277,240,778,866,865,800,600,518,517,1215,1209,758,1274,1284,1280,1274,1277,1284,1277,1276,101,1270,1276,1277,522,600,517,608,193,195,194,192,618,1280,1284,773,1270,1271,1276,690,688,105,142,688,689,916,695,736,1206,1215,549,1213,1214,1215,1209,1208,758,1204,1206,549,1212,1203,1214,1272,1271,1273,1276,1290,101,600,1204,549,1206,1212,1213,1341,437,208,1030,438,709,307,1341,576,193,192,194,224,608,210,607,612,610,944,1280,773,1273,1271,1270,1273,1270,1274,1271,1290,1276,1281,1273,1274,691,690,105,1203,1209,1214,1203,1208,1209,247,205,113,1290,1271,1272,688,690,914,612,474,611,606,608,224,616,608,606,1281,1272,1273,1281,1290,1272,1212,1206,1204,1212,1214,1213,1208,378,758,192,277,778,1283,944,1279,1280,1281,1274,1210,1212,1216,1275,1281,1280,692,691,105,692,832,694,690,691,572,692,695,572,610,616,607,607,616,606,608,610,193,780,277,776,1216,1212,1204,1212,1210,1203,1203,1207,1208,1205,1207,1203,405,522,517,1211,1205,1210,1149,719,3,247,819,205,674,3,556,539,142,1290,691,692,572,1216,1204,600,1210,1205,1203,718,378,1208,682,1027,362,18,29,11,1297,1216,600,596,500,285,281,500,1260,718,1207,1205,718,1208,1207,546,1211,1216,1216,1211,1210,546,718,1205,378,929,758,1033,1092,1016,539,1275,1280,1281,1275,1290,1283,1280,944,548,405,517,522,1297,600,780,781,277,277,781,240,682,497,66,277,192,636,1279,1289,1311,6,236,824,548,547,405,1100,1279,1311,362,490,682,66,497,18,35,423,771,693,696,695,695,870,736,693,695,692,362,801,490,733,1352,709,733,994,683,1100,1278,1279,636,192,193,781,780,865,1283,539,1280,1275,539,1290,1282,539,1283,35,771,740,771,423,556,949,733,709,694,693,692,1279,1282,1283,1278,1282,1279,832,692,105,693,832,696,1282,1278,539,1100,1311,1317,546,378,718,546,929,378,558,823,1092,870,824,736,733,467,994,915,949,709,545,547,7,7,547,548,1297,546,1216,1211,546,1205,444,438,437,437,438,1030,694,832,693,696,870,695,105,688,142,687,467,997,994,687,1317,1297,522,405,432,437,1341,444,440,438,950,63,952,612,607,474,616,610,608,490,801,865,752,751,497,29,35,740,326,214,328,434,545,7,547,526,405,444,441,440,440,308,438,312,490,865,29,18,497,526,544,1095,545,544,547,869,868,870,870,868,824,915,63,950,562,997,733,444,439,441,915,709,63,432,439,444,29,497,751,422,674,556,819,307,205,205,307,576,329,869,327,868,329,824,546,1024,929,929,626,443,308,912,63,915,950,949,715,626,929,307,432,1341,709,308,63,497,682,752,715,1023,716,1024,1023,929,1023,1024,716,438,308,709,950,952,949,746,819,247,422,556,423,746,904,819,669,596,285,500,596,1328,951,63,912,997,467,733,344,105,539,539,105,142,1169,636,193,780,312,865,716,1024,546,1023,715,929,713,716,714,440,441,308,63,951,952,308,441,744,752,682,491,752,491,490,319,752,490,751,319,29,949,952,562,733,949,562,467,687,994,1278,314,539,202,1100,1317,202,1099,1100,1100,1195,1278,1095,544,434,544,526,547,611,474,1328,610,1169,193,202,201,1099,1099,1195,1100,674,1149,3,1095,24,526,526,24,405,251,776,636,636,776,277,434,544,545,520,329,327,869,329,868,6,434,7,869,214,326,1217,434,6,1095,10,24,714,716,546,716,713,715,715,335,626,335,714,334,963,443,626,1052,1225,674,674,1225,1149,870,214,869,329,907,6,562,952,951,202,1195,201,870,213,214,434,10,1095,24,1297,405,15,1333,35,35,1333,423,15,35,29,326,327,869,744,441,439,912,561,951,870,696,213,326,328,327,962,1016,443,1092,823,965,662,823,558,202,1317,687,201,1195,1099,1333,422,423,311,1297,10,10,1297,24,1195,314,1278,561,562,951,954,202,687,327,907,520,520,907,329,434,311,10,328,907,327,268,907,328,285,500,281,596,611,1328,1195,343,314,314,344,539,139,343,1195,823,540,965,343,344,314,668,611,596,612,920,610,308,561,912,562,954,997,540,285,281,424,426,432,432,426,439,1189,954,561,424,431,419,1342,670,669,669,668,596,670,668,669,159,1052,674,1225,320,1149,1149,904,746,425,424,419,426,744,439,213,696,338,419,431,416,424,425,426,214,274,328,907,1217,6,1240,319,490,752,319,751,261,254,255,214,267,274,416,431,415,425,428,426,267,268,274,274,268,328,418,417,419,419,417,425,424,432,431,261,267,214,415,418,416,416,418,419,417,414,425,431,432,430,905,904,1300,121,430,1302,415,414,418,418,414,417,429,414,415,430,432,307,285,1342,669,670,1346,668,540,351,285,823,662,540,962,443,963,320,904,1149,904,905,819,785,430,121,431,429,415,261,213,338,213,261,214,267,270,268,335,715,713,1343,1342,285,617,920,611,259,270,267,268,269,907,351,1343,285,422,159,674,1052,320,1225,651,159,422,152,422,1333,428,429,785,414,428,425,334,714,337,714,335,713,775,963,626,962,1033,1016,954,687,997,343,139,344,337,714,546,335,775,626,338,696,832,261,255,267,136,1345,1343,1343,1345,1342,1342,1346,670,1345,1346,1342,336,337,546,334,336,335,260,269,270,270,269,268,14,15,29,258,338,832,259,260,270,338,254,261,148,320,1052,727,1033,962,259,267,255,262,148,159,159,148,1052,136,1344,1345,1345,1344,1346,617,611,668,256,255,254,256,259,255,785,429,431,429,428,414,785,431,430,202,139,1195,615,1285,105,258,254,338,257,256,254,1189,561,308,561,954,562,258,832,1028,258,257,254,272,260,259,272,1018,260,15,1331,1333,319,14,29,15,16,1331,1285,832,105,1033,558,1092,662,351,540,1297,336,546,337,336,334,164,351,1031,187,16,738,14,16,15,650,422,152,650,651,422,152,1333,1331,1330,152,1331,615,105,344,1021,1018,477,272,256,257,272,259,256,260,1018,269,269,1018,907,828,1189,308,954,756,202,202,756,139,421,784,650,650,784,651,651,784,159,148,262,320,1025,1217,907,1297,1022,336,999,668,1346,611,920,612,776,312,780,251,312,776,187,1331,16,430,307,1302,428,744,426,421,511,784,784,511,159,320,1300,904,272,257,258,1018,1021,907,785,433,428,351,136,1343,1344,1000,1346,164,136,351,271,272,258,1021,1025,907,272,477,1018,850,478,477,477,478,1021,336,775,335,963,727,962,1033,1296,558,617,211,920,920,211,610,1093,4,136,136,4,1344,1296,662,558,4,1000,1344,4,999,1000,1000,999,1346,421,262,511,511,262,159,1235,650,152,732,421,650,775,727,963,1093,1307,999,1028,271,258,272,850,477,478,1025,1021,16,14,738,187,1330,1331,849,850,272,271,849,272,738,14,319,775,1034,727,727,1034,1033,143,344,139,143,615,344,1028,472,271,1078,756,954,1330,1235,152,297,1235,1330,37,738,510,187,1332,1330,1048,143,139,1028,832,1285,271,472,849,849,472,850,850,472,478,737,739,187,738,737,187,977,1169,211,211,1169,610,1307,617,668,1034,1296,1033,732,925,421,421,925,262,737,1332,739,739,1332,187,39,1240,312,312,1240,490,296,301,158,293,297,296,145,732,300,1235,732,650,659,1028,1285,472,275,478,373,428,433,373,744,428,1067,138,1069,372,433,791,372,373,433,756,1048,139,143,489,615,138,1048,756,1028,275,472,1031,351,662,999,1307,668,104,1031,844,1296,1031,662,925,174,262,262,1300,320,812,307,819,145,174,925,163,160,164,164,1093,136,1028,276,275,275,276,478,1031,163,164,162,161,163,163,161,160,160,161,164,812,819,905,1093,999,4,1031,162,163,161,1093,164,162,1093,161,121,8,785,973,828,744,791,433,785,977,251,1169,1169,251,636,297,732,1235,732,145,925,174,1300,262,435,211,617,435,977,211,973,744,373,744,828,308,162,1056,1093,1093,1056,1307,342,790,8,8,791,785,813,812,838,121,342,8,276,1025,478,790,791,8,812,816,307,814,838,810,812,813,816,815,1302,816,816,1302,307,1294,372,791,436,617,1307,436,435,617,814,813,838,813,814,816,1302,1308,121,814,815,816,885,436,1307,885,77,977,346,1308,1302,1332,297,1330,297,350,296,138,489,143,615,666,1285,1028,654,276,814,1301,815,815,1301,1302,810,1301,814,836,373,372,836,973,373,836,372,1294,791,790,1323,342,121,1308,838,812,905,1301,346,1302,521,954,1189,1048,138,143,818,838,905,810,811,1301,838,811,810,244,666,489,489,666,615,346,342,1308,39,58,1240,1240,58,319,297,290,732,296,158,291,1323,1294,791,836,779,973,293,290,297,470,818,17,838,818,811,811,346,1301,1082,174,145,293,289,290,301,288,158,293,294,289,207,521,828,828,521,1189,992,828,973,291,294,293,299,290,289,292,300,290,290,300,732,296,291,293,294,299,289,1332,350,297,292,299,294,336,1221,775,775,1221,1034,1034,844,1296,1031,104,162,1102,1221,623,311,434,1217,792,1323,342,342,1323,790,795,346,811,1332,37,350,291,158,294,299,292,290,991,779,993,993,779,836,1069,138,1068,138,1067,489,158,292,294,1080,145,300,1080,1082,145,1068,138,1078,1082,1300,174,1081,1080,117,1082,1081,1300,794,811,818,794,795,811,346,445,342,993,836,1294,445,793,446,795,445,346,1078,138,756,1069,1068,1067,1067,244,489,1080,1081,1082,117,1080,300,992,207,828,521,1078,954,1025,311,1217,158,288,292,292,288,300,1332,737,37,276,654,1025,1025,1314,311,659,654,1028,993,1294,591,779,992,973,37,737,738,445,794,793,794,445,795,993,992,991,991,992,779,591,1294,1323,1081,9,1300,1300,9,905,117,9,1081,92,794,818,445,792,342,231,92,818,350,301,296,288,937,300,543,1078,521,322,792,446,446,792,445,91,231,818,92,793,794,94,91,470,231,90,92,46,39,77,251,39,312,510,738,1015,39,251,77,1047,613,301,301,613,288,1047,301,350,94,90,91,91,90,231,793,322,446,792,322,1323,470,91,818,90,87,92,510,1015,509,580,1103,654,654,1103,1025,89,90,94,89,87,90,1047,937,613,613,937,288,88,89,94,87,793,92,17,818,905,88,87,89,1091,793,87,937,117,300,470,88,94,793,796,322,738,319,1015,37,501,350,1090,1091,93,88,1091,87,162,104,1056,1056,104,1307,46,20,39,844,1031,1296,623,1221,336,1221,1102,1034,93,1091,88,1091,1090,793,1015,319,58,510,508,37,1087,93,1232,470,93,88,1090,1088,793,93,1089,1090,509,508,510,46,77,395,39,20,58,509,65,508,917,543,42,42,543,521,521,207,42,93,1088,1089,1089,1088,1090,322,591,1323,56,65,509,501,1047,350,243,659,316,666,659,1285,501,37,508,937,235,117,1232,93,470,93,1087,1088,1088,1087,793,993,1019,992,316,659,666,659,243,654,283,591,1,243,580,654,1103,1314,1025,65,501,508,745,1015,58,65,64,501,1,591,322,591,282,993,283,282,591,1022,623,336,151,937,1047,151,235,937,117,681,9,17,1232,470,57,56,1015,1015,56,509,157,151,593,17,905,9,150,151,157,655,57,1015,56,655,65,42,1145,1144,543,917,1078,1078,1322,1068,311,1022,1297,42,207,1145,842,1034,1102,842,844,1034,842,1102,833,833,903,1336,150,117,235,1087,796,793,283,1,282,251,977,77,657,655,658,1145,207,992,42,1130,917,151,64,593,151,150,235,681,17,9,1019,1145,992,456,58,20,57,655,56,460,681,117,649,1102,623,842,843,844,1232,796,1087,330,1137,1019,891,924,741,796,797,322,1322,1067,1068,244,316,666,243,594,580,1022,649,623,460,157,593,150,460,117,282,1,741,796,1,797,797,1,322,844,1264,104,760,885,1307,531,1264,844,455,456,20,903,833,1102,827,843,842,1336,1337,833,883,1338,1337,1337,1338,833,46,455,20,1130,1322,917,917,1322,1078,1130,42,1137,658,655,642,655,657,65,745,58,456,455,454,456,827,833,1338,827,842,833,658,656,657,657,656,65,316,594,243,580,1314,1103,311,557,1022,1298,903,1102,1336,883,1337,883,827,1338,151,1047,64,157,460,150,64,1047,501,903,883,1336,827,906,843,642,655,1015,656,64,65,843,531,844,885,435,436,248,531,843,633,244,1067,1315,1314,595,454,745,456,1137,1133,1134,1132,1130,1134,394,642,745,745,642,1015,658,64,656,919,26,43,1131,1132,1135,1130,1138,1322,1130,1137,1134,1132,1131,1130,42,1144,1137,1137,1144,1145,1134,1135,1132,1137,1145,1019,331,1135,1133,1133,1135,1134,1131,1136,1130,1137,331,1133,331,1136,1135,1135,1136,1131,903,906,883,883,906,827,1298,906,903,1137,332,331,331,332,1136,330,332,1137,1315,557,311,1022,672,649,649,1298,1102,1019,993,282,332,330,1136,1138,633,1322,672,1298,649,455,394,454,454,394,745,233,232,658,46,395,455,977,435,885,395,394,455,1,891,741,741,36,282,36,1019,282,1306,741,924,36,1306,1019,1298,252,906,906,252,843,1314,594,313,594,1314,580,1307,104,760,395,529,394,1340,26,681,681,26,17,17,492,1232,681,460,182,313,594,316,1314,1315,311,252,248,843,760,104,1264,26,40,17,40,492,17,759,313,707,313,595,1314,1315,595,557,557,672,1022,1298,742,252,961,882,248,182,460,593,26,919,40,40,919,492,1,1009,891,1009,888,891,741,1306,36,1142,1136,330,707,313,316,313,867,595,760,1264,531,1138,1130,1136,1322,633,1067,244,707,316,589,760,531,742,248,252,248,882,531,891,888,889,1306,1222,1019,1098,742,1298,882,589,531,924,1222,1306,1142,1140,1136,759,867,313,595,834,557,557,834,672,984,99,77,77,99,395,394,27,642,182,593,366,644,77,885,796,1009,1,924,324,1222,796,1232,1009,891,323,924,890,888,1009,593,64,366,325,182,366,1009,1232,492,888,890,889,889,892,891,1009,892,890,890,892,889,892,323,891,241,324,323,323,324,924,943,1009,492,892,241,323,182,1340,681,919,942,492,867,834,595,589,1032,760,760,644,885,845,389,672,672,389,1298,1098,1014,742,742,1014,248,882,629,589,330,1019,624,1142,51,1141,527,529,99,99,529,395,1143,1142,1141,671,1139,1140,1140,1139,1136,1141,51,50,1142,1143,1140,671,1138,1139,1139,1138,1136,1143,671,1140,348,1164,182,182,1164,1340,223,1019,1222,1143,1141,671,671,1141,1138,1032,644,760,530,527,99,956,961,248,646,1309,1032,897,898,364,325,1079,182,366,897,364,1218,111,1079,366,370,325,1060,707,1171,759,147,867,364,371,366,366,371,370,370,365,325,111,348,1079,1079,348,182,79,43,1340,1340,43,26,79,1340,1164,371,365,370,232,64,658,371,368,365,365,363,325,363,368,371,364,363,371,368,363,365,635,629,961,961,629,882,369,367,363,363,367,325,38,1164,348,179,79,67,43,1228,919,364,369,363,367,512,325,141,369,364,1009,241,892,324,387,1222,387,241,643,1014,956,248,614,956,1014,233,637,217,233,658,642,233,642,637,1218,1079,325,966,530,99,527,587,529,956,635,961,512,1218,325,111,38,348,966,528,530,530,528,527,67,38,1108,1108,38,111,898,141,364,369,512,367,141,516,369,899,140,141,141,140,516,516,512,369,515,512,516,902,515,140,140,515,516,100,587,528,528,587,527,643,241,1009,241,387,324,67,79,1164,79,734,43,67,1164,38,846,1218,512,897,366,896,515,846,512,874,875,232,232,875,64,874,217,978,1188,874,978,896,366,64,895,899,898,898,899,141,897,895,898,896,64,1188,902,899,895,902,140,899,902,846,515,41,734,179,179,734,79,900,902,895,1051,67,28,111,1218,173,897,896,895,902,900,846,1188,64,875,387,223,1222,896,900,895,896,901,900,900,901,846,1051,1154,67,67,1154,179,1108,111,173,1154,1157,179,28,1157,1051,1051,1157,1154,475,309,734,734,309,43,874,232,217,874,1188,875,1321,173,582,217,232,233,28,685,1157,1157,685,179,41,475,734,496,1228,43,637,642,27,173,1218,582,685,41,179,1218,846,582,846,901,582,1185,41,1186,27,394,529,217,519,978,28,67,1108,1183,1185,1186,41,1185,475,496,43,309,264,309,475,173,1321,1108,582,901,403,96,1183,1186,1185,1183,475,1186,41,457,1183,96,475,1320,28,939,939,28,1108,28,457,685,263,264,551,96,264,475,1299,1179,1228,1228,1179,919,377,496,309,496,1299,1228,1179,942,919,551,264,1057,264,263,309,1321,447,1108,552,1186,457,403,901,1101,403,1101,404,582,447,1321,552,457,1184,502,377,309,502,309,382,496,1008,1299,447,939,1108,582,939,447,1057,96,1186,1057,264,96,41,685,457,871,413,777,644,1017,77,494,413,411,1184,1057,552,552,1057,1186,382,309,263,413,1017,644,457,28,1320,382,263,381,45,529,587,45,27,529,263,551,381,377,1008,496,390,503,502,502,503,377,494,983,1017,1017,984,77,494,1017,413,411,413,871,103,45,100,646,589,629,551,1057,286,381,551,286,286,1057,1184,382,167,502,956,614,635,635,614,629,941,614,402,575,457,939,939,457,1320,1171,707,244,707,147,759,1171,244,633,457,286,1184,381,286,382,984,1017,983,499,217,637,457,287,286,286,287,382,265,167,287,287,167,382,503,631,377,457,265,287,1008,347,989,390,631,503,1299,757,1179,1008,631,347,631,1008,377,410,411,871,494,412,983,820,942,1179,387,643,223,347,631,505,1008,989,1299,901,896,1101,582,403,939,390,167,129,390,502,167,393,943,942,942,943,492,390,129,1293,167,265,129,411,412,494,602,505,631,390,602,631,505,1073,347,106,757,989,601,602,1293,1293,602,390,602,601,505,989,757,1299,1073,989,347,601,1073,505,413,1309,777,411,410,412,412,984,983,867,845,834,834,845,672,402,614,1014,1010,845,867,129,265,457,601,106,1073,1073,106,989,851,409,410,410,409,412,590,1171,633,50,155,1138,1138,155,633,50,1138,1141,763,643,1009,51,1142,624,463,106,601,757,820,1179,1101,896,303,403,404,939,896,519,303,413,644,1309,896,1188,519,584,129,583,1293,463,601,777,851,871,871,851,410,409,984,412,1098,1298,389,614,941,629,1101,303,404,583,129,1354,519,1188,978,767,763,1009,763,764,643,766,765,763,763,765,764,764,652,643,769,766,763,765,770,764,943,767,1009,851,984,409,768,769,767,767,769,763,768,770,766,766,770,765,996,768,767,769,768,766,943,996,767,768,996,770,1019,223,624,1142,330,624,624,223,643,627,1176,155,996,652,770,770,652,764,393,652,996,830,147,1060,1060,147,707,1309,644,1032,851,953,984,129,457,575,129,592,1293,106,820,757,652,624,643,130,592,584,584,592,129,590,1176,1074,155,590,633,575,939,404,583,130,584,463,820,106,1109,575,122,86,115,130,646,1032,589,777,953,851,575,1354,129,928,1098,389,627,155,50,1176,590,155,115,592,130,463,1293,592,943,393,996,130,583,1109,86,130,1109,583,1354,1109,115,116,592,1109,1354,575,115,118,116,845,928,389,581,1109,122,86,118,115,116,463,592,1109,118,86,488,402,1098,1098,402,1014,953,722,721,995,488,1098,402,488,941,374,463,134,645,637,102,499,519,217,122,575,1236,1267,721,1094,984,966,99,134,463,116,463,374,820,1109,581,118,118,75,116,575,404,1055,133,122,212,581,273,118,953,966,984,133,273,122,122,273,581,273,75,118,133,134,75,75,134,116,102,27,103,102,637,27,384,404,303,273,133,75,1001,1003,374,374,1003,820,820,393,942,1001,183,1002,1001,374,183,1002,1003,1001,1002,1004,1003,1003,1004,820,183,374,134,1004,1005,820,1002,1005,1004,645,499,637,840,183,134,1002,183,1005,840,393,1005,1005,393,820,103,27,45,645,397,499,498,397,645,102,498,645,397,498,499,730,306,519,1055,384,306,306,384,303,133,840,134,1010,1083,845,845,1083,928,928,995,1098,459,1010,867,100,45,587,1351,887,498,1236,1055,168,384,1055,404,1010,127,1083,1083,128,928,995,128,127,127,128,1083,953,1267,966,966,100,528,1267,953,721,723,722,953,30,100,966,624,385,51,51,385,50,839,385,894,385,624,894,609,830,1171,1171,830,1060,147,459,867,777,723,953,1267,30,966,777,1309,723,721,1269,1094,1094,1269,1267,723,1309,1011,721,1096,1269,646,629,941,722,1292,721,459,995,1010,1010,995,127,128,995,928,249,1236,168,1055,1236,575,183,840,1005,1236,212,122,385,627,50,590,609,1171,306,303,519,1236,249,212,555,840,133,728,519,499,169,168,1055,1170,646,941,306,169,1055,168,171,249,171,170,169,169,170,168,406,634,249,249,634,212,555,133,212,306,171,169,170,171,168,646,1011,1309,723,1292,722,830,459,147,1351,498,102,498,887,499,1351,102,103,1011,1292,723,1269,30,1267,1074,609,590,830,560,459,1292,1096,721,630,555,634,634,555,212,609,560,830,887,728,499,306,406,171,729,730,728,728,730,519,246,729,728,245,391,306,82,406,306,171,406,249,1096,30,1269,100,1351,103,385,839,627,627,1074,1176,894,624,652,894,652,393,30,1351,100,887,246,728,839,934,627,932,933,934,934,933,627,894,932,934,532,1074,627,532,627,933,839,894,934,840,894,393,646,1170,1011,1011,947,1292,1292,947,1096,1096,946,30,488,1170,941,83,82,391,406,630,634,82,306,391,1351,246,887,306,730,245,82,630,406,245,730,729,391,630,83,83,630,82,864,245,246,246,245,729,488,357,1170,1170,357,1011,894,532,932,932,532,933,357,947,1011,30,946,1351,357,946,947,947,946,1096,1351,864,246,245,534,391,391,534,630,535,534,245,630,534,555,555,535,840,864,535,245,534,535,555,1351,535,864] --------------------------------------------------------------------------------