{"id":345850,"date":"2023-02-24T21:02:01","date_gmt":"2023-02-24T21:02:01","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=345850"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=345850","title":{"rendered":"<span>\u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u043c\u043e\u0434\u0443\u043b\u044f WebAssembly \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e Emscripten, AssemblyScript \u0438 Rust<\/span>"},"content":{"rendered":"<div><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<p>\u0412 \u044d\u0442\u043e\u0439 \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u043e\u0439 \u0437\u0430\u043c\u0435\u0442\u043a\u0435 \u043f\u0440\u0435\u0434\u043b\u0430\u0433\u0430\u0435\u0442\u0441\u044f \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0441\u043f\u043e\u0441\u043e\u0431\u043e\u0432 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0446\u0438\u0438 \u043c\u043e\u0434\u0443\u043b\u044f \u0434\u043b\u044f WebAssembly, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f \u0442\u0440\u0438 \u0440\u0430\u0437\u043d\u044b\u0445 \u043f\u043e\u0434\u0445\u043e\u0434\u0430. \u041c\u044b \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u043c \u0440\u0435\u0448\u0435\u043d\u0438\u0435 \u043e\u0434\u043d\u043e\u0439 \u0438 \u0442\u043e\u0439 \u0436\u0435 \u0437\u0430\u0434\u0430\u0447\u043a\u0438 \u043d\u0430 \u0442\u0440\u0451\u0445 \u044f\u0437\u044b\u043a\u0430\u0445 \u0438 \u0441\u043a\u043e\u043c\u043f\u0438\u043b\u0438\u0440\u0443\u0435\u043c \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u044b\u0439 \u043a\u043e\u0434 \u0432 \u043c\u043e\u0434\u0443\u043b\u044c WebAssembly. \u0411\u0443\u0434\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c:<\/p>\n<ul>\n<li>\n<p>Emscripten \u0434\u043b\u044f \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0446\u0438\u0438 \u043a\u043e\u0434\u0430, \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u043d\u043e\u0433\u043e \u043d\u0430 c++<\/p>\n<\/li>\n<li>\n<p>AssemblyScript \u0434\u043b\u044f \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0446\u0438\u0438 \u043a\u043e\u0434\u0430, \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u043d\u043e\u0433\u043e \u043d\u0430, \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u043e, AssemblyScript<\/p>\n<\/li>\n<li>\n<p>wasm-pack \u0434\u043b\u044f \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0446\u0438\u0438 \u043a\u043e\u0434\u0430, \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u043d\u043e\u0433\u043e \u043d\u0430 Rust<\/p>\n<\/li>\n<\/ul>\n<p>\u041f\u043b\u0430\u043d \u0442\u0430\u043a\u043e\u0439:<\/p>\n<ul>\n<li>\n<p>\u0412\u043e \u0432\u0432\u0435\u0434\u0435\u043d\u0438\u0438 \u043c\u044b \u043e\u0431\u0441\u0443\u0434\u0438\u043c \u043f\u043e\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0443 \u0437\u0430\u0434\u0430\u0447\u0438 \u0438 \u043d\u0435\u043c\u043d\u043e\u0436\u043a\u043e \u043f\u043e\u0433\u043e\u0432\u043e\u0440\u0438\u043c \u043e \u0442\u0435\u0445\u043d\u043e\u043b\u043e\u0433\u0438\u0438 WebAssembly<\/p>\n<\/li>\n<li>\n<p>\u0412 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u043d\u043e\u0439 \u0447\u0430\u0441\u0442\u0438 \u043c\u044b \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u043e\u0441\u0442\u044c \u043c\u043e\u0434\u0443\u043b\u044f \u043d\u0430 \u0442\u0440\u0451\u0445 \u044f\u0437\u044b\u043a\u0430\u0445: c++, AssemblyScript \u0438 Rust. \u041f\u043e\u0433\u043e\u0432\u043e\u0440\u0438\u043c \u043e \u0442\u043e\u043c, \u043a\u0430\u043a\u0438\u0435 \u043f\u0440\u0438 \u044d\u0442\u043e\u043c \u0432\u043e\u0437\u043d\u0438\u043a\u0430\u044e\u0442 \u0441\u043b\u043e\u0436\u043d\u043e\u0441\u0442\u0438 \u0438 \u043a\u0430\u043a \u0438\u0445 \u043c\u043e\u0436\u043d\u043e \u043e\u0431\u043e\u0439\u0442\u0438<\/p>\n<\/li>\n<li>\n<p>\u041f\u043e\u0434\u0432\u0435\u0434\u0451\u043c \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u043e\u0439 \u0438\u0442\u043e\u0433. \u0421\u0442\u0430\u043d\u0435\u0442 \u0432\u0438\u0434\u043d\u043e, \u043a\u0430\u043a\u0430\u044f \u0442\u0435\u0445\u043d\u043e\u043b\u043e\u0433\u0438\u044f \u0445\u043e\u0440\u043e\u0448\u0430\u044f, \u0430 \u043a\u0430\u043a\u0430\u044f \u043d\u0435 \u043e\u0447\u0435\u043d\u044c<\/p>\n<\/li>\n<\/ul>\n<p>\u0412 \u043a\u043e\u043d\u0446\u0435 \u043f\u043b\u0430\u043d\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u0434\u0432\u0430 \u0431\u043e\u043d\u0443\u0441\u0430. \u041f\u0435\u0440\u0432\u044b\u0439 \u0431\u043e\u043d\u0443\u0441 &#8212; \u044d\u0442\u043e \u043f\u0440\u0438\u043c\u0435\u0440 \u043f\u0440\u043e\u0441\u0442\u043e\u0433\u043e web-\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0449\u0435\u0433\u043e \u043e\u0434\u0438\u043d \u0438\u0437 \u0441\u043a\u043e\u043c\u043f\u0438\u043b\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0445 \u043d\u0430\u043c\u0438 \u043c\u043e\u0434\u0443\u043b\u0435\u0439. \u0412\u0442\u043e\u0440\u043e\u0439 \u0431\u043e\u043d\u0443\u0441 &#8212; \u0434\u0435\u043c\u043e\u043d\u0441\u0442\u0440\u0430\u0446\u0438\u044f \u0442\u043e\u0433\u043e, \u043a\u0430\u043a \u044d\u0442\u043e\u0442 \u043c\u043e\u0434\u0443\u043b\u044c \u043c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0432 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0435 \u043d\u0430 Python.<\/p>\n<h2>\u0412\u0432\u0435\u0434\u0435\u043d\u0438\u0435<\/h2>\n<p>\u041f\u0440\u0435\u0434\u043f\u043e\u043b\u0430\u0433\u0430\u0435\u0442\u0441\u044f, \u0447\u0442\u043e \u0447\u0438\u0442\u0430\u0442\u0435\u043b\u044c \u0437\u043d\u0430\u043a\u043e\u043c \u0445\u043e\u0442\u044f \u0431\u044b \u043f\u043e\u043d\u0430\u0441\u043b\u044b\u0448\u043a\u0435 \u0441 \u0442\u0435\u0445\u043d\u043e\u043b\u043e\u0433\u0438\u0435\u0439 WebAssembly \u0438 \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u043b \u043e\u0434\u0438\u043d \u0438\u0437 HelloWorld \u0442\u0443\u0442\u043e\u0440\u0438\u0430\u043b\u043e\u0432 \u0434\u043b\u044f \u043e\u0434\u043d\u043e\u0439 \u0438\u0437 \u043f\u0435\u0440\u0435\u0447\u0438\u0441\u043b\u0435\u043d\u043d\u044b\u0445 \u0432\u044b\u0448\u0435 \u0442\u0435\u0445\u043d\u043e\u043b\u043e\u0433\u0438\u0439. \u0412\u043f\u0440\u043e\u0447\u0435\u043c, \u043c\u043e\u0436\u043d\u043e \u0431\u044b\u043b\u043e \u0438 \u043d\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0442\u044c. \u041e\u0431\u044b\u0447\u043d\u043e \u044d\u0442\u0438 HelloWorld-\u044b  \u043e\u043f\u0438\u0441\u044b\u0432\u0430\u044e\u0442 \u0442\u043e, \u043a\u0430\u043a \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u043c\u043e\u0434\u0443\u043b\u044c \u0434\u043b\u044f \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u044f \u0447\u0438\u0441\u0435\u043b \u0424\u0438\u0431\u043e\u043d\u0430\u0447\u0447\u0438, \u043d\u0443 \u0438\u043b\u0438 \u0432 \u043a\u0440\u0430\u0439\u043d\u0435\u043c \u0441\u043b\u0443\u0447\u0430\u0435 &#8212; \u0434\u043b\u044f \u043d\u0430\u0445\u043e\u0436\u0434\u0435\u043d\u0438\u044f \u0447\u0438\u0441\u043b\u0430 \u0434\u0435\u043b\u0438\u0442\u0435\u043b\u0435\u0439 \u0434\u0430\u043d\u043d\u043e\u0433\u043e \u0447\u0438\u0441\u043b\u0430. \u0422\u0435\u043a\u0443\u0449\u0430\u044f \u0437\u0430\u043c\u0435\u0442\u043a\u0430 \u043f\u0440\u0435\u0434\u043b\u0430\u0433\u0430\u0435\u0442 \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u043c\u0430\u043b\u0435\u043d\u044c\u043a\u0438\u0439 (\u043d\u0443 \u0432\u043e\u0442 \u0431\u0443\u043a\u0432\u0430\u043b\u044c\u043d\u043e \u0432\u0441\u0435\u0433\u043e \u043d\u0438\u0447\u0435\u0433\u043e) \u0448\u0430\u0436\u043e\u043a \u043e\u0442 HelloWorld-\u0430 \u0438 \u0440\u0435\u0448\u0438\u0442\u044c \u0447\u0443\u0442\u044c \u0431\u043e\u043b\u0435\u0435 \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0442\u0435\u043b\u044c\u043d\u0443\u044e \u0437\u0430\u0434\u0430\u0447\u0443 \u043f\u043e \u0441\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u044e \u0441 \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u0435\u043c \u0447\u0438\u0441\u0435\u043b \u0424\u0438\u0431\u043e\u043d\u0430\u0447\u0447\u0438.<\/p>\n<p>\u0418\u0442\u0430\u043a, \u0437\u0430\u0434\u0430\u0447\u0430. \u041f\u0440\u0435\u0434\u043b\u0430\u0433\u0430\u0435\u0442\u0441\u044f \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u043c\u043e\u0434\u0443\u043b\u044c, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0435. \u041d\u0430 \u0432\u0445\u043e\u0434 \u043f\u043e\u0434\u0430\u0451\u0442\u0441\u044f \u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u043e \u0442\u043e\u0447\u0435\u043a \u043d\u0430 \u043f\u043b\u043e\u0441\u043a\u043e\u0441\u0442\u0438. \u041c\u043e\u0434\u0443\u043b\u044c \u0441\u0442\u0440\u043e\u0438\u0442 \u0442\u0440\u0438\u0430\u043d\u0433\u0443\u043b\u044f\u0446\u0438\u044e \u0414\u0435\u043b\u043e\u043d\u0435 \u0441 \u0432\u0435\u0440\u0448\u0438\u043d\u0430\u043c\u0438 \u0432 \u044d\u0442\u0438\u0445 \u0442\u043e\u0447\u043a\u0430\u0445, \u0443\u043f\u0430\u043a\u043e\u0432\u044b\u0432\u0430\u0435\u0442 \u043f\u043e\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u044b\u0435 \u0442\u0440\u0435\u0443\u0433\u043e\u043b\u044c\u043d\u0438\u043a\u0438 \u0432 BVH \u0438 \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u0442 \u043c\u0435\u0442\u043e\u0434 \u043f\u043e\u0438\u0441\u043a\u0430 \u0442\u0440\u0435\u0443\u0433\u043e\u043b\u044c\u043d\u0438\u043a\u0430, \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0449\u0435\u0433\u043e \u043b\u044e\u0431\u0443\u044e \u0443\u043a\u0430\u0437\u0430\u043d\u043d\u0443\u044e \u0442\u043e\u0447\u043a\u0443.<\/p>\n<p>\u0411\u0443\u0434\u0435\u043c \u0441\u0447\u0438\u0442\u0430\u0442\u044c, \u0447\u0442\u043e \u043c\u044b \u0437\u043d\u0430\u0435\u043c, \u0447\u0442\u043e \u0442\u0430\u043a\u043e\u0435 \u0442\u0440\u0438\u0430\u043d\u0433\u0443\u043b\u044f\u0446\u0438\u044f \u0414\u0435\u043b\u043e\u043d\u0435. \u0415\u0441\u043b\u0438 \u043a\u0442\u043e \u0437\u0430\u0431\u044b\u043b (\u0438\u043b\u0438 \u043d\u0435 \u0437\u043d\u0430\u043b) &#8212; \u043c\u043e\u0436\u043d\u043e \u0432\u0441\u043f\u043e\u043c\u043d\u0438\u0442\u044c \u043d\u0430 <a href=\"https:\/\/ru.wikipedia.org\/wiki\/%D0%A2%D1%80%D0%B8%D0%B0%D0%BD%D0%B3%D1%83%D0%BB%D1%8F%D1%86%D0%B8%D1%8F_%D0%94%D0%B5%D0%BB%D0%BE%D0%BD%D0%B5\" rel=\"noopener noreferrer nofollow\">\u0412\u0438\u043a\u0438\u043f\u0435\u0434\u0438\u0438<\/a>. \u0415\u0441\u0442\u044c \u043c\u043d\u043e\u0433\u043e \u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c\u043e\u0432 \u0435\u0451 \u043f\u043e\u0441\u0442\u0440\u043e\u0435\u043d\u0438\u044f. \u041f\u0440\u0435\u0434\u043b\u0430\u0433\u0430\u0435\u0442\u0441\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043e\u0434\u0438\u043d \u0438\u0437 \u043d\u0438\u0445 \u0432\u043e\u0442 <a href=\"https:\/\/github.com\/darkskyapp\/delaunay-fast\" rel=\"noopener noreferrer nofollow\">\u043e\u0442\u0441\u044e\u0434\u0430<\/a>. \u041c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u044d\u0442\u043e\u0442 \u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c \u043d\u0435 \u0441\u0438\u043b\u044c\u043d\u043e \u0431\u044b\u0441\u0442\u0440\u044b\u0439, \u043d\u043e \u043f\u043e \u043a\u0440\u0430\u0439\u043d\u0435\u0439 \u043c\u0435\u0440\u0435 \u043f\u0440\u043e\u0441\u0442\u043e\u0439 \u0438 \u0435\u0433\u043e \u043c\u043e\u0436\u043d\u043e \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u043a\u043e\u0440\u043e\u0442\u043a\u043e\u0439 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u043e\u0439. \u0412 \u043b\u044e\u0431\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u0441\u0430\u043c \u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c \u043d\u0435 \u0438\u043c\u0435\u0435\u0442 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f. \u0417\u0430\u043c\u0435\u0442\u043a\u0430 \u0432\u0435\u0434\u044c \u043d\u0435 \u043e\u0431 \u044d\u0442\u043e\u043c.<\/p>\n<p>\u0427\u0442\u043e \u0442\u0430\u043a\u043e\u0435 BVH (Bounding Volume Hierarhy) \u0442\u043e\u0436\u0435, \u043d\u0430\u0432\u0435\u0440\u043d\u043e\u0435, \u0432\u0441\u0435 \u0437\u043d\u0430\u044e\u0442. \u0415\u0449\u0451 \u0432 \u0448\u043a\u043e\u043b\u0435, \u043f\u043e\u0434\u0438, \u0432 \u0432\u043e\u0441\u044c\u043c\u043e\u043c \u043a\u043b\u0430\u0441\u0441\u0435 \u043f\u0438\u0441\u0430\u043b\u0438 \u0440\u0430\u0437\u043d\u044b\u0435 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438. \u041d\u0443 \u0430 \u0435\u0441\u043b\u0438 \u043a\u043e\u043c\u0443 \u043d\u0435 \u043f\u043e\u0432\u0435\u0437\u043b\u043e \u0438\u043b\u0438 \u043e\u043d \u0437\u0430\u0431\u044b\u043b \u0441\u0432\u043e\u0451 \u0441\u0447\u0430\u0441\u0442\u043b\u0438\u0432\u043e\u0435 \u0434\u0435\u0442\u0441\u0442\u0432\u043e &#8212; \u043c\u043e\u0436\u043d\u043e \u0442\u043e\u0436\u0435 \u043e\u0437\u043d\u0430\u043a\u043e\u043c\u0438\u0442\u044c\u0441\u044f \u0441 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u0435\u043c \u043d\u0430 <a href=\"https:\/\/en.wikipedia.org\/wiki\/Bounding_volume_hierarchy\" rel=\"noopener noreferrer nofollow\">\u0412\u0438\u043a\u0438\u043f\u0435\u0434\u0438\u0438<\/a>. \u0418 \u0441\u043d\u043e\u0432\u0430, \u043f\u043e \u0431\u043e\u043b\u044c\u0448\u043e\u043c\u0443 \u0441\u0447\u0451\u0442\u0443, \u0447\u0442\u043e \u044d\u0442\u043e \u0442\u0430\u043a\u043e\u0435 \u043d\u0435 \u043e\u0441\u043e\u0431\u043e \u0432\u0430\u0436\u043d\u043e.<\/p>\n<p>\u0418 \u0435\u0449\u0451 \u043f\u0430\u0440\u0443 \u0441\u043b\u043e\u0432 \u043e \u0442\u043e\u043c, \u0447\u0442\u043e \u0442\u0430\u043a\u043e\u0435 WebAssembly. \u0415\u0441\u0442\u044c \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u0435 \u043d\u0430 \u0432\u0441\u0451 \u0442\u043e\u0439 \u0436\u0435 <a href=\"https:\/\/ru.wikipedia.org\/wiki\/WebAssembly\" rel=\"noopener noreferrer nofollow\">\u0412\u0438\u043a\u0438\u043f\u0435\u0434\u0438\u0438<\/a>, \u0435\u0441\u0442\u044c \u0432 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438 <a href=\"https:\/\/developer.mozilla.org\/ru\/docs\/WebAssembly\" rel=\"noopener noreferrer nofollow\">Mozill-\u044b<\/a>. \u041c\u043e\u0436\u043d\u043e \u043f\u043e \u0440\u0430\u0437\u043d\u043e\u043c\u0443 \u0440\u0430\u0441\u0441\u0442\u0430\u0432\u043b\u044f\u0442\u044c \u0430\u043a\u0446\u0435\u043d\u0442\u044b \u0432 \u0432\u043e\u043f\u0440\u043e\u0441\u0430\u0445 \u043e \u0442\u043e\u043c, \u043a\u0430\u043a \u043e\u0442\u043d\u043e\u0441\u0438\u0442\u044c\u0441\u044f \u043a \u0442\u0435\u0445\u043d\u043e\u043b\u043e\u0433\u0438\u0438 WebAssembly \u0438 \u0434\u043b\u044f \u0447\u0435\u0433\u043e \u0435\u0451 \u043c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c. \u041d\u0430 \u043c\u043e\u0439 \u0432\u0437\u0433\u043b\u044f\u0434 \u043e\u0434\u043d\u043e \u0438\u0437 \u043f\u0440\u0435\u0438\u043c\u0443\u0449\u0435\u0441\u0442\u0432\u043e \u043c\u043e\u0434\u0443\u043b\u0435\u0439 WebAssembly &#8212; \u044d\u0442\u043e \u0438\u0445 \u0443\u043d\u0438\u0432\u0435\u0440\u0441\u0430\u043b\u044c\u043d\u043e\u0441\u0442\u044c \u0432 \u0441\u043c\u044b\u0441\u043b\u0435 \u043d\u0435\u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043e\u0442 \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u044b. \u042d\u0442\u0438 \u043c\u043e\u0434\u0443\u043b\u0438 \u043c\u043e\u0436\u043d\u043e (\u0438 \u043d\u0443\u0436\u043d\u043e) \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0442\u044c \u043d\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u0432 \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u0435 \u0438 NodeJS. \u0415\u0441\u0442\u044c \u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u043e \u0441\u0442\u0430\u0446\u0438\u043e\u043d\u0430\u0440\u043d\u044b\u0445 \u0438\u0442\u0435\u0440\u043f\u0440\u0435\u0442\u0430\u0442\u043e\u0440\u043e\u0432 \u0438 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440\u043e\u0432 \u0432 \u043d\u0430\u0441\u0442\u043e\u044f\u0449\u0438\u0435 \u043c\u0430\u0448\u0438\u043d\u043d\u044b\u0435 \u043a\u043e\u0434\u044b. <a href=\"https:\/\/github.com\/appcypher\/awesome-wasm-runtimes\" rel=\"noopener noreferrer nofollow\">\u0412\u043e\u0442 \u0442\u0443\u0442<\/a> \u0431\u043e\u043b\u044c\u0448\u043e\u0439 \u0441\u043f\u0438\u0441\u043e\u043a \u0440\u0430\u0437\u043d\u044b\u0445 \u0442\u0430\u043a\u0438\u0445 \u043f\u0440\u043e\u0435\u043a\u0442\u043e\u0432. \u041f\u043e\u043c\u0438\u043c\u043e \u044d\u0442\u043e\u0433\u043e \u043c\u043e\u0434\u0443\u043b\u0438 WebAssembly \u043c\u043e\u0436\u043d\u043e \u0432\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u0442\u044c \u0432 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b \u0441\u043a\u0440\u0438\u043f\u0442\u043e\u0432\u044b\u0445 (\u0447\u0438\u0442\u0430\u0439 \u043c\u0435\u0434\u043b\u0435\u043d\u043d\u044b\u0445) \u044f\u0437\u044b\u043a\u0430\u0445 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f, \u0438 \u0442\u0435\u043c \u0441\u0430\u043c\u044b\u043c \u043a\u0430\u043a\u0438\u0435-\u0442\u043e \u0432\u044b\u0447\u0438\u0441\u043b\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0442\u044f\u0436\u0451\u043b\u044b\u0435 \u043a\u0443\u0441\u043a\u0438 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0442\u044c \u0433\u043e\u0440\u0430\u0437\u0434\u043e \u0431\u044b\u0441\u0442\u0440\u0435\u0435. \u0422\u0435\u0445\u043d\u043e\u043b\u043e\u0433\u0438\u044f <a href=\"https:\/\/github.com\/wasmerio\/wasmer\" rel=\"noopener noreferrer nofollow\">Wasmer<\/a> \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442, \u0432 \u0447\u0430\u0441\u0442\u043d\u043e\u0441\u0442\u0438, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043c\u043e\u0434\u0443\u043b\u0438 WebAssembly \u0432\u043d\u0443\u0442\u0440\u0438 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c \u043a\u0430\u043a \u043d\u0430 Python, \u0442\u0430\u043a \u0438 \u043d\u0430 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u0434\u0440\u0443\u0433\u0438\u0445 \u044f\u0437\u044b\u043a\u0430\u0445 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f.<\/p>\n<p>\u041f\u0438\u0441\u0430\u0442\u044c \u043a\u043e\u0434 \u043d\u0435\u043f\u043e\u0441\u0440\u0435\u0434\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u043d\u0430 WebAssembly \u043c\u043e\u0436\u043d\u043e. \u041d\u043e \u043d\u0443\u0436\u043d\u043e \u044d\u0442\u043e \u043f\u0440\u0438\u043c\u0435\u0440\u043d\u043e \u0441\u0442\u043e\u043b\u044c\u043a\u043e \u0436\u0435 \u0440\u0430\u0437, \u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043f\u0438\u0441\u0430\u0442\u044c \u043d\u0430 \u043e\u0431\u044b\u0447\u043d\u043e\u043c \u0430\u0441\u0441\u0435\u043c\u0431\u043b\u0435\u0440\u0435, \u0438 \u0434\u0430\u0436\u0435 \u0440\u0435\u0436\u0435. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u043e\u0431\u044b\u0447\u043d\u043e \u043f\u0438\u0448\u0443\u0442 \u043d\u0430 \u043a\u0430\u043a\u043e\u043c-\u043d\u0438\u0431\u0443\u0434\u044c \u0447\u0435\u043b\u043e\u0432\u0435\u0447\u0435\u0441\u043a\u043e\u043c \u044f\u0437\u044b\u043a\u0435, \u0430 \u043f\u043e\u0442\u043e\u043c \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u0443\u044e \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0443 \u043a\u043e\u043c\u043f\u0438\u043b\u0438\u0440\u0443\u044e\u0442 \u0432 WebAssembly. \u0418 \u0432\u043e\u0442 \u0442\u0443\u0442 \u0432\u043e\u0442 \u0438 \u043a\u0440\u043e\u0435\u0442\u0441\u044f \u043e\u0434\u043d\u0430 \u0438\u0437 \u043f\u0440\u043e\u0431\u043b\u0435\u043c. \u0414\u0435\u043b\u043e \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u043c\u043d\u043e\u0433\u043e \u044f\u0437\u044b\u043a\u043e\u0432 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u043a\u043e\u043c\u043f\u0438\u043b\u0438\u0440\u0443\u044e\u0442\u0441\u044f \u0432 WebAssembly. <a href=\"https:\/\/github.com\/appcypher\/awesome-wasm-langs\" rel=\"noopener noreferrer nofollow\">\u0412\u043e\u0442 \u0442\u0443\u0442<\/a> \u0435\u0441\u0442\u044c \u0441\u043f\u0438\u0441\u043e\u043a. \u041c\u043d\u043e\u0433\u043e \u0442\u0430\u043c \u0432\u0441\u044f\u043a\u043e\u0433\u043e \u0440\u0430\u0437\u043d\u043e\u0433\u043e \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u043e. \u041d\u043e \u043c\u0430\u043b\u043e \u043c\u043e\u0434\u0443\u043b\u044c \u0441\u043a\u043e\u043c\u043f\u0438\u043b\u0438\u0440\u043e\u0432\u0430\u0442\u044c, \u0435\u0433\u043e \u0432\u0435\u0434\u044c \u043f\u043e\u0442\u043e\u043c \u043d\u0430\u0434\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0438\u0437 \u043a\u0430\u043a\u043e\u0433\u043e-\u0442\u043e \u0434\u0440\u0443\u0433\u043e\u0433\u043e \u043c\u0435\u0441\u0442\u0430. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0432\u044b\u0437\u0432\u0430\u0442\u044c \u0444\u0443\u043d\u043a\u0446\u0438\u044e, \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d\u043d\u0443\u044e \u0432 \u043c\u043e\u0434\u0443\u043b\u0435, \u0438 \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442. \u041d\u043e \u0432\u043e\u0442 \u0431\u0435\u0434\u0430, \u044f\u0437\u044b\u043a WebAssembly \u043f\u043e\u043d\u0438\u043c\u0430\u0435\u0442 \u0442\u043e\u043b\u044c\u043a\u043e \u0447\u0438\u0441\u043b\u043e\u0432\u044b\u0435 \u0442\u0438\u043f\u044b \u0434\u0430\u043d\u043d\u044b\u0445: \u0446\u0435\u043b\u044b\u0435 \u0438 \u0441 \u043f\u043b\u0430\u0432\u0430\u044e\u0449\u0435\u0439 \u0442\u043e\u0447\u043a\u043e\u0439 \u0440\u0430\u0437\u043d\u043e\u0439 \u0431\u0438\u0442\u043d\u043e\u0441\u0442\u0438. \u0418 \u0441 \u044d\u0442\u0438\u043c \u043d\u0435\u0442 \u043f\u0440\u043e\u0431\u043b\u0435\u043c, \u0435\u0441\u043b\u0438 \u043c\u044b \u0445\u043e\u0442\u0438\u043c \u0432\u044b\u0437\u0432\u0430\u0442\u044c \u0444\u0443\u043d\u043a\u0446\u0438\u044e, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442 \u0442\u043e\u043b\u044c\u043a\u043e \u0447\u0438\u0441\u043b\u043e\u0432\u044b\u0435 \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u044b \u0438 \u0432\u044b\u0434\u0430\u0451\u0442 \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0430 \u0442\u043e\u0436\u0435 \u0447\u0438\u0441\u043b\u043e. \u0410 \u0435\u0441\u043b\u0438 \u043c\u044b, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0445\u043e\u0442\u0438\u043c \u043f\u043e\u0441\u0447\u0438\u0442\u0430\u0442\u044c \u0441\u0443\u043c\u043c\u0443 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432 \u043c\u0430\u0441\u0441\u0438\u0432\u0430. \u042d\u0442\u043e \u0432\u0435\u0434\u044c \u043d\u0430\u0434\u043e \u043a\u0430\u043a-\u0442\u043e \u043f\u0435\u0440\u0435\u0434\u0430\u0442\u044c \u043c\u0430\u0441\u0441\u0438\u0432 \u0432 \u043c\u043e\u0434\u0443\u043b\u044c. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0435\u0433\u043e \u043d\u0430\u0434\u043e \u0440\u0430\u0437\u043c\u0435\u0441\u0442\u0438\u0442\u044c \u0432 \u043f\u0430\u043c\u044f\u0442\u0438 \u043c\u043e\u0434\u0443\u043b\u044f, \u0430 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0430 \u0443\u0436\u0435 \u0434\u043e\u043b\u0436\u043d\u0430 \u0441\u0430\u043c\u0430 \u0443\u043c\u0435\u0442\u044c \u0435\u0433\u043e \u0438\u0437 \u044d\u0442\u043e\u0439 \u043f\u0430\u043c\u044f\u0442\u0438 \u0432\u0437\u044f\u0442\u044c. \u0412\u043e\u0442 \u0438 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0430: \u043e\u0442\u043a\u0443\u0434\u0430 \u044f \u043a\u0430\u043a \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0441\u0442 \u0437\u043d\u0430\u044e \u0432 \u043a\u0430\u043a\u043e\u043c \u0432\u0438\u0434\u0435 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0430 \u043f\u0430\u043c\u044f\u0442\u044c \u043c\u043e\u0434\u0443\u043b\u044f \u043f\u043e\u0441\u043b\u0435 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0446\u0438\u0438, \u043a\u0430\u043a \u043e\u0442\u0442\u0443\u0434\u0430 \u0447\u0442\u043e-\u0442\u043e \u0431\u0440\u0430\u0442\u044c \u0438, \u043f\u0440\u043e\u0441\u0442\u0438 \u0433\u043e\u0441\u043f\u043e\u0434\u0438, \u0447\u0442\u043e-\u0442\u043e \u0442\u0443\u0434\u0430 \u043a\u043b\u0430\u0441\u0442\u044c? \u0413\u043e\u0432\u043e\u0440\u044e \u0436\u0435 &#8212; \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u044b. \u0414\u0430, \u043e\u043d\u0438 \u0440\u0435\u0448\u0430\u044e\u0442\u0441\u044f, \u043d\u043e \u043f\u0440\u043e\u0446\u0435\u0434\u0443\u0440\u0430 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u043e\u0442\u043a\u043e\u043c\u043f\u0438\u043b\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0433\u043e \u043c\u043e\u0434\u0443\u043b\u044f \u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u0441\u044f \u0432\u0435\u0441\u044c\u043c\u0430 \u043d\u0435\u0442\u0440\u0438\u0432\u0438\u0430\u043b\u044c\u043d\u043e\u0439.<\/p>\n<p>\u041e\u0434\u043d\u0430\u043a\u043e \u043d\u0435 \u0432\u0441\u0451 \u0442\u0430\u043a \u043f\u043b\u043e\u0445\u043e. \u0415\u0441\u0442\u044c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0442\u0435\u0445\u043d\u043e\u043b\u043e\u0433\u0438\u0439, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043d\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u043a\u043e\u043c\u043f\u0438\u043b\u0438\u0440\u0443\u044e\u0442 \u043c\u043e\u0434\u0443\u043b\u044c WebAssembly, \u043d\u043e \u0438 \u0441\u043e\u0437\u0434\u0430\u044e\u0442 \u043e\u0431\u0432\u0435\u0441 (\u0442\u0430\u043a \u043d\u0430\u0437\u044b\u0432\u0430\u0435\u043c\u044b\u0439 gluing code), \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0438 \u0434\u0435\u043b\u0430\u0435\u0442 \u0432\u0441\u0435 \u0432\u043e\u0442 \u044d\u0442\u0438 \u043d\u0435\u0443\u0434\u043e\u0431\u043d\u044b\u0435 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f, \u0437\u0430\u0441\u0442\u0430\u0432\u043b\u044f\u044e\u0449\u0438\u0435 \u0437\u0430\u0434\u0443\u043c\u044b\u0432\u0430\u0442\u044c\u0441\u044f \u0438 \u043e\u0442\u0447\u0430\u0438\u0432\u0430\u0442\u044c\u0441\u044f. \u042d\u0442\u0438 \u0442\u0435\u0445\u043d\u043e\u043b\u043e\u0433\u0438\u0438 \u043f\u0435\u0440\u0435\u0447\u0438\u0441\u043b\u0435\u043d\u044b \u0432 \u0441\u0430\u043c\u043e\u043c \u043d\u0430\u0447\u0430\u043b\u0435. \u041c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u0435\u0441\u0442\u044c \u0435\u0449\u0451 \u043a\u0430\u043a\u0438\u0435-\u0442\u043e \u0434\u0440\u0443\u0433\u0438\u0435, \u043d\u043e \u0434\u0430\u0432\u0430\u0439\u0442\u0435 \u0434\u043b\u044f \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0451\u043d\u043d\u043e\u0441\u0442\u0438 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0438\u043c\u0441\u044f \u044d\u0442\u0438\u043c\u0438 \u0442\u0440\u0435\u043c\u044f. \u041e\u043d\u0438, \u0432\u0441\u0451-\u0442\u0430\u043a\u0438, \u043d\u0430\u0438\u0431\u043e\u043b\u0435\u0435 \u043f\u043e\u043f\u0443\u043b\u044f\u0440\u043d\u044b. <\/p>\n<h2>\u041f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u043d\u0430\u044f \u0447\u0430\u0441\u0442\u044c<\/h2>\n<p>\u0418\u0442\u0430\u043a, \u043f\u0440\u0438\u0441\u0442\u0443\u043f\u0438\u043c \u043a \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044e. \u0415\u0449\u0451 \u0440\u0430\u0437 \u043f\u043e\u0432\u0442\u043e\u0440\u044e, \u0447\u0442\u043e \u043d\u0430\u0448\u0430 \u0446\u0435\u043b\u044c \u0441\u043e\u0441\u0442\u043e\u0438\u0442 \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e\u0431\u044b \u0437\u0430\u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0443\u043f\u0430\u043a\u043e\u0432\u043a\u0443 \u0432 BVH \u0442\u0440\u0435\u0443\u0433\u043e\u043b\u044c\u043d\u0438\u043a\u043e\u0432 \u0442\u0440\u0438\u0430\u043d\u0433\u0443\u043b\u044f\u0446\u0438\u0438 \u0414\u0435\u043b\u043e\u043d\u0435. \u041d\u0430\u0447\u043d\u0451\u043c \u0441 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u043d\u0430 c++, \u043f\u043e\u0442\u043e\u043c \u0441\u0434\u0435\u043b\u0430\u0435\u043c \u0442\u043e \u0436\u0435 \u0441\u0430\u043c\u043e\u0435 \u043d\u0430 AssemblyScript, \u0430 \u0437\u0430\u043a\u043e\u043d\u0447\u0438\u043c \u043d\u0430 Rust.<\/p>\n<h3>Emscripten \u0438 c++<\/h3>\n<p>\u041f\u0440\u0435\u0434\u043b\u0430\u0433\u0430\u0435\u0442\u0441\u044f \u0440\u0430\u0437\u044b\u0433\u0440\u0430\u0442\u044c \u0442\u0430\u043a\u043e\u0439 \u0441\u0446\u0435\u043d\u0430\u0440\u0438\u0439. \u041f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u0438\u043c, \u0447\u0442\u043e \u043c\u044b \u043a\u0430\u043a \u0431\u0443\u0434\u0442\u043e \u0431\u044b \u043f\u0438\u0448\u0435\u043c \u043e\u0431\u044b\u0447\u043d\u0443\u044e \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0443 \u043d\u0430 c++, \u043d\u0435 \u0438\u043c\u0435\u044f \u0432\u0432\u0438\u0434\u0443 \u043a\u0430\u043a\u0443\u044e-\u0442\u043e \u043f\u043e\u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0443\u044e \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0446\u0438\u044e \u0432 WebAssembly. \u042d\u0442\u043e \u0443\u0434\u043e\u0431\u043d\u043e, \u0442\u0430\u043a \u043a\u0430\u043a \u043c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043f\u0440\u0438\u0432\u044b\u0447\u043d\u044b\u0435 \u0441\u0440\u0435\u0434\u0441\u0442\u0432\u0430 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438, \u043e\u0442\u043b\u0430\u0434\u043a\u0438 \u0438 \u0447\u0435\u0433\u043e \u0442\u0430\u043c \u0435\u0449\u0451 \u043d\u0443\u0436\u043d\u043e. \u042f \u043d\u0430 c++ \u043d\u0438\u043a\u043e\u0433\u0434\u0430 \u043e\u0441\u043e\u0431\u043e \u043d\u0438\u0447\u0435\u0433\u043e \u043d\u0435 \u043f\u0438\u0441\u0430\u043b, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0431\u0443\u0434\u0443 \u0434\u0435\u043b\u0430\u0442\u044c \u0432\u0441\u0451 \u0432 VisualStudio, \u0441\u043e\u0437\u0434\u0430\u0432 \u043f\u0440\u043e\u0435\u043a\u0442 \u0434\u043b\u044f \u043e\u0431\u044b\u0447\u043d\u043e\u0433\u043e \u043a\u043e\u043d\u0441\u043e\u043b\u044c\u043d\u043e\u0433\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f. \u041f\u043e\u0442\u043e\u043c, \u043a\u043e\u0433\u0434\u0430 \u0443\u0436\u0435 \u0432\u0441\u0451 \u043d\u0430\u043f\u0438\u0448\u0435\u043c, \u0442\u043e\u0433\u0434\u0430 \u0438 \u0431\u0443\u0434\u0435\u043c \u0434\u0443\u043c\u0430\u0442\u044c \u043e \u0442\u043e\u043c, \u043a\u0430\u043a \u0432\u0441\u0451 \u044d\u0442\u043e \u0434\u0435\u043b\u043e \u0441\u043a\u043e\u043c\u043f\u0438\u043b\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0432 WebAssembly.<\/p>\n<h4>\u041f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0430 \u043d\u0430 c++<\/h4>\n<p>\u0418\u0442\u0430\u043a, \u0441\u043e\u0437\u0434\u0430\u0451\u043c \u043f\u044f\u0442\u044c \u0444\u0430\u0439\u043b\u043e\u0432: <code>point.h<\/code> <code>delaunay.h<\/code> <code>delaunay.cpp<\/code> <code>bvh.h<\/code> \u0438 <code>bvh.cpp<\/code><\/p>\n<p>\u0424\u0430\u0439\u043b <code>point.h<\/code> \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443 \u0434\u043b\u044f \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u044f \u0442\u043e\u0447\u043a\u0438 \u043d\u0430 \u043f\u043b\u043e\u0441\u043a\u043e\u0441\u0442\u0438.<\/p>\n<details class=\"spoiler\">\n<summary>point.h<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"cpp\">#pragma once  #include &lt;string>  struct Point { Point() : x(0.0f), y(0.0f) { } Point(float _x, float _y) : x(_x), y(_y) { }  std::string to_string() const { return \"(\" + std::to_string(x) + \", \" + std::to_string(y) + \")\"; }  float x; float y; };<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u0424\u0430\u0439\u043b <code>delaunay.h<\/code> \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u0442\u043e\u043b\u044c\u043a\u043e \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u0441\u0438\u0433\u043d\u0430\u0442\u0443\u0440\u044b \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0434\u043b\u044f \u043f\u043e\u0441\u0442\u0440\u043e\u0435\u043d\u0438\u044f \u0442\u0440\u0438\u0430\u043d\u0433\u0443\u043b\u044f\u0446\u0438\u0438 \u0414\u0435\u043b\u043e\u043d\u0435. \u041d\u0430 \u0432\u0445\u043e\u0434 \u043e\u043d\u0430 \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442 \u043c\u0430\u0441\u0441\u0438\u0432 \u0442\u043e\u0447\u0435\u043a, \u0430 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u043c\u0430\u0441\u0441\u0438\u0432 \u0438\u043d\u0434\u0435\u043a\u0441\u043e\u0432 \u044d\u0442\u0438\u0445 \u0442\u043e\u0447\u0435\u043a, \u043e\u043f\u0438\u0441\u044b\u0432\u0430\u044e\u0449\u0438\u0445 \u0442\u0440\u0435\u0443\u0433\u043e\u043b\u044c\u043d\u0438\u043a\u0438. \u041f\u0440\u0435\u0434\u043f\u043e\u043b\u0430\u0433\u0430\u0435\u0442\u0441\u044f, \u0447\u0442\u043e \u043f\u0435\u0440\u0432\u044b\u0435 \u0442\u0440\u0438 \u0447\u0438\u0441\u043b\u0430 \u0438\u0442\u043e\u0433\u043e\u0432\u043e\u0433\u043e \u043c\u0430\u0441\u0441\u0438\u0432\u0430 &#8212; \u044d\u0442\u043e \u0438\u043d\u0434\u0435\u043a\u0441\u044b \u0432\u0435\u0440\u0448\u0438\u043d \u043f\u0435\u0440\u0432\u043e\u0433\u043e \u0442\u0440\u0435\u0443\u0433\u043e\u043b\u044c\u043d\u0438\u043a\u0430, \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u0442\u0440\u0438 &#8212; \u0432\u0442\u043e\u0440\u043e\u0433\u043e, \u0438 \u0442\u0430\u043a \u0434\u0430\u043b\u0435\u0435.<\/p>\n<details class=\"spoiler\">\n<summary>delaunay.h<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"cpp\">std::vector&lt;int> triangulate(std::vector&lt;Point>&amp; points);<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u0424\u0430\u0439\u043b <code>delaunay.cpp<\/code> \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u043d\u0435\u043f\u043e\u0441\u0440\u0435\u0434\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e \u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c\u0430 \u043f\u043e\u0441\u0442\u0440\u043e\u0435\u043d\u0438\u044f \u0442\u0440\u0438\u0430\u043d\u0433\u0443\u043b\u044f\u0446\u0438\u0438 \u0414\u0435\u043b\u043e\u043d\u0435. \u0422\u0430\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0432\u0441\u043f\u043e\u043c\u043e\u0433\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u0445 \u0444\u0443\u043d\u043a\u0446\u0438\u0439 \u0438 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440, \u043d\u043e \u0432 \u0446\u0435\u043b\u043e\u043c \u043d\u0438\u0447\u0435\u0433\u043e \u0441\u043b\u043e\u0436\u043d\u043e\u0433\u043e. \u041a\u0430\u043a\u043e\u0433\u043e \u0431\u044b \u0442\u043e \u043d\u0438 \u0431\u044b\u043b\u043e, \u0440\u0430\u0437\u0431\u043e\u0440\u0430 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0449\u0435\u0433\u043e\u0441\u044f \u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c\u0430 \u0437\u0434\u0435\u0441\u044c \u0434\u0430\u0432\u0430\u0442\u044c \u043d\u0435 \u0431\u0443\u0434\u0435\u043c, \u0442\u0430\u043a \u043a\u0430\u043a \u044d\u0442\u043e \u0443\u0432\u0435\u0434\u0451\u0442 \u043d\u0430\u0441 \u0434\u0430\u043b\u0435\u043a\u043e \u0432 \u0441\u0442\u043e\u0440\u043e\u043d\u0443.<\/p>\n<details class=\"spoiler\">\n<summary>delaunay.cpp<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"cpp\">#include \"point.h\"  #include &lt;vector> #include &lt;iostream> #include &lt;algorithm> #include &lt;float.h>  struct TriangleCircle {     \/\/ triangle point indices     int i;     int j;     int k;      \/\/ circle center     float x;     float y;      \/\/ the square of the circle radius     float radius_sq;      std::string to_string() const     {         return \"&lt;\" + std::to_string(i) + \", \" + std::to_string(j) + \", \" + std::to_string(k) + \"|\" + std::to_string(x) + \", \" + std::to_string(y) + \"|\" + std::to_string(radius_sq) + \">\";     } };  std::vector&lt;Point> build_supertriangle(const std::vector&lt;Point> &amp;points) {     float x_min = FLT_MAX;     float y_min = FLT_MAX;     float x_max = FLT_MIN;     float y_max = FLT_MIN;      for (size_t i = 0; i &lt; points.size(); i++)     {         const Point p = points[i];         if (p.x &lt; x_min) { x_min = p.x; }         if (p.x > x_max) { x_max = p.x; }         if (p.y &lt; y_min) { y_min = p.y; }         if (p.y > y_max) { y_max = p.y; }     }      float dx = x_max - x_min;     float dy = y_max - y_min;      float d_max = std::max(dx, dy);     float x_mid = x_min + dx * 0.5f;     float y_mid = y_min + dy * 0.5f;      return {          Point(x_mid - 20.0f * d_max, y_mid - d_max),         Point(x_mid, y_mid + 20.0f * d_max),         Point(x_mid + 20.0f * d_max, y_mid - d_max) }; }  TriangleCircle circumcircle(const std::vector&lt;Point> &amp;points, int i, int j, int k) {     const Point point_i = points[i];     const Point point_j = points[j];     const Point point_k = points[k];      float x_1 = point_i.x;     float y_1 = point_i.y;      float x_2 = point_j.x;     float y_2 = point_j.y;      float x_3 = point_k.x;     float y_3 = point_k.y;      float y1_y2 = std::abs(y_1 - y_2);     float y2_y3 = std::abs(y_2 - y_3);      float center_x = 0.0f;     float center_y = 0.0f;     float m_1 = 0.0f;     float m_2 = 0.0f;     float mx_1 = 0.0f;     float mx_2 = 0.0f;     float my_1 = 0.0f;     float my_2 = 0.0f;      float EPSILON = 0.00001f;      if (y1_y2 &lt; EPSILON)     {         m_2 = -(x_3 - x_2) \/ (y_3 - y_2);         mx_2 = (x_2 + x_3) \/ 2.0f;         my_2 = (y_2 + y_3) \/ 2.0f;         center_x = (x_2 + x_1) \/ 2.0f;         center_y = m_2 * (center_x - mx_2) + my_2;     }     else if (y2_y3 &lt; EPSILON)     {         m_1 = -(x_2 - x_1) \/ (y_2 - y_1);         mx_1 = (x_1 + x_2) \/ 2.0f;         my_1 = (y_1 + y_2) \/ 2.0f;         center_x = (x_3 + x_2) \/ 2.0f;         center_y = m_1 * (center_x - mx_1) + my_1;     }     else     {         m_1 = -(x_2 - x_1) \/ (y_2 - y_1);         m_2 = -(x_3 - x_2) \/ (y_3 - y_2);         mx_1 = (x_1 + x_2) \/ 2.0f;         mx_2 = (x_2 + x_3) \/ 2.0f;         my_1 = (y_1 + y_2) \/ 2.0f;         my_2 = (y_2 + y_3) \/ 2.0f;         center_x = (m_1 * mx_1 - m_2 * mx_2 + my_2 - my_1) \/ (m_1 - m_2);         center_y = y1_y2 > y2_y3 ? (m_1 * (center_x - mx_1) + my_1) : (m_2 * (center_x - mx_2) + my_2);     }      float dx = x_2 - center_x;     float dy = y_2 - center_y;      return TriangleCircle{ i, j, k, center_x, center_y, dx*dx + dy*dy}; }  void remove_duplicates(std::vector&lt;int> &amp;edges) {     int j = edges.size();     while (j >= 2)     {         int b = edges[--j];         int a = edges[--j];          int i = j;         while (i >= 2)         {             int n = edges[--i];             int m = edges[--i];              if ((a == m &amp;&amp; b == n) || (a == n &amp;&amp; b == m))             {                 edges.erase(std::next(edges.begin(), j), std::next(edges.begin(), j + 2));                 edges.erase(std::next(edges.begin(), i), std::next(edges.begin(), i + 2));                  j -= 2;                 break;             }         }     } }  std::vector&lt;int> triangulate(std::vector&lt;Point> &amp;points) {     size_t points_count = points.size();      \/\/ if the nmber is less than 3, nothing to do     if (points_count &lt; 3)     {         return std::vector&lt;int>(0);     }      \/\/ sort points by x coordinate     \/\/ create array with indices 0, 1, 2, ...     std::vector&lt;int> indices(points_count);     for (size_t  i = 0; i &lt; points_count; i++)     {         indices[i] = i;     }      \/\/ sort it by using input points     std::sort(indices.begin(), indices.end(), [&amp;points](int a, int b) { return points[a].x &lt; points[b].x; });      const std::vector&lt;Point> st = build_supertriangle(points);     \/\/ add points of the super triangle into input array     points.insert(points.end(), st.begin(), st.end());      \/\/ create buffers     std::vector&lt;TriangleCircle> open_list;     std::vector&lt;TriangleCircle> closed_list;     std::vector&lt;int> edges_list;      \/\/ init open buffer by super triangle     open_list.push_back(circumcircle(points, points_count, points_count + 1, points_count + 2));          for (size_t i = 0; i &lt; points_count; i++)     {         int c = indices[i];         Point p = points[c];         edges_list.clear();          for (int j = open_list.size() - 1; j >= 0; j--)         {             TriangleCircle t = open_list[j];                          float dx = p.x - t.x;             if (dx > 0.0f &amp;&amp; dx*dx > t.radius_sq)             {                 open_list.erase(open_list.begin() + j);                 closed_list.push_back(t);                 continue;             }              float dy = p.y - t.y;             if (dx*dx + dy*dy - t.radius_sq > 0.00001f)             {                 continue;             }              open_list.erase(open_list.begin() + j);             edges_list.insert(edges_list.end(), { t.i, t.j, t.j, t.k, t.k, t.i });         }          \/\/ delete edges with two triangles         remove_duplicates(edges_list);          \/\/ add triangles for the remain edges to the open list         int k = edges_list.size();         while (k >= 2)         {             int b = edges_list[--k];             int a = edges_list[--k];             open_list.push_back(circumcircle(points, a, b, c));         }     }      \/\/ add to the closest list all triangles from the remain open list     for (size_t i = 0; i &lt; open_list.size(); i++)     {         closed_list.push_back(open_list[i]);     }      open_list.clear();     edges_list.clear();      \/\/ form the output array     std::vector&lt;int> triangles;     for (size_t i = 0; i &lt; closed_list.size(); i++)     {         TriangleCircle t = closed_list[i];         if (t.i &lt; points_count &amp;&amp; t.j &lt; points_count &amp;&amp; t.k &lt; points_count)         {             triangles.insert(triangles.end(), { t.i, t.j, t.k });         }     }      closed_list.clear();      return triangles; }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u0424\u0430\u0439\u043b <code>bvh.h<\/code> \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u043a\u043b\u0430\u0441\u0441\u043e\u0432, \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b\u0445 \u0434\u043b\u044f \u043f\u043e\u0441\u0442\u0440\u043e\u0435\u043d\u0438\u044f \u0441\u0430\u043c\u043e\u0433\u043e \u0434\u0435\u0440\u0435\u0432\u0430 BVH. \u041e\u0431\u044a\u0435\u043a\u0442\u044b, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0441\u043a\u043b\u0430\u0434\u044b\u0432\u0430\u044e\u0442\u0441\u044f \u0432 bvh &#8212; \u044d\u0442\u043e \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u0430\u044f \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 <code>Triangle<\/code>, \u043f\u0440\u0435\u0434\u043d\u0430\u0437\u043d\u0430\u0447\u0435\u043d\u043d\u0430\u044f \u0434\u043b\u044f \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u044f \u0442\u0440\u0435\u0443\u0433\u043e\u043b\u044c\u043d\u0438\u043a\u043e\u0432 \u043d\u0430 \u043f\u043b\u043e\u0441\u043a\u043e\u0441\u0442\u0438.<\/p>\n<details class=\"spoiler\">\n<summary>bvh.h<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"cpp\">#pragma once #include \"point.h\" #include &lt;vector>  struct AABB { float x_min; float y_min; float x_max; float y_max;  std::string to_string() { return \"|\" + std::to_string(x_min) + \", \" + std::to_string(y_min) + \", \" + std::to_string(x_max) + \", \" + std::to_string(y_max) + \"|\"; } };  class Trinangle { public: Trinangle(const std::vector&lt;Point>&amp; vertices); ~Trinangle() {}; AABB get_aabb(); Point get_center(); bool is_point_inside(const Point &amp;point); std::string to_string();  Point get_a(); Point get_b(); Point get_c();  private: Point a; Point b; Point c;  AABB aabb; Point center; };  class BVHNode { public: BVHNode(const std::vector&lt;Trinangle*> &amp;triangles); ~BVHNode();  AABB get_aabb(); bool is_inside_aabb(const Point &amp;point); Trinangle* sample(const Point &amp;point);  private: Trinangle* triangle; BVHNode* left_node; BVHNode* right_node; AABB aabb; };<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u041d\u0443 \u0438 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u0439 \u0444\u0430\u0439\u043b <code>bvh.cpp<\/code> \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u043c\u0435\u0442\u043e\u0434\u043e\u0432 \u0434\u043b\u044f \u0432\u0441\u0435\u0445 \u043d\u0443\u0436\u043d\u044b\u0445 \u043a\u043b\u0430\u0441\u0441\u043e\u0432.<\/p>\n<details class=\"spoiler\">\n<summary>bvh.cpp<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"cpp\">#include &lt;iostream> #include &lt;float.h>  #include \"bvh.h\"  Trinangle::Trinangle(const std::vector&lt;Point> &amp;vertices) { a = vertices[0]; b = vertices[1]; c = vertices[2];  float x_min = FLT_MAX; float y_min = FLT_MAX; float x_max = FLT_MIN; float y_max = FLT_MIN;  float x_accum = 0.0f; float y_accum = 0.0f;  for (size_t i = 0; i &lt; vertices.size(); i++) { Point v = vertices[i]; if (v.x &lt; x_min) { x_min = v.x; } if (v.x > x_max) { x_max = v.x; } if (v.y &lt; y_min) { y_min = v.y; } if (v.y > y_max) { y_max = v.y; }  x_accum += v.x; y_accum += v.y; }  aabb = AABB{ x_min, y_min, x_max, y_max }; center = Point(x_accum \/ vertices.size(), y_accum \/ vertices.size()); }  AABB Trinangle::get_aabb() { return aabb; }  Point Trinangle::get_center() { return center; }  bool Trinangle::is_point_inside(const Point&amp; point) { float as_x = point.x - a.x; float as_y = point.y - a.y;  bool s_ab = ((b.x - a.x) * as_y - (b.y - a.y) * as_x) > 0;  if (((c.x - a.x) * as_y - (c.y - a.y) * as_x > 0) == s_ab) { return false; } if (((c.x - b.x) * (point.y - b.y) - (c.y - b.y) * (point.x - b.x) > 0) != s_ab) { return false; } return true; }  std::string Trinangle::to_string() { return \"&lt;\" + a.to_string() + \", \" + b.to_string() + \", \" + c.to_string() + \">\"; }  Point Trinangle::get_a() { return a; }  Point Trinangle::get_b() { return b; } Point Trinangle::get_c() { return c; }  AABB union_aabb(AABB &amp;x, AABB &amp;y) { return AABB { std::min(x.x_min, y.x_min), std::min(x.y_min, y.y_min),  std::max(x.x_max, y.x_max), std::max(x.y_max, y.y_max) }; }  BVHNode::BVHNode(const std::vector&lt;Trinangle*>&amp; triangles) { triangle = NULL; left_node = NULL; right_node = NULL;  int objects_count = triangles.size(); if (objects_count == 1) { triangle = triangles[0]; aabb = triangle->get_aabb(); } else { float x_median = 0.0f; float y_median = 0.0f;  float x_min = FLT_MAX; float x_max = FLT_MIN; float y_min = FLT_MAX; float y_max = FLT_MIN;  for (size_t i = 0; i &lt; objects_count; i++) { Trinangle* t = triangles[i]; Point c = t->get_center(); x_median += c.x; y_median += c.y;  if (c.x &lt; x_min) { x_min = c.x; } if (c.x > x_max) { x_max = c.x; } if (c.y &lt; y_min) { y_min = c.y; } if (c.y > y_max) { y_max = c.y; } }  int split_axis = ((x_max - x_min) > (y_max - y_min)) ? 0 : 1; float median = split_axis == 0 ? (x_median \/ objects_count) : (y_median \/ objects_count);  std::vector&lt;Trinangle*> left; std::vector&lt;Trinangle*> right;  for (size_t i = 0; i &lt; objects_count; i++) { Trinangle* t = triangles[i]; Point c = t->get_center(); float v = split_axis == 0 ? c.x : c.y; if (v &lt; median) { left.push_back(t); } else { right.push_back(t); } }  if (left.size() == 0) { left.push_back(right[right.size() - 1]); right.pop_back(); }  if (right.size() == 0) { right.push_back(left[left.size() - 1]); left.pop_back(); }  left_node = new BVHNode(left); right_node = new BVHNode(right);  AABB left_aabb = left_node->get_aabb(); AABB right_aabb = right_node->get_aabb();  aabb = union_aabb(left_aabb, right_aabb); } }  BVHNode::~BVHNode() { if (triangle) { delete triangle; } if (left_node) { delete left_node; } if (right_node) { delete right_node; } }  AABB BVHNode::get_aabb() { return aabb; }  bool BVHNode::is_inside_aabb(const Point&amp; point) { return aabb.x_min &lt; point.x &amp;&amp; aabb.y_min &lt; point.y &amp;&amp; aabb.x_max > point.x &amp;&amp; aabb.y_max > point.y; }  Trinangle* BVHNode::sample(const Point&amp; point) { if (is_inside_aabb(point)) { if (!triangle &amp;&amp; left_node &amp;&amp; right_node) { Trinangle* left_sample = left_node->sample(point); Trinangle* right_sample = right_node->sample(point);  if (!left_sample) { return right_sample; } else { if (!right_sample) { return left_sample; } else { Point l_c = left_sample->get_center(); float l_dist = (l_c.x - point.x) * (l_c.x - point.x) + (l_c.y - point.y) * (l_c.y - point.y);  Point r_c = right_sample->get_center(); float r_dist = (r_c.x - point.x) * (r_c.x - point.x) + (r_c.y - point.y) * (r_c.y - point.y);  if (l_dist &lt; r_dist) { return left_sample; } else { return right_sample; } } } } else { if (triangle &amp;&amp; triangle->is_point_inside(point)) { return triangle; } else { return NULL; } } } else { return NULL; } }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043c\u043e\u0436\u0435\u043c \u0432\u043e\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u043d\u043e\u0439 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u043e\u0439. \u0421\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u0432\u043e\u0442 \u0442\u0430\u043a\u043e\u0439 \u0444\u0430\u0439\u043b <code>main.cpp<\/code>.<\/p>\n<details class=\"spoiler\">\n<summary>main.cpp<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"cpp\">#include \"delaunay.h\" #include \"bvh.h\"  #include &lt;iostream>  void console_log(const std::vector&lt;int>&amp; array) {     std::cout &lt;&lt; \"[\";     for (size_t i = 0; i &lt; array.size(); i++)     {         std::cout &lt;&lt; array[i] &lt;&lt; (i == array.size() - 1 ? \"\" : \", \");     }      std::cout &lt;&lt; \"]\" &lt;&lt; std::endl; }  int main() {     std::vector&lt;Point> points = {          Point(-0.5, 3.0),          Point(8.0, -3.5),          Point(-7.0, 3.0),          Point(2.0, -10.0),          Point(7.0, 8.0),          Point(8.0, 5.5)      };     std::vector&lt;int> triangle_indices = triangulate(points);      console_log(triangle_indices);      std::vector&lt;Trinangle*> triangles(triangle_indices.size() \/ 3);     for (size_t i = 0; i &lt; triangles.size(); i++)     {         int a = triangle_indices[3 * i];         int b = triangle_indices[3 * i + 1];         int c = triangle_indices[3 * i + 2];         std::vector&lt;Point> vertices = { points[a], points[b], points[c] };         triangles[i] = new Trinangle(vertices);     }      BVHNode* tree = new BVHNode(triangles);     Point p = Point(0.0f, 0.0f);     Trinangle* sample_result = tree->sample(p);      if (sample_result)     {         std::cout &lt;&lt; sample_result->to_string() &lt;&lt; std::endl;     }     else     {         std::cout &lt;&lt; \"Empty sample\" &lt;&lt; std::endl;     } } <\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u041e\u0442\u043a\u043e\u043c\u043f\u0438\u043b\u0438\u0440\u0443\u0435\u043c \u0435\u0433\u043e \u0438 \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u043c. \u041e\u043d \u0432\u044b\u0432\u0435\u0434\u0435\u0442 \u043d\u0430 \u044d\u043a\u0440\u0430\u043d \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u044b\u0439 \u043e\u0442\u0432\u0435\u0442<\/p>\n<pre><code>[2, 0, 3, 0, 2, 4, 3, 0, 1, 1, 0, 5, 0, 4, 5] &lt;(-7.000000, 3.000000), (-0.500000, 3.000000), (2.000000, -10.000000)><\/code><\/pre>\n<p>\u041f\u0435\u0440\u0432\u0430\u044f \u0441\u0442\u0440\u043e\u0447\u043a\u0430 &#8212; \u0438\u043d\u0434\u0435\u043a\u0441\u044b \u0442\u0440\u0435\u0443\u0433\u043e\u043b\u044c\u043d\u0438\u043a\u043e\u0432 \u0442\u0440\u0438\u0430\u043d\u0433\u0443\u043b\u044f\u0446\u0438\u0438. \u0412\u0442\u043e\u0440\u0430\u044f \u0441\u0442\u0440\u043e\u0447\u043a\u0430 &#8212; \u0432\u0435\u0440\u0448\u0438\u043d\u044b \u0442\u0440\u0435\u0443\u0433\u043e\u043b\u044c\u043d\u0438\u043a\u0430, \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0449\u0435\u0433\u043e \u043d\u0430\u0447\u0430\u043b\u043e \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442.<\/p>\n<p>\u0412\u0441\u0451, \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0430 \u0433\u043e\u0442\u043e\u0432\u0430, \u0442\u0435\u043f\u0435\u0440\u044c \u043c\u043e\u0436\u043d\u043e \u043d\u0430\u0447\u0438\u043d\u0430\u0442\u044c \u0435\u0451 \u044d\u043a\u0441\u043f\u043e\u0440\u0442 \u0432 \u043c\u043e\u0434\u0443\u043b\u044c WebAssembly. \u041d\u043e \u0441\u043d\u0430\u0447\u0430\u043b\u0430 \u043d\u0430\u0434\u043e \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u0442\u044c\u0441\u044f, \u0447\u0442\u043e \u043c\u044b, \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u043e, \u0445\u043e\u0442\u0438\u043c \u044d\u043a\u0441\u043f\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c.<\/p>\n<ul>\n<li>\n<p>\u0424\u0443\u043d\u043a\u0446\u0438\u044e \u0434\u043b\u044f \u043f\u043e\u0441\u0442\u0440\u043e\u0435\u043d\u0438\u044f \u0442\u0440\u0438\u0430\u043d\u0433\u0443\u043b\u044f\u0446\u0438\u0438<\/p>\n<\/li>\n<li>\n<p>\u041a\u043b\u0430\u0441\u0441 <code>BVHNode<\/code><\/p>\n<\/li>\n<li>\n<p>\u041c\u0435\u0442\u043e\u0434 <code>sample<\/code> \u0443 \u043a\u043b\u0430\u0441\u0441\u0430 <code>BVHNode<\/code>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043d\u0430\u0445\u043e\u0434\u0438\u0442 \u0442\u0440\u0435\u0443\u0433\u043e\u043b\u044c\u043d\u0438\u043a, \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0449\u0438\u0439 \u0434\u0430\u043d\u043d\u0443\u044e \u0442\u043e\u0447\u043a\u0443<\/p>\n<\/li>\n<\/ul>\n<h4>\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 Emscripten<\/h4>\n<p>Emscripten &#8212; \u044d\u0442\u043e \u043d\u0430\u0431\u043e\u0440 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u043e\u0432, \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u044e\u0449\u0438\u0445 \u043e\u0442\u043a\u043e\u043c\u043f\u0438\u043b\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043a\u043e\u0434 \u043d\u0430 c \u0438 c++ \u0432 \u043c\u043e\u0434\u0443\u043b\u044c WebAssembly. \u041a\u0430\u043a \u0443\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0442\u044c Emscripten \u0441\u043a\u0430\u0437\u0430\u043d\u043e \u0432 <a href=\"https:\/\/emscripten.org\/docs\/getting_started\/downloads.html\" rel=\"noopener noreferrer nofollow\">\u043e\u0444\u0438\u0446\u0438\u0430\u043b\u044c\u043d\u043e\u0439 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438<\/a>. \u041f\u043e \u0441\u0443\u0442\u0438 \u0434\u0435\u043b\u0430 \u043d\u0430\u0434\u043e \u043f\u0440\u043e\u0441\u0442\u043e \u043a\u043b\u043e\u043d\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0439 \u043d\u0430 \u0433\u0438\u0442\u0445\u0430\u0431\u0435. \u0421\u0430\u043c Emscripten \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u043e\u0432 \u0434\u043b\u044f \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0446\u0438\u0438 c++ \u043a\u043e\u0434\u0430 \u0432 WebAssembly. \u041f\u0440\u0435\u0434\u043b\u0430\u0433\u0430\u0435\u0442\u0441\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c <code>embind<\/code><\/p>\n<p>\u0418 \u043e\u043f\u044f\u0442\u044c \u0436\u0435, \u0434\u043b\u044f \u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u0432\u0441\u0451 \u0431\u044b\u043b\u043e \u043c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u043e \u043f\u0440\u043e\u0441\u0442\u043e, \u043f\u043e\u0441\u0442\u0430\u0440\u0430\u0435\u043c\u0441\u044f \u0434\u0435\u043b\u0430\u0442\u044c \u043a\u0430\u043a \u043c\u043e\u0436\u043d\u043e \u0431\u043e\u043b\u044c\u0448\u0435 \u0432\u0435\u0449\u0435\u0439 \u0432\u0440\u0443\u0447\u043d\u0443\u044e. \u042d\u0442\u043e \u043f\u043e\u0437\u0432\u043e\u043b\u0438\u0442 \u0438\u0437\u0431\u0435\u0436\u0430\u0442\u044c \u0441\u0438\u0442\u0443\u0430\u0446\u0438\u0439, \u043a\u043e\u0433\u0434\u0430 &#171;\u043e\u043d\u043e \u0442\u0430\u043c \u0441\u0430\u043c\u043e&#187;. \u041d\u0430 \u0441\u0430\u043c\u043e\u043c \u0434\u0435\u043b\u0435 \u044f \u043f\u0440\u043e\u0441\u0442\u043e \u043f\u043e \u0434\u0440\u0443\u0433\u043e\u043c\u0443 \u043d\u0435 \u0443\u043c\u0435\u044e \u0438 \u043f\u0440\u044f\u0447\u0443 \u044d\u0442\u043e \u0437\u0430 \u0434\u0435\u043c\u043e\u043d\u0441\u0442\u0440\u0430\u0446\u0438\u0435\u0439 \u0437\u0430\u0431\u043e\u0442\u044b \u043e \u0447\u0438\u0442\u0430\u0442\u0435\u043b\u0435.<\/p>\n<p>\u0421\u043e\u0437\u0434\u0430\u0451\u043c \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0439 \u0444\u0430\u0439\u043b, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u0442 \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0442\u044c \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u0442\u043e\u0433\u043e, \u0447\u0442\u043e \u043c\u044b \u0445\u043e\u0442\u0438\u043c \u044d\u043a\u0441\u043f\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c, \u0430 \u0442\u0430\u043a\u0436\u0435 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f \u043f\u043e \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u044e \u0434\u0430\u043d\u043d\u044b\u0445 \u043c\u0435\u0436\u0434\u0443 \u043d\u0430\u0448\u0435\u0439 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u043e\u0439 \u043d\u0430 c++ \u0438 \u0442\u0435\u043c\u0438 \u0434\u0430\u043d\u043d\u044b\u043c\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043f\u0440\u0438\u0445\u043e\u0434\u044f\u0442 \u0438\u0437\u0432\u043d\u0435, \u0430 \u0442\u0430\u043a\u0436\u0435 \u0442\u0443\u0434\u0430 \u0443\u0445\u043e\u0434\u044f\u0442. \u041d\u0430\u0437\u043e\u0432\u0451\u043c \u0435\u0433\u043e <code>delaunay_api.cpp<\/code><\/p>\n<p>\u0412\u043e\u0442 \u0435\u0433\u043e \u043a\u043e\u0434<\/p>\n<details class=\"spoiler\">\n<summary>delaunay_api.cpp<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"cpp\"> #include &lt;emscripten\/bind.h> #include &lt;emscripten\/val.h>  #include \"point.h\" #include \"delaunay.h\" #include \"bvh.h\"  using namespace emscripten;  emscripten::val build_triangulation(const emscripten::val &amp;in_coordinates) { \/\/ prepare input const std::vector&lt;float> coordinates = convertJSArrayToNumberVector&lt;float>(in_coordinates);  int points_count = coordinates.size() \/ 2; std::vector&lt;Point> points(points_count); for (size_t i = 0; i &lt; points_count; i++) { points[i] = Point(coordinates[2*i], coordinates[2*i + 1]); }  std::vector&lt;int> triangles = triangulate(points);  \/\/ prepare output emscripten::val view{ emscripten::typed_memory_view(triangles.size(), triangles.data()) }; emscripten::val result = emscripten::val::global(\"Int32Array\").new_(triangles.size()); result.call&lt;void>(\"set\", view);  return result; }  class BVHNodeWrapper { public: BVHNodeWrapper(const emscripten::val &amp;in_coordinates); BVHNodeWrapper(const emscripten::val &amp;in_coordinates, const emscripten::val &amp;in_triangles); ~BVHNodeWrapper();  emscripten::val sample(float x, float y);  private: BVHNode* bvh; };  BVHNodeWrapper::BVHNodeWrapper(const emscripten::val &amp;in_coordinates) { const std::vector&lt;float> coordinates = convertJSArrayToNumberVector&lt;float>(in_coordinates);  int points_count = coordinates.size() \/ 2; std::vector&lt;Point> points(points_count); for (size_t i = 0; i &lt; points_count; i++) { points[i] = Point(coordinates[2*i], coordinates[2*i + 1]); }  std::vector&lt;int> trinagle_indices = triangulate(points); int trinagles_count = trinagle_indices.size() \/ 3; std::vector&lt;Trinangle*> trinagles(trinagles_count); for (size_t i = 0; i &lt; trinagles_count; i++) { int a = trinagle_indices[3 * i]; int b = trinagle_indices[3 * i + 1]; int c = trinagle_indices[3 * i + 2];  std::vector&lt;Point> vertices = { points[a], points[b], points[c] }; trinagles[i] = new Trinangle(vertices); }  bvh = new BVHNode(trinagles); }  BVHNodeWrapper::BVHNodeWrapper(const emscripten::val &amp;in_coordinates, const emscripten::val &amp;in_triangles) { const std::vector&lt;float> coordinates = convertJSArrayToNumberVector&lt;float>(in_coordinates); const std::vector&lt;int> triangles = convertJSArrayToNumberVector&lt;int>(in_triangles);  int triangles_count = triangles.size() \/ 3; std::vector&lt;Trinangle*> triangles_array(triangles_count); for (size_t i = 0; i &lt; triangles_count; i++) { int a = triangles[3 * i]; int b = triangles[3 * i + 1]; int c = triangles[3 * i + 2];  std::vector&lt;Point> vertices = { Point(coordinates[2 * a], coordinates[2 * a + 1]), Point(coordinates[2 * b], coordinates[2 * b + 1]), Point(coordinates[2 * c], coordinates[2 * c + 1]) }; triangles_array[i] = new Trinangle(vertices); }  bvh = new BVHNode(triangles_array); }  BVHNodeWrapper::~BVHNodeWrapper() { delete bvh; }  emscripten::val BVHNodeWrapper::sample(float x, float y) { Point p = Point(x, y); Trinangle* s = bvh->sample(p); std::vector&lt;float> to_return(0); if (s) { Point a = s->get_a(); Point b = s->get_b(); Point c = s->get_c();  to_return.insert(to_return.end(), { a.x, a.y, b.x, b.y, c.x, c.y }); }  emscripten::val view{ emscripten::typed_memory_view(to_return.size(), to_return.data()) }; emscripten::val result = emscripten::val::global(\"Float32Array\").new_(to_return.size()); result.call&lt;void>(\"set\", view);  return result; }  EMSCRIPTEN_BINDINGS(delaunay_module) { class_&lt;BVHNodeWrapper>(\"BVHNode\") .constructor&lt;emscripten::val>() .constructor&lt;emscripten::val, emscripten::val>() .function(\"sample\", &amp;BVHNodeWrapper::sample); function(\"build_triangulation\", &amp;build_triangulation); }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u0422\u0443\u0442 \u043d\u0443\u0436\u043d\u044b \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0438 \u043f\u043e \u043f\u043e\u0432\u043e\u0434\u0443 \u0442\u043e\u0433\u043e, \u0447\u0442\u043e \u0434\u0435\u043b\u0430\u0435\u0442\u0441\u044f. \u0421\u0430\u043c\u043e\u0435 \u0433\u043b\u0430\u0432\u043d\u043e\u0435 &#8212; \u044d\u0442\u043e \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u0439 \u0443\u0447\u0430\u0441\u0442\u043e\u043a \u043a\u043e\u0434\u0430 <code>EMSCRIPTEN_BINDINGS(delaunay_module) { \/*...*\/ }<\/code>\u0412 \u043d\u0451\u043c \u043a\u0430\u043a \u0440\u0430\u0437 \u0438 \u043e\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0447\u0442\u043e \u043c\u044b \u0445\u043e\u0442\u0438\u043c \u044d\u043a\u0441\u043f\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0432 \u043c\u043e\u0434\u0443\u043b\u044c. \u041f\u0440\u043e\u0449\u0435 \u0432\u0441\u0435\u0433\u043e \u043e\u043f\u0438\u0441\u0430\u0442\u044c \u044d\u043a\u0441\u043f\u043e\u0440\u0442 \u0444\u0443\u043d\u043a\u0446\u0438\u0439. \u0417\u0434\u0435\u0441\u044c \u044d\u0442\u043e \u0441\u0434\u0435\u043b\u0430\u043d\u043e \u043e\u0434\u043d\u043e\u0439 \u0441\u0442\u0440\u043e\u0447\u043a\u043e\u0439<\/p>\n<pre><code class=\"cpp\">function(\"build_triangulation\", &amp;build_triangulation);<\/code><\/pre>\n<p>\u0421\u043c\u044b\u0441\u043b \u0435\u0451 \u0441\u043e\u0432\u0435\u0440\u0448\u0435\u043d\u043d\u043e \u043f\u043e\u043d\u044f\u0442\u0435\u043d. \u0423\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c \u0438\u043c\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u0438, \u043f\u043e \u043a\u043e\u0442\u043e\u0440\u043e\u043c\u0443 \u043e\u043d\u0430 \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u0437\u044b\u0432\u0430\u0442\u044c\u0441\u044f \u0438\u0437\u0432\u043d\u0435, \u0430 \u0442\u0430\u043a\u0436\u0435 \u0441\u0441\u044b\u043b\u043a\u0443 \u043d\u0430 \u043d\u0435\u043f\u043e\u0441\u0440\u0435\u0434\u0441\u0442\u0432\u0435\u043d\u043d\u0443\u044e \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e \u044d\u0442\u043e\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u0438. \u0417\u0434\u0435\u0441\u044c \u043c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u043f\u0440\u043e\u043c\u0435\u0436\u0443\u0442\u043e\u0447\u043d\u0443\u044e \u0444\u0443\u043d\u043a\u0446\u0438\u044e <code>build_triangulation<\/code>, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442 \u0438 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u044b \u0442\u0438\u043f\u0430 <code>emscripten::val<\/code>. \u042d\u0442\u043e\u0442 \u0442\u0438\u043f &#8212; \u044d\u0442\u043e \u043e\u0431\u0451\u0440\u0442\u043a\u0430 \u043d\u0430\u0434 \u0442\u0435\u043c\u0438 \u0434\u0430\u043d\u043d\u044b\u043c\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043f\u0435\u0440\u0435\u0434\u0430\u044e\u0442\u0441\u044f \u0432 \u043c\u043e\u0434\u0443\u043b\u044c \u0438 \u0437\u0430\u0431\u0438\u0440\u0430\u044e\u0442\u0441\u044f \u0438\u0437 \u043d\u0435\u0433\u043e. \u041d\u0430\u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 <code>build_triangulation <\/code>\u0441\u043e\u0441\u0442\u043e\u0438\u0442 \u0432 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u043c:<\/p>\n<ul>\n<li>\n<p>\u041f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u0442\u044c \u043f\u0440\u0438\u0448\u0435\u0434\u0448\u0438\u0435 \u0434\u0430\u043d\u043d\u044b\u0435 \u0432 \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u044b\u0439 \u0444\u043e\u0440\u043c\u0430\u0442. \u041a\u043e\u043c\u0430\u043d\u0434\u0430  <code>convertJSArrayToNumberVector&lt;float><\/code> \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 <code>std::vector&lt;float><\/code><\/p>\n<\/li>\n<li>\n<p>\u0421\u0444\u043e\u0440\u043c\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0438\u0437 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u043e\u0433\u043e \u043d\u0430\u0431\u043e\u0440\u0430 \u0447\u0438\u0441\u0435\u043b \u043c\u0430\u0441\u0441\u0438\u0432 \u0442\u043e\u0447\u0435\u043a<\/p>\n<\/li>\n<li>\n<p>\u0412\u044b\u0437\u0432\u0430\u0442\u044c \u0434\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u043c\u0430\u0441\u0441\u0438\u0432\u0430 \u0442\u043e\u0447\u0435\u043a \u043d\u0430\u0448\u0443 \u0433\u043e\u0442\u043e\u0432\u0443\u044e \u0444\u0443\u043d\u043a\u0446\u0438\u044e <code>triangulate<\/code><\/p>\n<\/li>\n<li>\n<p>\u041f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u0442\u044c \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u044b\u0439 \u043c\u0430\u0441\u0441\u0438\u0432 \u0446\u0435\u043b\u044b\u0445 \u0447\u0438\u0441\u0435\u043b \u0432 \u0442\u043e, \u0447\u0442\u043e \u0441\u043d\u0430\u0440\u0443\u0436\u0438 \u0431\u0443\u0434\u0435\u0442 \u043f\u043e\u043d\u044f\u0442\u043e \u043a\u0430\u043a <code>Int32Array<\/code>. \u042d\u0442\u043e \u0434\u0435\u043b\u0430\u0435\u0442\u0441\u044f \u0442\u0440\u0435\u043c\u044f \u043a\u043e\u043c\u0430\u043d\u0434\u0430\u043c\u0438<\/p>\n<pre><code class=\"cpp\">emscripten::val view{ emscripten::typed_memory_view(triangles.size(), triangles.data()) }; emscripten::val result = emscripten::val::global(\"Int32Array\").new_(triangles.size()); result.call&lt;void>(\"set\", view);<\/code><\/pre>\n<\/li>\n<\/ul>\n<p>\u0412 \u043e\u0431\u0449\u0435\u043c-\u0442\u043e \u043d\u0438\u0447\u0435\u0433\u043e \u0441\u043b\u043e\u0436\u043d\u043e\u0433\u043e. \u041e\u0434\u043d\u0430\u043a\u043e, \u043a\u0430\u043a \u043c\u044b \u0432\u0438\u0434\u0438\u043c, \u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0440\u0430\u0431\u043e\u0442\u0430 \u043f\u043e \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u044e \u0434\u0430\u043d\u043d\u044b\u0445.<\/p>\n<p>\u0414\u043b\u044f \u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u044d\u043a\u0441\u043f\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043a\u043b\u0430\u0441\u0441 <code>BVHNode <\/code>\u043c\u044b \u0441\u0434\u0435\u043b\u0430\u0435\u043c \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0439 \u043a\u043b\u0430\u0441\u0441-\u043e\u0431\u0451\u0440\u0442\u043a\u0443, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u0442 \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0442\u044c \u043d\u0443\u0436\u043d\u044b\u0435 \u043d\u0430\u043c \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440\u044b \u0438 \u0442\u043e\u043b\u044c\u043a\u043e \u0442\u0435 \u043c\u0435\u0442\u043e\u0434\u044b, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043c\u044b \u0445\u043e\u0442\u0438\u043c \u044d\u043a\u0441\u043f\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c. \u0418\u0442\u0430\u043a, \u0441\u043e\u0437\u0434\u0430\u0451\u043c \u043a\u043b\u0430\u0441\u0441 <code>BVHNodeWrapper<\/code><\/p>\n<details class=\"spoiler\">\n<summary>BVHNodeWrapper<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"cpp\">class BVHNodeWrapper { public: BVHNodeWrapper(const emscripten::val &amp;in_coordinates); BVHNodeWrapper(const emscripten::val &amp;in_coordinates, const emscripten::val &amp;in_triangles); ~BVHNodeWrapper();  emscripten::val sample(float x, float y);  private: BVHNode* bvh; };<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u0412 \u043d\u0451\u043c \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u043c \u0434\u0432\u0430 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440\u0430. \u041f\u0435\u0440\u0432\u044b\u0439 \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442 \u043d\u0430 \u0432\u0445\u043e\u0434 \u0442\u043e\u043b\u044c\u043a\u043e \u043c\u0430\u0441\u0441\u0438\u0432 \u0441 \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u0430\u043c\u0438 \u0442\u043e\u0447\u0435\u043a. \u041c\u044b \u0443\u0436\u0435 \u0443\u043c\u0435\u0435\u043c \u0435\u0433\u043e \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u044b\u0432\u0430\u0442\u044c \u0432 \u0444\u043e\u0440\u043c\u0430\u0442 <code>std::vector&lt;float><\/code>. \u0414\u0430\u043b\u0435\u0435 \u0441\u0442\u0440\u043e\u0438\u043c \u0442\u0440\u0438\u0430\u043d\u0433\u0443\u043b\u044f\u0446\u0438\u044e, \u043f\u043e\u0442\u043e\u043c \u0442\u0440\u0435\u0443\u0433\u043e\u043b\u044c\u043d\u0438\u043a\u0438 \u0438 \u0443\u043f\u0430\u043a\u043e\u0432\u044b\u0432\u0430\u0435\u043c \u0438\u0445 \u0432 BVH, \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u044f \u0441\u0441\u044b\u043b\u043a\u0443 \u043d\u0430 BVH \u0432\u043e \u0432\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u0435\u0439 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0439.<\/p>\n<details class=\"spoiler\">\n<summary>\u041f\u0435\u0440\u0432\u044b\u0439 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440 \u043a\u043b\u0430\u0441\u0441\u0430 BVHNodeWrapper<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"cpp\">BVHNodeWrapper::BVHNodeWrapper(const emscripten::val &amp;in_coordinates) { const std::vector&lt;float> coordinates = convertJSArrayToNumberVector&lt;float>(in_coordinates);  int points_count = coordinates.size() \/ 2; std::vector&lt;Point> points(points_count); for (size_t i = 0; i &lt; points_count; i++) { points[i] = Point(coordinates[2*i], coordinates[2*i + 1]); }  std::vector&lt;int> trinagle_indices = triangulate(points); int trinagles_count = trinagle_indices.size() \/ 3; std::vector&lt;Trinangle*> trinagles(trinagles_count); for (size_t i = 0; i &lt; trinagles_count; i++) { int a = trinagle_indices[3 * i]; int b = trinagle_indices[3 * i + 1]; int c = trinagle_indices[3 * i + 2];  std::vector&lt;Point> vertices = { points[a], points[b], points[c] }; trinagles[i] = new Trinangle(vertices); }  bvh = new BVHNode(trinagles); }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u0414\u0440\u0443\u0433\u043e\u0439 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440 \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442 \u043c\u0430\u0441\u0441\u0438\u0432 \u0441 \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u0430\u043c\u0438 \u0438 \u043c\u0430\u0441\u0441\u0438\u0432 \u0441 \u0438\u043d\u0434\u0435\u043a\u0441\u0430\u043c\u0438 \u0432\u0435\u0440\u0448\u0438\u043d \u0442\u0440\u0435\u0443\u0433\u043e\u043b\u044c\u043d\u0438\u043a\u043e\u0432. \u0412 \u044d\u0442\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u043f\u0440\u043e\u0441\u0442\u043e \u0440\u0430\u0437\u0431\u0438\u0440\u0430\u0435\u043c \u0438\u0445 \u0438 \u0441\u0442\u0440\u043e\u0438\u043c \u0438\u0437 \u0442\u0440\u0435\u0443\u0433\u043e\u043b\u044c\u043d\u0438\u043a\u043e\u0432 BVH.<\/p>\n<details class=\"spoiler\">\n<summary>\u0412\u0442\u043e\u0440\u043e\u0439 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440 \u043a\u043b\u0430\u0441\u0441\u0430 BVHNodeWrapper<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"cpp\">BVHNodeWrapper::BVHNodeWrapper(const emscripten::val &amp;in_coordinates, const emscripten::val &amp;in_triangles) { const std::vector&lt;float> coordinates = convertJSArrayToNumberVector&lt;float>(in_coordinates); const std::vector&lt;int> triangles = convertJSArrayToNumberVector&lt;int>(in_triangles);  int triangles_count = triangles.size() \/ 3; std::vector&lt;Trinangle*> triangles_array(triangles_count); for (size_t i = 0; i &lt; triangles_count; i++) { int a = triangles[3 * i]; int b = triangles[3 * i + 1]; int c = triangles[3 * i + 2];  std::vector&lt;Point> vertices = { Point(coordinates[2 * a], coordinates[2 * a + 1]), Point(coordinates[2 * b], coordinates[2 * b + 1]), Point(coordinates[2 * c], coordinates[2 * c + 1]) }; triangles_array[i] = new Trinangle(vertices); }  bvh = new BVHNode(triangles_array); }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u041d\u0443 \u0438, \u043d\u0430\u043a\u043e\u043d\u0435\u0446, \u043c\u0435\u0442\u043e\u0434 <code>sample<\/code>. \u041d\u0430 \u0432\u0445\u043e\u0434 \u043e\u043d \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442 \u0434\u0432\u0430 \u0447\u0438\u0441\u043b\u0430. \u0421\u0442\u0440\u043e\u0438\u043c \u0438\u0437 \u043d\u0438\u0445 \u0442\u043e\u0447\u043a\u0443, \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u043c \u043c\u0435\u0442\u043e\u0434 <code>sample<\/code> \u0443 \u043e\u0431\u044a\u0435\u043a\u0442\u0430, \u0441\u043e\u0445\u0440\u0430\u043d\u0451\u043d\u043d\u043e\u0433\u043e \u0432\u043e \u0432\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u0435\u0439 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0439. \u0414\u0430\u043b\u0435\u0435 \u0444\u043e\u0440\u043c\u0438\u0440\u0443\u0435\u043c \u043e\u0442\u0432\u0435\u0442 \u0432 \u0432\u0438\u0434\u0435 \u043c\u0430\u0441\u0441\u0438\u0432\u0430 \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442 \u0432\u0435\u0440\u0448\u0438\u043d (\u0438\u043b\u0438 \u043f\u0443\u0441\u0442\u043e\u0433\u043e \u043c\u0430\u0441\u0441\u0438\u0432\u0430, \u0435\u0441\u043b\u0438 \u0442\u043e\u0447\u043a\u0430 \u043d\u0435 \u043f\u0440\u0438\u043d\u0430\u0434\u043b\u0435\u0436\u0438\u0442 \u043d\u0438\u043a\u0430\u043a\u043e\u043c\u0443 \u0442\u0440\u0435\u0443\u0433\u043e\u043b\u044c\u043d\u0438\u043a\u0443).<\/p>\n<details class=\"spoiler\">\n<summary>\u041c\u0435\u0442\u043e\u0434 sample \u043a\u043b\u0430\u0441\u0441\u0430 BVHNodeWrapper<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"cpp\">emscripten::val BVHNodeWrapper::sample(float x, float y) { Point p = Point(x, y); Trinangle* s = bvh->sample(p); std::vector&lt;float> to_return(0); if (s) { Point a = s->get_a(); Point b = s->get_b(); Point c = s->get_c();  to_return.insert(to_return.end(), { a.x, a.y, b.x, b.y, c.x, c.y }); }  emscripten::val view{ emscripten::typed_memory_view(to_return.size(), to_return.data()) }; emscripten::val result = emscripten::val::global(\"Float32Array\").new_(to_return.size()); result.call&lt;void>(\"set\", view);  return result; }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u041e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u044d\u043a\u0441\u043f\u043e\u0440\u0442\u0430 \u043a\u043b\u0430\u0441\u0441\u0430 \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c<\/p>\n<pre><code class=\"cpp\">class_&lt;BVHNodeWrapper>(\"BVHNode\")     .constructor&lt;emscripten::val>()     .constructor&lt;emscripten::val, emscripten::val>()     .function(\"sample\", &amp;BVHNodeWrapper::sample);<\/code><\/pre>\n<p>\u0417\u0434\u0435\u0441\u044c \u0443\u043a\u0430\u0437\u0430\u043d\u043e, \u0447\u0442\u043e\u0431\u044b \u043a\u043b\u0430\u0441\u0441 <code>BVHNodeWrapper<\/code> \u044d\u043a\u0441\u043f\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u043b\u0441\u044f \u0441 \u0438\u043c\u0435\u043d\u0435\u043c <code>BVHNode<\/code>. \u041f\u043e\u0442\u043e\u043c \u0441\u043a\u0430\u0437\u0430\u043d\u043e, \u043a\u0430\u043a\u0438\u0435 \u0443 \u043d\u0435\u0433\u043e \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440\u044b \u0438 \u043a\u0430\u043a\u0438\u0435 \u043c\u0435\u0442\u043e\u0434\u044b (\u043e\u043d \u0442\u0443\u0442 \u043e\u0434\u0438\u043d).<\/p>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u0441\u043a\u043e\u043c\u043f\u0438\u043b\u0438\u0440\u0443\u0435\u043c \u043d\u0430\u0448 \u0444\u0430\u0439\u043b <code>delaunay_api.cpp<\/code> \u0432 \u043c\u043e\u0434\u0443\u043b\u044c WebAssembly. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u043d\u0430\u0434\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u044b\u0439 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440 Emscripten. \u0427\u0442\u043e\u0431\u044b \u043d\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043d\u0438\u043a\u0430\u043a\u0438\u0445 \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0445 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0435\u0439, \u0441\u0434\u0435\u043b\u0430\u0435\u043c \u044d\u0442\u043e \u0432\u0440\u0443\u0447\u043d\u0443\u044e. <\/p>\n<p>\u0418\u0442\u0430\u043a, \u0441\u043d\u0430\u0447\u0430\u043b\u0430 \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u043c \u0444\u0430\u0439\u043b <code>emcmdprompt.bat<\/code> \u0438\u0437 \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u0438 \u0441\u043e \u0441\u043a\u0430\u0447\u0435\u043d\u043d\u044b\u043c Emscripten-\u043e\u043c. \u042d\u0442\u043e \u0434\u043b\u044f \u0442\u0435\u0445, \u0443 \u043a\u043e\u0433\u043e Windows. \u0423 \u043a\u043e\u0433\u043e Linux &#8212; \u0442\u0435 \u0441\u0430\u043c\u0438 \u0440\u0430\u0437\u0431\u0435\u0440\u0443\u0442\u0441\u044f, \u0447\u0442\u043e \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0442\u044c. \u0412 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0435 \u043e\u0442\u043a\u0440\u043e\u0435\u0442\u0441\u044f \u043e\u043a\u043d\u043e \u0442\u0435\u0440\u043c\u0438\u043d\u0430\u043b\u0430 \u0441 \u0443\u0436\u0435 \u043f\u0440\u043e\u043f\u0438\u0441\u0430\u043d\u043d\u044b\u043c\u0438 \u0432\u0441\u0435\u043c\u0438 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b\u043c\u0438 \u043f\u0443\u0442\u044f\u043c\u0438 \u0434\u043b\u044f \u043f\u043e\u0438\u0441\u043a\u0430 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0435\u0439. <\/p>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u0432 \u0437\u0430\u043f\u0443\u0449\u0435\u043d\u043d\u043e\u043c \u0442\u0435\u0440\u043c\u0438\u043d\u0430\u043b\u0435 \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0438\u043c \u0432 \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u044e \u0441 \u043f\u0440\u043e\u0435\u043a\u0442\u043e\u043c. \u0414\u0430\u043b\u0435\u0435 \u043a\u0430\u0436\u0434\u044b\u0439 \u0438\u0437 \u0444\u0430\u0439\u043b\u043e\u0432 <code>delaunay.cpp<\/code> \u0438 <code>bvh.cpp<\/code> \u043a\u043e\u043c\u043f\u0438\u043b\u0438\u0440\u0443\u0435\u043c \u0432 \u043f\u0440\u043e\u043c\u0435\u0436\u0443\u0442\u043e\u0447\u043d\u044b\u0439 \u0444\u043e\u0440\u043c\u0430\u0442 <code>*.o<\/code>. \u0427\u0442\u043e\u0431\u044b \u043d\u0435 \u0437\u0430\u0433\u0440\u043e\u043c\u043e\u0436\u0434\u0430\u0442\u044c \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u044e \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u043b\u0443\u0447\u0448\u0435 \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u0443\u044e \u043f\u0430\u043f\u043a\u0443 <code>\\output\\libs\\<\/code> \u0438 \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0442\u044c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u0442\u0443\u0434\u0430. \u0414\u0435\u043b\u0430\u0435\u0442\u0441\u044f \u044d\u0442\u043e \u043a\u043e\u043c\u0430\u043d\u0434\u0430\u043c\u0438<\/p>\n<pre><code>emcc .\\delaunay.cpp -o output\\libs\\delaunay.o -c emcc .\\bvh.cpp -o output\\libs\\bvh.o -c<\/code><\/pre>\n<p>\u0421\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0441 \u043f\u0440\u043e\u0441\u0442\u043e\u0439: \u043f\u043e\u0441\u043b\u0435 <code>emcc<\/code> \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0447\u0442\u043e \u043a\u043e\u043c\u043f\u0438\u043b\u0438\u0440\u043e\u0432\u0430\u0442\u044c, \u043f\u043e\u0441\u043b\u0435 \u043a\u043b\u044e\u0447\u0430 <code>-o<\/code> \u043a\u0443\u0434\u0430, \u0430 \u043a\u043b\u044e\u0447 <code>-c<\/code> \u0433\u043e\u0432\u043e\u0440\u0438\u0442, \u0447\u0442\u043e \u043d\u0430\u0434\u043e \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u043e\u0431\u044a\u0435\u043a\u0442\u043d\u044b\u0439 \u0444\u0430\u0439\u043b. \u0422\u0435\u043f\u0435\u0440\u044c, \u043d\u0430\u043a\u043e\u043d\u0435\u0446, \u043c\u044b \u0433\u043e\u0442\u043e\u0432\u044b \u0441\u043a\u043e\u043c\u043f\u0438\u043b\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043d\u0430\u0448 \u043c\u043e\u0434\u0443\u043b\u044c. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u043c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0443\u044e \u043a\u043e\u043c\u0430\u043d\u0434\u0443 <\/p>\n<pre><code>emcc .\\delaunay_api.cpp output\\libs\\delaunay.o output\\libs\\bvh.o -o output\\delaunay.js -lembind -s MODULARIZE -s ALLOW_MEMORY_GROWTH=1 -s EXPORT_NAME=delaunay -Oz<\/code><\/pre>\n<p>\u0421\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 \u043a\u043e\u043c\u0430\u043d\u0434\u044b \u0442\u0430\u043a\u0430\u044f:<\/p>\n<ul>\n<li>\n<p>\u041f\u043e\u0441\u043b\u0435 emcc \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u0439 \u0444\u0430\u0439\u043b \u0434\u043b\u044f \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0446\u0438\u0438<\/p>\n<\/li>\n<li>\n<p>\u0414\u0430\u043b\u0435\u0435 \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u044e\u0442\u0441\u044f \u0432\u0441\u0435 \u0440\u0430\u043d\u0435\u0435 \u0441\u043e\u0437\u0434\u0430\u043d\u043d\u044b\u0435 \u043e\u0431\u044a\u0435\u043a\u0442\u043d\u044b\u0435 \u0444\u0430\u0439\u043b\u044b <code>delaunay.o<\/code> \u0438 <code>bvh.o<\/code>. \u0418\u0437 \u043d\u0438\u0445 Emscripten \u0431\u0443\u0434\u0435\u0442 \u0431\u0440\u0430\u0442\u044c \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b\u0445 \u0444\u0443\u043d\u043a\u0446\u0438\u0439<\/p>\n<\/li>\n<li>\n<p>\u041f\u043e\u0441\u043b\u0435 \u043a\u043b\u044e\u0447\u0430 <code>-o<\/code> \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u043a\u0443\u0434\u0430 \u0441\u043e\u0445\u0440\u0430\u043d\u0438\u0442\u044c \u0438\u0442\u043e\u0433\u043e\u0432\u044b\u0439 \u043c\u043e\u0434\u0443\u043b\u044c \u0438 \u0441 \u043a\u0430\u043a\u0438\u043c \u0438\u043c\u0435\u043d\u0435\u043c. \u0423\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0438\u043c\u044f \u0444\u0430\u0439\u043b\u0430 \u0441 \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u0435\u043c <code>*.js<\/code>, \u0440\u044f\u0434\u043e\u043c \u0431\u0443\u0434\u0435\u0442 \u0441\u043e\u0437\u0434\u0430\u043d \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u043c\u043e\u0434\u0443\u043b\u044c \u0441 \u0442\u0430\u043a\u0438\u043c \u0436\u0435 \u0438\u043c\u0435\u043d\u0435\u043c, \u043d\u043e \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u0435\u043c <code>*.wasm<\/code><\/p>\n<\/li>\n<li>\n<p>\u041a\u043b\u044e\u0447 <code>-lembind<\/code> \u0433\u043e\u0432\u043e\u0440\u0438\u0442, \u0447\u0442\u043e \u043d\u0430\u0434\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c <code>embind<\/code><\/p>\n<\/li>\n<li>\n<p>\u0414\u0430\u043b\u0435\u0435 \u0438\u0434\u0451\u0442 \u043d\u0430\u0431\u043e\u0440 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043e\u0432, \u043a\u0430\u0436\u0434\u044b\u0439 \u0438\u0437 \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u043d\u0430\u0447\u0438\u043d\u0430\u0435\u0442\u0441\u044f \u0441 \u043a\u043b\u044e\u0447\u0430 <code>-s<\/code><\/p>\n<ul>\n<li>\n<p><code>MODULARIZE<\/code> \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043f\u043e\u0442\u043e\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043c\u043e\u0434\u0443\u043b\u044c \u0432 NodeJS, \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0430\u044f \u0435\u0433\u043e \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e <code>require<\/code><\/p>\n<\/li>\n<li>\n<p><code>ALLOW_MEMORY_GROWTH=1<\/code> \u0433\u043e\u0432\u043e\u0440\u0438\u0442, \u0447\u0442\u043e \u0432 \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u0435 \u0440\u0430\u0431\u043e\u0442\u044b \u043c\u043e\u0434\u0443\u043b\u044e \u0440\u0430\u0437\u0440\u0435\u0448\u0430\u0435\u0442\u0441\u044f \u0443\u0432\u0435\u043b\u0438\u0447\u0438\u0432\u0430\u0442\u044c \u043e\u0431\u044a\u0451\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u043e\u0439 \u043f\u0430\u043c\u044f\u0442\u0438. \u0422\u0430\u043a\u043e\u0435 \u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f, \u043a\u043e\u0433\u0434\u0430 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u044e\u0442\u0441\u044f \u043e\u0431\u044a\u0451\u043c\u043d\u044b\u0435 \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u044f. \u0411\u0435\u0437 \u044d\u0442\u043e\u0433\u043e \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430 \u0432\u043e \u0432\u0440\u0435\u043c\u044f \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u0439 \u043c\u043e\u0436\u0435\u0442 \u0432\u043e\u0437\u043d\u0438\u043a\u043d\u0443\u0442\u044c \u043e\u0448\u0438\u0431\u043a\u0430 \u043f\u0435\u0440\u0435\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u043f\u0430\u043c\u044f\u0442\u0438<\/p>\n<\/li>\n<li>\n<p><code>EXPORT_NAME<\/code> \u0437\u0430\u0434\u0430\u0451\u0442 \u0438\u043c\u044f \u044d\u043a\u0441\u043f\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0433\u043e \u043c\u043e\u0434\u0443\u043b\u044f<\/p>\n<\/li>\n<\/ul>\n<\/li>\n<li>\n<p>\u043a\u043b\u044e\u0447 <code>-Oz<\/code> \u0437\u0430\u0434\u0430\u0451\u0442 \u043c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u0443\u044e \u0441\u0442\u0435\u043f\u0435\u043d\u044c \u043e\u043f\u0442\u0438\u043c\u0438\u0437\u0430\u0446\u0438\u0438<\/p>\n<\/li>\n<\/ul>\n<p>\u0412\u043e\u0442 \u0438 \u0432\u0441\u0451. \u041d\u0435\u043f\u043e\u0441\u0440\u0435\u0434\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u0444\u0430\u0439\u043b \u0441 \u043c\u043e\u0434\u0443\u043b\u0435\u043c <code>delaunay.wasm<\/code> \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u0441\u044f 43 \u043a\u0438\u043b\u043e\u0431\u0430\u0439\u0442\u0430, \u0430 \u0444\u0430\u0439\u043b \u0441 \u043e\u0431\u0432\u0435\u0441\u043e\u043c <code>delaunay.js<\/code> \u0432\u0441\u0435\u0433\u043e \u043d\u0438\u0447\u0435\u0433\u043e &#8212; \u0430\u0436 57 \u043a\u0438\u043b\u043e\u0431\u0430\u0439\u0442. \u0418 \u044d\u0442\u043e \u0443\u0436\u0435 \u043c\u0438\u043d\u0438\u0444\u0438\u0446\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0439. \u041d\u0443 \u0443\u0436 \u0447\u0442\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u043e\u0441\u044c.<\/p>\n<p>\u0412\u043e\u0442 \u043f\u0440\u0438\u043c\u0435\u0440 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f:<\/p>\n<pre><code class=\"javascript\">var factory = require('..\/cpp\/output\/delaunay.js');  factory().then((instance) => { const coordinates = [ -0.5, 3.0, 8.0, -3.5, -7.0, 3.0, 2.0, -10.0, 7.0, 8.0, 8.0, 5.5]; const triangle_indices = instance.build_triangulation(coordinates); console.log(triangle_indices);  let bvh = new instance.BVHNode(coordinates); let s = bvh.sample(0.0, 0.0); console.log(s); });<\/code><\/pre>\n<p>\u0412 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u043e\u0442\u0432\u0435\u0442\u0430 \u0432\u044b\u0434\u0430\u0451\u0442 \u0432 \u0442\u043e\u0447\u043d\u043e\u0441\u0442\u0438 \u0442\u043e \u0436\u0435 \u0441\u0430\u043c\u043e\u0435, \u0447\u0442\u043e \u0438 \u0447\u0438\u0441\u0442\u0430\u044f \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0430 \u043d\u0430 c++. \u0420\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e.<\/p>\n<h3>AssemblyScript<\/h3>\n<p>\u0415\u0441\u043b\u0438 \u043a\u0442\u043e \u043d\u0435 \u0441\u043b\u044b\u0445\u0430\u043b, \u0442\u043e <a href=\"https:\/\/www.assemblyscript.org\/\" rel=\"noopener noreferrer nofollow\">AssemblyScript <\/a>&#8212; \u044d\u0442\u043e \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u044b\u0439 \u044f\u0437\u044b\u043a \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043a\u043e\u043c\u043f\u0438\u043b\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u0442\u043e\u043b\u044c\u043a\u043e \u0432 WebAssembly, \u0438 \u043d\u0438 \u0434\u043b\u044f \u0447\u0435\u0433\u043e \u0434\u0440\u0443\u0433\u043e\u0433\u043e \u043d\u0435 \u043f\u0440\u0435\u0434\u043d\u0430\u0437\u043d\u0430\u0447\u0435\u043d. \u041f\u043e \u0441\u0432\u043e\u0435\u043c\u0443 \u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0441\u0443 \u043e\u043d \u043e\u0447\u0435\u043d\u044c \u043f\u043e\u0445\u043e\u0436 \u043d\u0430 TypeScript.<\/p>\n<p>\u0423\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c AssemblyScript \u043c\u043e\u0436\u043d\u043e \u0447\u0435\u0440\u0435\u0437 npm. \u0423\u0434\u043e\u0431\u043d\u043e \u044d\u0442\u043e \u0431\u0443\u0434\u0435\u0442 \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0433\u043b\u043e\u0431\u0430\u043b\u044c\u043d\u043e. \u0412\u0441\u0451-\u0442\u0430\u043a\u0438 \u044d\u0442\u043e \u043d\u0435 \u0442\u0430 \u0432\u0435\u0449\u044c, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043c\u0435\u043d\u044f\u0435\u0442\u0441\u044f \u043e\u0442 \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u043a \u043f\u0440\u043e\u0435\u043a\u0442\u0443.<\/p>\n<p>\u041f\u043e \u0431\u043e\u043b\u044c\u0448\u043e\u043c\u0443 \u0441\u0447\u0451\u0442\u0443 \u044d\u0442\u043e\u0433\u043e \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e, \u0447\u0442\u043e \u043a\u043e\u043c\u043f\u0438\u043b\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043c\u043e\u0434\u0443\u043b\u0438 WebAssembly. \u0412\u0441\u0451, \u0447\u0442\u043e \u0442\u0435\u043f\u0435\u0440\u044c \u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f &#8212; \u044d\u0442\u043e \u0432\u044b\u0437\u0432\u0430\u0442\u044c \u043a\u043e\u043c\u0430\u043d\u0434\u0443<\/p>\n<pre><code>asc index.ts<\/code><\/pre>\n<p>\u0417\u0434\u0435\u0441\u044c <code>index.ts<\/code> \u044d\u0442\u043e \u0444\u0430\u0439\u043b \u0441 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u043e\u0439. \u0421\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u043e\u0435 \u043e\u0442\u043a\u043e\u043c\u043f\u0438\u043b\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0433\u043e \u043c\u043e\u0434\u0443\u043b\u044f \u0432 \u0442\u0435\u043a\u0441\u0442\u043e\u0432\u043e\u043c \u0444\u043e\u0440\u043c\u0430\u0442\u0435 \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u0432\u0435\u0434\u0435\u043d \u0432 \u043a\u043e\u043d\u0441\u043e\u043b\u044c.<\/p>\n<p>\u0422\u043e, \u0447\u0442\u043e AssemblyScript \u043f\u0440\u0435\u0434\u043d\u0430\u0437\u043d\u0430\u0447\u0435\u043d \u0438\u0441\u043a\u043b\u044e\u0447\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0434\u043b\u044f WebAssembly \u043d\u0430\u043a\u043b\u0430\u0434\u044b\u0432\u0430\u0435\u0442 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043d\u0435\u0443\u0434\u043e\u0431\u0441\u0442\u0432\u0430. \u041e\u043d\u0438 \u0441\u0432\u044f\u0437\u0430\u043d\u044b \u0441 \u043f\u0440\u043e\u0446\u0435\u0434\u0443\u0440\u043e\u0439 \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0438\u044f \u0438 \u043e\u0442\u043b\u0430\u0434\u043a\u0438 \u0431\u043e\u043b\u0435\u0435 \u0438\u043b\u0438 \u043c\u0435\u043d\u0435\u0435 \u043a\u043e\u043c\u043f\u043b\u0435\u043a\u0441\u043d\u044b\u0445 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c. \u041d\u0443 \u0432\u043e\u0442 \u043a\u0430\u043a, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u043d\u0430\u0448\u0430. \u0422\u044f\u0436\u043a\u043e \u043a\u0430\u0436\u0434\u044b\u0439 \u0440\u0430\u0437 \u043a\u043e\u043c\u043f\u0438\u043b\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043c\u043e\u0434\u0443\u043b\u044c, \u0432\u044b\u0437\u044b\u0432\u0430\u0442\u044c \u0435\u0433\u043e \u0438\u0437 \u0437\u0430\u0440\u0430\u043d\u0435\u0435 \u0437\u0430\u0433\u043e\u0442\u043e\u0432\u043b\u0435\u043d\u043d\u043e\u0439 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u043a\u0438 \u043d\u0430 JavaScript, \u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u0447\u0442\u043e \u043e\u043d \u0432\u044b\u0434\u0430\u0451\u0442, \u0447\u0435\u0440\u0442\u044b\u0445\u0430\u0442\u044c\u0441\u044f. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u043f\u0440\u0435\u0434\u043b\u0430\u0433\u0430\u0435\u0442\u0441\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0443\u044e \u043e\u0440\u0433\u0430\u043d\u0438\u0437\u0430\u0446\u0438\u044e \u0440\u0430\u0431\u043e\u0447\u0435\u0439 \u0441\u0440\u0435\u0434\u044b.<\/p>\n<p>\u0418\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u0443\u0435\u043c \u043f\u0443\u0441\u0442\u043e\u0439 \u043f\u0440\u043e\u0435\u043a\u0442. <\/p>\n<pre><code>npm init<\/code><\/pre>\n<p>\u041f\u043e\u0441\u043b\u0435 \u044d\u0442\u043e\u0433\u043e \u0443\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u043c \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u043e <code>@assemblyscript\/wasi-shim<\/code>. \u0422\u0430\u043a \u0438 \u043f\u0438\u0448\u0435\u043c<\/p>\n<pre><code>npm install -D @assemblyscript\/wasi-shim<\/code><\/pre>\n<p>\u042d\u0442\u043e \u043f\u043e\u0437\u0432\u043e\u043b\u0438\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c WASI \u0438\u0437\u043d\u0443\u0442\u0440\u0438 \u043e\u0442\u043a\u043e\u043c\u043f\u0438\u043b\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0433\u043e \u043c\u043e\u0434\u0443\u043b\u044f. \u0412 \u0447\u0430\u0441\u0442\u043d\u043e\u0441\u0442\u0438 &#8212; \u0432\u044b\u0432\u043e\u0434\u0438\u0442\u044c \u0432 \u043a\u043e\u043d\u0441\u043e\u043b\u044c \u0432\u0441\u044f\u043a\u0438\u0435 \u0442\u0435\u043a\u0441\u0442\u043e\u0432\u044b\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f, \u043d\u0435 \u0441\u043e\u0432\u0435\u0440\u0448\u0430\u044f \u043d\u0438\u043a\u0430\u043a\u0438\u0445 \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0445 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0439. \u041a\u0430\u043a \u0440\u0430\u0437 \u0442\u043e \u0441\u0430\u043c\u043e\u0435 &#171;\u043e\u043d\u043e \u0442\u0430\u043c \u0441\u0430\u043c\u043e&#187;.<\/p>\n<p>\u0424\u0430\u0439\u043b\u044b \u0441 \u043a\u043e\u0434\u043e\u043c \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b \u043d\u0430 AssemblyScript \u043f\u0440\u0438\u043d\u044f\u0442\u043e \u0441\u043a\u043b\u0430\u0434\u044b\u0432\u0430\u0442\u044c \u0432 \u043f\u0430\u043f\u043a\u0443<code>.\/assembly\/<\/code>, \u0430 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u044b \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0446\u0438\u0438 \u0432 \u043f\u0430\u043f\u043a\u0443 <code>.\/build\/<\/code>. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u0441\u043e\u0437\u0434\u0430\u0451\u043c \u0432 \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u0438 <code>.\/assembly\/<\/code> \u0444\u0430\u0439\u043b <code>index.ts<\/code>. \u042d\u0442\u043e \u0431\u0443\u0434\u0435\u0442 \u0442\u043e\u0447\u043a\u0430 \u0432\u0445\u043e\u0434\u0430 \u043f\u0440\u0438 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0435. \u0421\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u043e\u0435 \u0442\u0430\u043a\u043e\u0435:<\/p>\n<pre><code class=\"typescript\">function main(): void {     console.log(\"Hello World\"); }  main();<\/code><\/pre>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c, \u0447\u0442\u043e\u0431\u044b \u0432\u043a\u043b\u044e\u0447\u0438\u0442\u044c \u0432 \u043c\u043e\u0434\u0443\u043b\u044c \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0434\u043b\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u043a\u043e\u043c\u0430\u043d\u0434\u044b <code>console.log<\/code>, \u0435\u0433\u043e \u043d\u0430\u0434\u043e \u043e\u0442\u043a\u043e\u043c\u043f\u0438\u043b\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0441 \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u043c\u0438 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430\u043c\u0438. \u0412 \u043e\u0431\u0449\u0435\u043c \u043f\u0438\u0448\u0435\u043c<\/p>\n<pre><code>asc assembly\/index.ts -o build\/index.wasm --target debug --config .\/node_modules\/@assemblyscript\/wasi-shim\/asconfig.json<\/code><\/pre>\n<p>\u041d\u0430\u043a\u043e\u043d\u0435\u0446 \u043c\u043e\u0436\u043d\u043e \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u043d\u0430\u0448 \u043c\u043e\u0434\u0443\u043b\u044c <code>index.wasm<\/code> \u0432 \u043a\u0430\u043a\u043e\u0439-\u043d\u0438\u0431\u0443\u0434\u044c \u0441\u0440\u0435\u0434\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 \u0432 WasmTime. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u043d\u0438\u043a\u0430\u043a\u043e\u0439 \u043e\u0431\u0432\u0435\u0441 \u043d\u0430 JavaScript \u043d\u0435 \u043d\u0443\u0436\u0435\u043d.<\/p>\n<pre><code>wasmtime .\/build\/index.wasm<\/code><\/pre>\n<p>\u041a\u0430\u0436\u0434\u044b\u0439 \u0440\u0430\u0437 \u043f\u0438\u0441\u0430\u0442\u044c \u043a\u043e\u043c\u0430\u043d\u0434\u0443 \u0434\u043b\u044f \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0446\u0438\u0438, \u0430 \u043f\u043e\u0442\u043e\u043c \u0435\u0449\u0451 \u043e\u0434\u043d\u0443 \u0434\u043b\u044f \u0437\u0430\u043f\u0443\u0441\u043a\u0430 \u0432 WasmTime \u0445\u043b\u043e\u043f\u043e\u0442\u043d\u043e. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u043b\u0443\u0447\u0448\u0435 \u0432 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u043e\u043d\u043d\u043e\u043c \u0444\u0430\u0439\u043b\u0435 \u043f\u0440\u043e\u0435\u043a\u0442\u0430 <code>package.json<\/code> \u0437\u0430\u0440\u0430\u043d\u0435\u0435 \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0437\u0430\u0433\u043e\u0442\u043e\u0432\u043a\u0438<\/p>\n<pre><code class=\"json\">\"scripts\": {     \"develop\": \"asc assembly\/index.ts -o build\/index.wasm --target debug --config .\/node_modules\/@assemblyscript\/wasi-shim\/asconfig.json\",     \"execute\": \"npm run develop &amp;&amp; wasmtime .\/build\/index.wasm\" },<\/code><\/pre>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0446\u0438\u044f \u0438 \u0437\u0430\u043f\u0443\u0441\u043a \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u043d\u0430\u0436\u0430\u0442\u0438\u0435\u043c \u043e\u0434\u043d\u043e\u0439 \u043a\u043d\u043e\u043f\u043a\u0438 <code>npm run execute<\/code>. \u041c\u043e\u0436\u043d\u043e \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0440\u043e\u0432\u0430\u0442\u044c.<\/p>\n<h4>\u041f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0430 \u043d\u0430 AssemblyScript<\/h4>\n<p>\u041e\u0431\u0449\u0430\u044f \u043b\u043e\u0433\u0438\u043a\u0430 \u0440\u043e\u0432\u043d\u043e \u0442\u0430 \u0436\u0435 \u0441\u0430\u043c\u0430\u044f, \u0447\u0442\u043e \u0431\u044b\u043b\u0430 \u0434\u043b\u044f \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b \u043d\u0430 c++. \u0421\u043e\u0437\u0434\u0430\u0451\u043c \u0432 \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u0438 <code>.\/assembly\/<\/code> \u0442\u0440\u0438 \u0444\u0430\u0439\u043b\u0430 <code>point.ts<\/code> <code>delaunay.ts<\/code> \u0438 <code>bvh.ts<\/code><\/p>\n<p>\u0424\u0430\u0439\u043b <code>point.ts<\/code> \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u043a\u043b\u0430\u0441\u0441\u0430 <code>Point<\/code> \u0434\u043b\u044f \u0437\u0430\u0434\u0430\u043d\u0438\u044f \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442 \u0442\u043e\u0447\u0435\u043a \u043d\u0430 \u043f\u043b\u043e\u0441\u043a\u043e\u0441\u0442\u0438.<\/p>\n<details class=\"spoiler\">\n<summary>points.ts<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"typescript\">export class Point {     private m_x: f32;     private m_y: f32;      constructor(in_x: f32 = 0.0, in_y: f32 = 0.0) {         this.m_x = in_x;         this.m_y = in_y;     }      @inline     x(): f32 {         return this.m_x;     }      @inline     y(): f32 {         return this.m_y;     }      toString(): string {         return \"(\" + this.m_x.toString() + \", \" + this.m_y.toString() + \")\";     } }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u0424\u0430\u0439\u043b <code>delaunay.ts<\/code> \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u0432\u0441\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0434\u043b\u044f \u043f\u043e\u0441\u0442\u0440\u043e\u0435\u043d\u0438\u044f \u0442\u0440\u0438\u0430\u043d\u0433\u0443\u043b\u044f\u0446\u0438\u0438. \u0421\u0430\u043c\u0430\u044f \u0433\u043b\u0430\u0432\u043d\u0430\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u044d\u0442\u043e <code>triangulate<\/code>, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442 \u043d\u0430 \u0432\u0445\u043e\u0434 <code>StaticArray&lt;Point><\/code>, \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0449\u0438\u0439 \u0442\u043e\u0447\u043a\u0438 \u043d\u0430 \u043f\u043b\u043e\u0441\u043a\u043e\u0441\u0442\u0438, \u0430 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 <code>StaticArray&lt;i32><\/code>, \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0449\u0438\u0439 \u043d\u043e\u043c\u0435\u0440\u0430 \u0432\u0435\u0440\u0448\u0438\u043d \u0442\u0440\u0435\u0443\u0433\u043e\u043b\u044c\u043d\u0438\u043a\u043e\u0432 \u0442\u0440\u0438\u0430\u043d\u0433\u0443\u043b\u044f\u0446\u0438\u0438.<\/p>\n<details class=\"spoiler\">\n<summary>delaunay.ts<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"typescript\">import { Point } from \".\/point\";  const EPSILON: f32 = 0.0001;  class PointExt extends Point {     private m_index: i32;      constructor(in_x: f32, in_y: f32, in_index: i32) {         super(in_x, in_y);          this.m_index = in_index;     }      index(): i32 {         return this.m_index;     } }  class TriangleCircle {     private m_i: i32;     private m_j: i32;     private m_k: i32;      private m_x: f32;     private m_y: f32;      private m_radius_sq: f32;      constructor(in_i: i32, in_j: i32, in_k: i32, in_x: f32, in_y: f32, in_r: f32) {         this.m_i = in_i;         this.m_j = in_j;         this.m_k = in_k;          this.m_x = in_x;         this.m_y = in_y;          this.m_radius_sq = in_r;     }      i(): i32 { return this.m_i; }     j(): i32 { return this.m_j; }     k(): i32 { return this.m_k; }      x(): f32 { return this.m_x; }     y(): f32 { return this.m_y; }      radius_sq(): f32 { return this.m_radius_sq; }      toString(): string {         return \"&lt;\" + this.m_i.toString() + \", \" + this.m_j.toString() + \", \" + this.m_k.toString() + \"|\" + this.m_x.toString() + \", \" + this.m_y.toString() + \"|\" + this.m_radius_sq.toString() + \">\";     } }  function maximum(a: f32, b: f32): f32 {     if(a > b) {         return a;     } else {         return b;     } }  function absolute(a: f32, b: f32): f32 {     if(a > b) {         return a - b;     } else {         return b - a;     } }  function build_supertriangle(points: StaticArray&lt;Point>): StaticArray&lt;Point> {     let x_min: f32 = f32.MAX_VALUE;     let y_min: f32 = f32.MAX_VALUE;     let x_max: f32 = f32.MIN_VALUE;     let y_max: f32 = f32.MIN_VALUE;      for(let i = 0, len = points.length; i &lt; len; i++) {         const p = points[i];         if (p.x() &lt; x_min) { x_min = p.x(); }         if (p.x() > x_max) { x_max = p.x(); }         if (p.y() &lt; y_min) { y_min = p.y(); }         if (p.y() > y_max) { y_max = p.y(); }     }      const dx: f32 = x_max - x_min;     const dy: f32 = y_max - y_min;      const d_max: f32 = maximum(dx, dy);     const x_mid: f32 = x_min + dx * 0.5;     const y_mid: f32 = y_min + dy * 0.5;      const vertices = new StaticArray&lt;Point>(3);     vertices[0] = new Point(x_mid - 20.0 * d_max, y_mid - d_max);     vertices[1] = new Point(x_mid, y_mid + 20.0 * d_max);     vertices[2] = new Point(x_mid + 20.0 * d_max, y_mid - d_max);     return vertices; }  function circumcircle(points: StaticArray&lt;Point>, i: i32, j: i32, k: i32): TriangleCircle {     const point_i = points[i];     const point_j = points[j];     const point_k = points[k];      const x_1 = point_i.x();     const y_1 = point_i.y();      const x_2 = point_j.x();     const y_2 = point_j.y();      const x_3 = point_k.x();     const y_3 = point_k.y();      const y1_y2 = absolute(y_1, y_2);     const y2_y3 = absolute(y_2, y_3);      let center_x: f32 = 0.0;     let center_y: f32 = 0.0;     let m_1: f32 = 0.0;     let m_2: f32 = 0.0;     let mx_1: f32 = 0.0;     let mx_2: f32 = 0.0;     let my_1: f32 = 0.0;     let my_2: f32 = 0.0;      if (y1_y2 &lt; EPSILON) {         m_2 = -(x_3 - x_2) \/ (y_3 - y_2);         mx_2 = (x_2 + x_3) \/ 2.0;         my_2 = (y_2 + y_3) \/ 2.0;         center_x = (x_2 + x_1) \/ 2.0;         center_y = m_2 * (center_x - mx_2) + my_2;     } else if (y2_y3 &lt; EPSILON)     {         m_1 = -(x_2 - x_1) \/ (y_2 - y_1);         mx_1 = (x_1 + x_2) \/ 2.0;         my_1 = (y_1 + y_2) \/ 2.0;         center_x = (x_3 + x_2) \/ 2.0;         center_y = m_1 * (center_x - mx_1) + my_1;     } else     {         m_1 = -(x_2 - x_1) \/ (y_2 - y_1);         m_2 = -(x_3 - x_2) \/ (y_3 - y_2);         mx_1 = (x_1 + x_2) \/ 2.0;         mx_2 = (x_2 + x_3) \/ 2.0;         my_1 = (y_1 + y_2) \/ 2.0;         my_2 = (y_2 + y_3) \/ 2.0;         center_x = (m_1 * mx_1 - m_2 * mx_2 + my_2 - my_1) \/ (m_1 - m_2);         center_y = y1_y2 > y2_y3 ? (m_1 * (center_x - mx_1) + my_1) : (m_2 * (center_x - mx_2) + my_2);     }      const dx = x_2 - center_x;     const dy = y_2 - center_y;      return new TriangleCircle(i, j, k, center_x, center_y, dx*dx + dy*dy); }  \/\/ retun new size of the edges array function remove_duplicates(edges: StaticArray&lt;i32>, in_length: i32): i32 {     let j = in_length;     while(j >= 2) {         const b = edges[--j];         const a = edges[--j];          let i = j;         while(i >= 2) {             const n = edges[--i];             const m = edges[--i];              if((a == m &amp;&amp; b == n) || (a == n &amp;&amp; b == m)) {                 edges[j] = -1;                 edges[j + 1] = -1;                  edges[i] = -1;                 edges[i + 1] = -1;                  j -= 2;                 break;             }         }     }      \/\/ next remove all -1 values in the array     let i = -1;  \/\/ actual new index     j = 0;  \/\/ pointer to the value in the array     while(j &lt; in_length) {         if(edges[j] == -1) {             j += 1;         } else {             edges[++i] = edges[j++];         }     }      return i + 1; }  function remove_from_array&lt;T>(array: StaticArray&lt;T>, in_length: i32, remove_index: i32): i32 {     for(let i = remove_index + 1; i &lt; in_length; i++) {         array[i - 1] = array[i];     }      return in_length - 1; }  export function triangulate(in_points: StaticArray&lt;Point>): StaticArray&lt;i32> {     const points_count: i32 = in_points.length;     if(points_count &lt; 3) {         return new StaticArray&lt;i32>(0);     }      \/\/ AS does not support closures, so, create array with extended points     let ext_points = new StaticArray&lt;PointExt>(points_count);     for(let i = 0; i &lt; points_count; i++) {         const p = in_points[i];         ext_points[i] = new PointExt(p.x(), p.y(), i);  \/\/ assign in dex to each point     }      \/\/ sort by using custom comparator     ext_points.sort((a: PointExt, b: PointExt): i32 => {         if(a.x() &lt; b.x()) {             return -1;         } else if(a.x() > b.x())         {             return 1;         } else {             return 0;         }     });      \/\/ extract indices from sorted array     let indices = new StaticArray&lt;i32>(points_count);     for(let i = 0; i &lt; points_count; i++) {         indices[i] = ext_points[i].index();     }      const st = build_supertriangle(in_points);      \/\/ create copy of the input points array and extend it by points from the super triangle     const points = new StaticArray&lt;Point>(points_count + 3);     for(let i = 0; i &lt; points_count; i++) {         points[i] = in_points[i];     }     points[points_count] = st[0];     points[points_count + 1] = st[1];     points[points_count + 2] = st[2];      \/\/ create buffers     const buffers_max_size = 6 * (points_count + 3);     let open_list = new StaticArray&lt;TriangleCircle>(buffers_max_size);     let open_list_length = 0;  \/\/ manually count the used length      let closed_list = new StaticArray&lt;TriangleCircle>(buffers_max_size);     let closed_list_length = 0;      let edges_list = new StaticArray&lt;i32>(6 * buffers_max_size);  \/\/ here we place 6 put for each triangle     let edges_list_length = 0;      open_list[open_list_length++] = circumcircle(points, points_count, points_count + 1, points_count + 2);      for(let i = 0; i &lt; points_count; i++) {         const c: i32 = indices[i];         const p: Point = points[c];          edges_list_length = 0;         for(let j = open_list_length - 1; j >= 0; j--) {             const t: TriangleCircle = open_list[j];             const dx: f32 = p.x() - t.x();              if(dx > EPSILON &amp;&amp; dx*dx > t.radius_sq()) {                 open_list_length = remove_from_array(open_list, open_list_length, j);                 closed_list[closed_list_length++] = t;                 continue;             }              const dy: f32 = p.y() - t.y();             if(dx*dx + dy*dy - t.radius_sq() > EPSILON) {                 continue;             }              open_list_length = remove_from_array(open_list, open_list_length, j);             edges_list[edges_list_length++] = t.i();             edges_list[edges_list_length++] = t.j();             edges_list[edges_list_length++] = t.j();             edges_list[edges_list_length++] = t.k();             edges_list[edges_list_length++] = t.k();             edges_list[edges_list_length++] = t.i();         }                  edges_list_length = remove_duplicates(edges_list, edges_list_length);          let k: i32 = edges_list_length;         while(k >= 2) {             const b = edges_list[--k];             const a = edges_list[--k];              open_list[open_list_length++] = circumcircle(points, a, b, c);         }     }      for(let i = 0; i &lt; open_list_length; i++) {         closed_list[closed_list_length++] = open_list[i];     }      const triangles = new StaticArray&lt;i32>(closed_list_length * 3);     let t_index: i32 = 0;     for(let i = 0; i &lt; closed_list_length; i++) {         const t = closed_list[i];         if(t.i() &lt; points_count &amp;&amp; t.j() &lt; points_count &amp;&amp; t.k() &lt; points_count) {             triangles[3*t_index] = t.i();             triangles[3*t_index + 1] = t.j();             triangles[3*t_index + 2] = t.k();              t_index += 1;         }     }     return triangles.slice&lt;StaticArray&lt;i32>>(0, 3*t_index); }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u0412 \u0444\u0430\u0439\u043b <code>bvh.ts<\/code> \u043e\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u043c \u043a\u043b\u0430\u0441\u0441 <code>BVHNode<\/code>. \u0412 \u043e\u0431\u0449\u0435\u043c \u0432\u0441\u0451 \u043a\u0430\u043a \u0438 \u0440\u0430\u043d\u044c\u0448\u0435.<\/p>\n<details class=\"spoiler\">\n<summary>bvh.ts<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"typescript\">import { Point } from \".\/point\";  @inline function maximum(a: f32, b: f32): f32 {     if(a > b) { return a;     } else { return b; } }  @inline function minimum(a: f32, b: f32): f32 {     if(a > b) { return b;     } else { return a; } }  @inline function square(value: f32): f32 {     return value * value; }  class AABB {     private m_x_min: f32;     private m_y_min: f32;      private m_x_max: f32;     private m_y_max: f32;      constructor(in_x_min: f32 = 0.0, in_y_min: f32 = 0.0, in_x_max: f32 = 0.0, in_y_max: f32 = 0.0) {         this.m_x_min = in_x_min;         this.m_y_min = in_y_min;          this.m_x_max = in_x_max;         this.m_y_max = in_y_max;     }      @inline     x_min(): f32 { return this.m_x_min; }      @inline     y_min(): f32 { return this.m_y_min; }      @inline     x_max(): f32 { return this.m_x_max; }      @inline     y_max(): f32 { return this.m_y_max; }      toString(): string {         return \"|\" + this.m_x_min.toString() + \", \" + this.m_y_min.toString() + \", \" + this.m_x_max.toString() + \", \" + this.m_y_max.toString() + \"|\";     } }  export class Triangle {     private m_a: Point;     private m_b: Point;     private m_c: Point;      private m_aabb: AABB;     private m_center: Point;      constructor(vertices: Array&lt;Point>) {         this.m_a = vertices[0];         this.m_b = vertices[1];         this.m_c = vertices[2];          let x_min = f32.MAX_VALUE;         let y_min = f32.MAX_VALUE;         let x_max = f32.MIN_VALUE;         let y_max = f32.MIN_VALUE;          let x_accum: f32 = 0.0;         let y_accum: f32 = 0.0;          for (let i = 0, len = vertices.length; i &lt; len; i++)         {             const v = vertices[i];             if (v.x() &lt; x_min) { x_min = v.x(); }             if (v.x() > x_max) { x_max = v.x(); }             if (v.y() &lt; y_min) { y_min = v.y(); }             if (v.y() > y_max) { y_max = v.y(); }              x_accum += v.x();             y_accum += v.y();         }          this.m_aabb = new AABB(x_min, y_min, x_max, y_max);         this.m_center = new Point(x_accum \/ &lt;f32>vertices.length, y_accum \/ &lt;f32>vertices.length);     }      @inline     a(): Point { return this.m_a; }      @inline     b(): Point { return this.m_b; }      @inline     c(): Point { return this.m_c; }      @inline     aabb(): AABB {         return this.m_aabb;     }      @inline     center(): Point {         return this.m_center;     }      is_point_inside(point: Point): bool {         const as_x = point.x() - this.m_a.x();         const as_y = point.y() - this.m_a.y();          const s_ab: bool = ((this.m_b.x() - this.m_a.x()) * as_y - (this.m_b.y() - this.m_a.y()) * as_x) > 0;          if (((this.m_c.x() - this.m_a.x()) * as_y - (this.m_c.y() - this.m_a.y()) * as_x > 0) == s_ab)         {             return false;         }         if (((this.m_c.x() - this.m_b.x()) * (point.y() - this.m_b.y()) - (this.m_c.y() - this.m_b.y()) * (point.x() - this.m_b.x()) > 0) != s_ab)         {             return false;         }         return true;     }      toString(): string {         return \"&lt;\" + this.m_a.toString() + \", \" + this.m_b.toString() + \", \" + this.m_c.toString() + \">\";     } }  function union_aabb(x: AABB, y: AABB): AABB {     return new AABB(minimum(x.x_min(), y.x_min()),      minimum(x.y_min(), y.y_min()),      maximum(x.x_max(), y.x_max()),      maximum(x.y_max(), y.y_max())); }  export class BVHNode {     private m_triangle: Triangle | null = null;     private m_left_node: BVHNode | null = null;     private m_right_node: BVHNode | null = null;     private m_aabb: AABB = new AABB();      constructor(triangles: StaticArray&lt;Triangle>) {         const objects_count = triangles.length;          if(objects_count == 1) {             this.m_triangle = triangles[0];             this.m_aabb = triangles[0].aabb();         } else {             let x_median: f32 = 0.0;             let y_median: f32 = 0.0;              let x_min = f32.MAX_VALUE;             let x_max = f32.MIN_VALUE;             let y_min = f32.MAX_VALUE;             let y_max = f32.MIN_VALUE;              for (let i = 0; i &lt; objects_count; i++) {                 const t = triangles[i];                 const c = t.center();                 x_median += c.x();                 y_median += c.y();                  if (c.x() &lt; x_min) { x_min = c.x(); }                 if (c.x() > x_max) { x_max = c.x(); }                 if (c.y() &lt; y_min) { y_min = c.y(); }                 if (c.y() > y_max) { y_max = c.y(); }             }              const split_axis: i32 = ((x_max - x_min) > (y_max - y_min)) ? 0 : 1;             const median: f32 = split_axis == 0 ? (x_median \/ &lt;f32>objects_count) : (y_median \/ &lt;f32>objects_count);              const left = new StaticArray&lt;Triangle>(objects_count);             let left_length: i32 = 0;             const right = new StaticArray&lt;Triangle>(objects_count);             let right_length: i32 = 0;              for (let i = 0; i &lt; objects_count; i++) {                 const t = triangles[i];                 const c = t.center();                 const v: f32 = split_axis == 0 ? c.x() : c.y();                 if (v &lt; median) {                     left[left_length++] = t;                 } else {                     right[right_length++] = t;                 }             }              if (left_length == 0)             {                 left[left_length++] = right[right_length - 1];                 right_length -= 1;             }              if (right_length == 0)             {                 right[right_length++] = left[left_length - 1];                 left_length -= 1;             }              let left_node = new BVHNode(left.slice&lt;StaticArray&lt;Triangle>>(0, left_length));             let right_node = new BVHNode(right.slice&lt;StaticArray&lt;Triangle>>(0, right_length));              const left_aabb = left_node.aabb();             const right_aabb = right_node.aabb();              this.m_aabb = union_aabb(left_aabb, right_aabb);             this.m_left_node = left_node;             this.m_right_node = right_node;         }     }      @inline     aabb(): AABB {         return this.m_aabb;     }      @inline     is_inside_aabb(point: Point): bool {         return this.m_aabb.x_min() &lt; point.x() &amp;&amp; this.m_aabb.y_min() &lt; point.y() &amp;&amp; this.m_aabb.x_max() > point.x() &amp;&amp; this.m_aabb.y_max() > point.y();     }      sample(point: Point): Triangle | null {         if(this.is_inside_aabb(point)) {             let triangle = this.m_triangle;             let left_node = this.m_left_node;             let right_node = this.m_right_node;              if(!triangle &amp;&amp; left_node &amp;&amp; right_node) {                 let left_sample = left_node.sample(point);                 let right_sample = right_node.sample(point);                  if(!left_sample) {                     return right_sample;                 } else {                     if(!right_sample) {                         return left_sample;                     } else {                         const l_c = left_sample.center();                         const l_dist = square(l_c.x() - point.x()) + square(l_c.y() - point.y());                          const r_c = right_sample.center();                         const r_dist = square(r_c.x() - point.x()) + square(r_c.y() - point.y());                          if (l_dist &lt; r_dist) {                             return left_sample;                         } else {                             return right_sample;                         }                     }                 }             } else {                 if(triangle &amp;&amp; triangle.is_point_inside(point)) {                     return triangle;                 } else {                     return null;                 }             }         } else {             return null;         }     } }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u041f\u0440\u043e\u0432\u0435\u0440\u0438\u043c, \u043a\u0430\u043a \u0440\u0430\u0431\u043e\u0442\u0430\u044e\u0442 \u043d\u0430\u0448\u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u0438, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0432 \u0438\u0445 \u043d\u0430 \u043f\u0440\u043e\u0432\u0435\u0440\u043e\u0447\u043d\u044b\u0445 \u0434\u0430\u043d\u043d\u044b\u0445 \u0432 \u0444\u0430\u0439\u043b\u0435 <code>index.ts<\/code><\/p>\n<details class=\"spoiler\">\n<summary>index.ts<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"typescript\">import { BVHNode, Triangle } from \".\/bvh\"; import { triangulate } from \".\/delaunay\"; import { Point } from \".\/point\";  function main(): void {     let points = new StaticArray&lt;Point>(6);     points[0] = new Point(-0.5, 3.0);     points[1] = new Point(8.0, -3.5);     points[2] = new Point(-7.0, 3.0);     points[3] = new Point(2.0, -10.0);     points[4] = new Point(7.0, 8.0);     points[5] = new Point(8.0, 5.5);      let triangle_indices = triangulate(points);     console.log(triangle_indices.toString());      const trinagles = new StaticArray&lt;Triangle>(triangle_indices.length \/ 3);     for(let i = 0; i &lt; trinagles.length; i++) {         const a: i32 = triangle_indices[3*i];         const b: i32 = triangle_indices[3*i + 1];         const c: i32 = triangle_indices[3*i + 2];         trinagles[i] = new Triangle([points[a], points[b], points[c]]);     }      const tree = new BVHNode(trinagles);     const p = new Point(0.0, 0.0);     const sample_result = tree.sample(p);     if(sample_result) {         console.log(sample_result.toString());     } else {         console.log(\"empty sample\");     } }  main();<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u0412\u044b\u043f\u043e\u043b\u043d\u0438\u043c <code>npm run execute<\/code>. \u0412 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0435 \u043f\u043e\u043b\u0443\u0447\u0438\u043c<\/p>\n<pre><code>2,0,3,0,2,4,3,0,1,1,0,5,0,4,5 &lt;(-7.0, 3.0), (-0.5, 3.0), (2.0, -10.0)><\/code><\/pre>\n<p>\u042d\u0442\u043e \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u044b\u0439 \u043e\u0442\u0432\u0435\u0442.<\/p>\n<h4>\u041a\u043e\u043c\u043f\u0438\u043b\u044f\u0446\u0438\u044f \u043c\u043e\u0434\u0443\u043b\u044f<\/h4>\n<p>\u041a \u0441\u043e\u0436\u0430\u043b\u0435\u043d\u0438\u044e \u043d\u0430 \u043d\u0430\u0441\u0442\u043e\u044f\u0449\u0438\u0439 \u043c\u043e\u043c\u0435\u043d\u0442 AssemblyScript \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442 \u044d\u043a\u0441\u043f\u043e\u0440\u0442 \u0442\u043e\u043b\u044c\u043a\u043e \u0444\u0443\u043d\u043a\u0446\u0438\u0439. \u0420\u0430\u043d\u044c\u0448\u0435 \u043c\u043e\u0436\u043d\u043e \u0431\u044b\u043b\u043e \u0438 \u043a\u043b\u0430\u0441\u0441\u044b, \u043f\u0440\u0438 \u044d\u0442\u043e\u043c \u0434\u043b\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u043e\u0442\u043a\u043e\u043c\u043f\u0438\u043b\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0433\u043e \u043c\u043e\u0434\u0443\u043b\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043b\u0441\u044f \u043e\u0434\u0438\u043d \u0443\u043d\u0438\u0432\u0435\u0440\u0441\u0430\u043b\u044c\u043d\u044b\u0439 \u0437\u0430\u0433\u0440\u0443\u0437\u0447\u0438\u043a. \u0410 \u043f\u043e\u0442\u043e\u043c \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0438 \u0440\u0435\u0448\u0438\u043b\u0438 \u0441\u043c\u0435\u0441\u0442\u0438\u0442\u044c \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u0430\u043a\u0446\u0435\u043d\u0442\u044b, \u043e\u0442\u043a\u0430\u0437\u0430\u043b\u0438\u0441\u044c \u043e\u0442 \u0443\u043d\u0438\u0432\u0435\u0440\u0441\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u0437\u0430\u0433\u0440\u0443\u0437\u0447\u0438\u043a\u0430 \u0432 \u043f\u043e\u043b\u044c\u0437\u0443 \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 JavaScript \u043e\u0431\u0432\u0435\u0441\u0430, \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u044e\u0449\u0435\u0433\u043e \u0434\u043e\u0441\u0442\u0443\u043f \u0442\u043e\u043b\u044c\u043a\u043e \u043a \u0443\u043a\u0430\u0437\u0430\u043d\u043d\u044b\u043c \u044d\u043a\u0441\u043f\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u043c \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u044f\u043c. \u041d\u0443 \u0438 \u043d\u0430 \u043d\u0430\u0441\u0442\u043e\u044f\u0449\u0438\u0439 \u043c\u043e\u043c\u0435\u043d\u0442 \u044d\u0442\u043e\u0442 \u043e\u0431\u0432\u0435\u0441 \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u0442\u043e\u043b\u044c\u043a\u043e \u0434\u043b\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u0439 \u0438 \u043a\u043e\u043d\u0441\u0442\u0430\u043d\u0442.<\/p>\n<p>\u041e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u0435 \u043d\u0430 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u0444\u0443\u043d\u043a\u0446\u0438\u0439 \u043f\u043e \u0431\u043e\u043b\u044c\u0448\u043e\u043c\u0443 \u0441\u0447\u0451\u0442\u0443 \u043d\u0438 \u043d\u0430 \u0447\u0442\u043e \u043d\u0435 \u0432\u043b\u0438\u044f\u0435\u0442. \u041f\u0440\u043e\u0441\u0442\u043e \u0432\u043c\u0435\u0441\u0442\u043e \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440\u0430 \u043a\u043b\u0430\u0441\u0441\u0430 \u043d\u0430\u0434\u043e \u0432\u044b\u0437\u044b\u0432\u0430\u0442\u044c \u0444\u0443\u043d\u043a\u0446\u0438\u044e, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0441\u043e\u0437\u0434\u0430\u0451\u0442 \u044d\u0442\u043e\u0442 \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440 \u0438 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u0435\u0433\u043e (\u0430 \u043d\u0430 \u0441\u0430\u043c\u043e\u043c \u0434\u0435\u043b\u0435 \u043b\u0438\u0448\u044c \u0443\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u044c \u043d\u0430 \u043d\u0435\u0433\u043e \u0432 \u043f\u0430\u043c\u044f\u0442\u0438), \u0430 \u0432\u043c\u0435\u0441\u0442\u043e \u0432\u044b\u0437\u043e\u0432\u0430 \u043c\u0435\u0442\u043e\u0434\u0430 \u043a\u043b\u0430\u0441\u0441\u0430 \u043d\u0430\u0434\u043e \u0432\u044b\u0437\u044b\u0432\u0430\u0442\u044c \u0444\u0443\u043d\u043a\u0446\u0438\u044e, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442 \u0443\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u044c \u043d\u0430 \u043e\u0431\u044a\u0435\u043a\u0442, \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442 \u0443 \u043d\u0435\u0433\u043e \u043c\u0435\u0442\u043e\u0434 \u0438 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442.<\/p>\n<p>\u0415\u0449\u0451 \u0440\u0430\u0437 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u043c\u0441\u044f, \u0447\u0442\u043e \u043c\u044b \u0445\u043e\u0442\u0438\u043c \u044d\u043a\u0441\u043f\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0432 \u043c\u043e\u0434\u0443\u043b\u044c<\/p>\n<ul>\n<li>\n<p>\u0424\u0443\u043d\u043a\u0446\u0438\u044e \u0434\u043b\u044f \u043f\u043e\u0441\u0442\u0440\u043e\u0435\u043d\u0438\u044f \u0442\u0440\u0438\u0430\u043d\u0433\u0443\u043b\u044f\u0446\u0438\u0438. \u041e\u043d\u0430 \u0434\u043e\u043b\u0436\u043d\u0430 \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0442\u044c \u043f\u0440\u043e\u0441\u0442\u043e\u0439 \u0447\u0438\u0441\u043b\u043e\u0432\u043e\u0439 \u043c\u0430\u0441\u0441\u0438\u0432, \u0437\u0430\u0434\u0430\u044e\u0449\u0438\u0439 \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u044b \u0442\u043e\u0447\u0435\u043a, \u0430 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0442\u044c \u043c\u0430\u0441\u0441\u0438\u0432 \u0446\u0435\u043b\u044b\u0445 \u0447\u0438\u0441\u0435\u043b, \u043e\u043f\u0438\u0441\u044b\u0432\u0430\u044e\u0449\u0438\u0439 \u0442\u0440\u0435\u0443\u0433\u043e\u043b\u044c\u043d\u0438\u043a\u0438<\/p>\n<\/li>\n<li>\n<p>\u0414\u0432\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0434\u043b\u044f \u043f\u043e\u0441\u0442\u0440\u043e\u0435\u043d\u0438\u044f BVH. \u041f\u0435\u0440\u0432\u0430\u044f \u0438\u0437 \u043d\u0438\u0445 \u0434\u043e\u043b\u0436\u043d\u0430 \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0442\u044c \u043c\u0430\u0441\u0441\u0438\u0432 \u0441 \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u0430\u043c\u0438 \u0442\u043e\u0447\u0435\u043a \u0438 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0442\u044c \u0443\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u044c \u043d\u0430 \u043f\u043e\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u044b\u0439 \u043e\u0431\u044a\u0435\u043a\u0442 BVH. \u0412\u0442\u043e\u0440\u0430\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u044f &#8212; \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0442\u044c \u0434\u0432\u0430 \u043c\u0430\u0441\u0441\u0438\u0432\u0430: \u0441 \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u0430\u043c\u0438 \u0442\u043e\u0447\u0435\u043a \u0438 \u0441 \u043d\u043e\u043c\u0435\u0440\u0430\u043c\u0438 \u0432\u0435\u0440\u0448\u0438\u043d \u0442\u0440\u0435\u0443\u0433\u043e\u043b\u044c\u043d\u0438\u043a\u043e\u0432, \u0430 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0442\u044c \u0442\u043e\u0447\u043d\u043e \u0442\u0430\u043a \u0436\u0435 \u0443\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u044c \u043d\u0430 \u043e\u0431\u044a\u0435\u043a\u0442 BVH.<\/p>\n<\/li>\n<li>\n<p>\u0424\u0443\u043d\u043a\u0446\u0438\u044e \u043f\u043e\u0438\u0441\u043a\u0430 \u0442\u0440\u0435\u0443\u0433\u043e\u043b\u044c\u043d\u0438\u043a\u0430, \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0449\u0435\u0433\u043e \u0434\u0430\u043d\u043d\u0443\u044e \u0442\u043e\u0447\u043a\u0443. \u041e\u043d\u0430 \u0434\u043e\u043b\u0436\u043d\u0430 \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0442\u044c \u0443\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u044c \u043d\u0430 \u043e\u0431\u044a\u0435\u043a\u0442 BVH \u0438 \u0434\u0432\u0430 \u0447\u0438\u0441\u043b\u0430, \u0430 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0442\u044c \u043b\u0438\u0431\u043e \u043f\u0443\u0441\u0442\u043e\u0439 \u043c\u0430\u0441\u0441\u0438\u0432, \u0435\u0441\u043b\u0438 \u0442\u043e\u0447\u043a\u0430 \u043d\u0435 \u043f\u0440\u0438\u043d\u0430\u0434\u043b\u0435\u0436\u0438\u0442 \u043d\u0438\u043a\u0430\u043a\u043e\u043c\u0443 \u0442\u0440\u0435\u0443\u0433\u043e\u043b\u044c\u043d\u0438\u043a\u0443, \u043b\u0438\u0431\u043e \u043c\u0430\u0441\u0441\u0438\u0432 \u0438\u0437 \u0448\u0435\u0441\u0442\u0438 \u0447\u0438\u0441\u0435\u043b, \u0437\u0430\u0434\u0430\u044e\u0449\u0438\u0445 \u0432\u0435\u0440\u0448\u0438\u043d\u044b \u0442\u0440\u0435\u0443\u0433\u043e\u043b\u044c\u043d\u0438\u043a\u0430, \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0449\u0435\u0433\u043e \u0442\u043e\u0447\u043a\u0443.<\/p>\n<\/li>\n<\/ul>\n<p>\u041a\u043e\u0440\u043e\u0447\u0435, \u0441\u043e\u0437\u0434\u0430\u0451\u043c \u0444\u0430\u0439\u043b <code>delaunay_api.ts<\/code><\/p>\n<details class=\"spoiler\">\n<summary>delaunay_api.ts<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"typescript\">import { BVHNode, Triangle } from \".\/bvh\"; import { triangulate } from \".\/delaunay\"; import { Point } from \".\/point\";  export function build_triangulation(coordinates: Float32Array): Int32Array {     const points_count = coordinates.length \/ 2;     const points = new StaticArray&lt;Point>(points_count);     for(let i = 0; i &lt; points_count; i++) {         points[i] = new Point(coordinates[2*i], coordinates[2*i + 1]);     }      const triangle_indices = triangulate(points);      \/\/ convert to Int32Array     const to_return = new Int32Array(triangle_indices.length);     for(let i = 0, len = triangle_indices.length; i &lt; len; i++) {         to_return[i] = triangle_indices[i];     }      return to_return; }  export function build_bvh(coordinates: Float32Array): BVHNode {     const points_count = coordinates.length \/ 2;     const points = new StaticArray&lt;Point>(points_count);     for(let i = 0; i &lt; points_count; i++) {         points[i] = new Point(coordinates[2*i], coordinates[2*i + 1]);     }      const triangle_indices = triangulate(points);      const trinagles = new StaticArray&lt;Triangle>(triangle_indices.length \/ 3);     for(let i = 0; i &lt; trinagles.length; i++) {         const a: i32 = triangle_indices[3*i];         const b: i32 = triangle_indices[3*i + 1];         const c: i32 = triangle_indices[3*i + 2];         trinagles[i] = new Triangle([points[a], points[b], points[c]]);     }      return new BVHNode(trinagles); }  export function build_bvh_triangulation(coordinates: Float32Array, triangles: Int32Array): BVHNode {     const trinagles_array = new StaticArray&lt;Triangle>(triangles.length \/ 3);     for(let i = 0, len = trinagles_array.length; i &lt; len; i++) {         const a: i32 = triangles[3*i];         const b: i32 = triangles[3*i + 1];         const c: i32 = triangles[3*i + 2];         trinagles_array[i] = new Triangle([             new Point(coordinates[2*a], coordinates[2*a + 1]),             new Point(coordinates[2*b], coordinates[2*b + 1]),             new Point(coordinates[2*c], coordinates[2*c + 1])]);     }      return new BVHNode(trinagles_array); }  export function sample_bvh(bvh: BVHNode, x: f32, y: f32): Float32Array {     const sample_result = bvh.sample(new Point(x, y));     if(sample_result) {         const to_return = new Float32Array(6);         const a = sample_result.a();         const b = sample_result.b();         const c = sample_result.c();         to_return[0] = a.x(); to_return[1] = a.y();         to_return[2] = b.x(); to_return[3] = b.y();         to_return[4] = c.x(); to_return[5] = c.y();          return to_return;     } else {         return new Float32Array(0);     } }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u0412\u0441\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043c\u044b \u0445\u043e\u0442\u0438\u043c \u044d\u043a\u0441\u043f\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0432 \u043c\u043e\u0434\u0443\u043b\u044c WebAssembly, \u0434\u043e\u043b\u0436\u043d\u044b \u0431\u044b\u0442\u044c \u043f\u043e\u043c\u0435\u0447\u0435\u043d\u044b \u0441\u043b\u043e\u0432\u043e\u043c <code>export<\/code>. \u041f\u0435\u0440\u0432\u0430\u044f \u0438\u0437 \u043d\u0443\u0436\u043d\u044b\u0445 \u043d\u0430\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u0439<\/p>\n<pre><code class=\"typescript\">function build_triangulation(coordinates: Float32Array): Int32Array<\/code><\/pre>\n<p>\u0412 \u044d\u0442\u043e\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0434\u043b\u044f \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0438 \u0434\u0430\u043d\u043d\u044b\u0445 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442\u0441\u044f \u043c\u0430\u0441\u0441\u0438\u0432\u044b <code>Float32Array<\/code> \u0438 <code>Int32Array<\/code>. \u041e\u0431\u0432\u0435\u0441, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u0442 AssemblyScript, \u043a\u0430\u043a \u0440\u0430\u0437 \u0438 \u0431\u0443\u0434\u0435\u0442 \u043a\u043e\u043d\u0432\u0435\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043c\u0430\u0441\u0441\u0438\u0432\u044b, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043f\u0435\u0440\u0435\u0434\u0430\u044e\u0442\u0441\u044f \u0441\u043e \u0441\u0442\u043e\u0440\u043e\u043d\u044b JavaScript \u0432\u043e\u0442 \u0432 \u044d\u0442\u0438, \u0438 \u043e\u0431\u0440\u0430\u0442\u043d\u043e<\/p>\n<p>\u0421\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u0434\u0432\u0435 \u043d\u0443\u0436\u043d\u044b\u0445 \u043d\u0430\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u0438<\/p>\n<pre><code class=\"typescript\">function build_bvh(coordinates: Float32Array): BVHNode  function build_bvh_triangulation(coordinates: Float32Array, triangles: Int32Array): BVHNode<\/code><\/pre>\n<p>\u041e\u043d\u0438 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u044e\u0442 \u0443\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u0438 \u043d\u0430 \u043e\u0431\u044a\u0435\u043a\u0442. \u0421\u043e \u0441\u0442\u043e\u0440\u043e\u043d\u044b JavaScript \u044d\u0442\u043e \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u043a\u0430\u043a \u043e\u0431\u044b\u0447\u043d\u043e\u0435 \u0446\u0435\u043b\u043e\u0435 \u0447\u0438\u0441\u043b\u043e. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u043d\u0430\u043f\u0440\u044f\u043c\u0443\u044e \u0432 JavaScript \u0441 \u044d\u0442\u0438\u043c\u0438 \u043e\u0431\u044a\u0435\u043a\u0442\u0430\u043c\u0438 \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u043d\u0435\u043b\u044c\u0437\u044f.<\/p>\n<p>\u0427\u0435\u0442\u0432\u0451\u0440\u0442\u0430\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u044f<\/p>\n<pre><code class=\"typescript\">function sample_bvh(bvh: BVHNode, x: f32, y: f32): Float32Array<\/code><\/pre>\n<p>\u041a\u043e\u043c\u043f\u0438\u043b\u0438\u0440\u0443\u0435\u043c<\/p>\n<pre><code>asc assembly\/delaunay_api.ts -o build\/delaunay.wasm --bindings esm --optimizeLevel 3 -Ospeed<\/code><\/pre>\n<p>\u0421\u043c\u044b\u0441\u043b \u043f\u043e\u0447\u0442\u0438 \u0432\u0441\u0435\u0445 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043e\u0432 \u043a\u043e\u043c\u0430\u043d\u0434\u044b \u043f\u043e\u043d\u044f\u0442\u0435\u043d. <code>--bindings esm<\/code> \u0433\u043e\u0432\u043e\u0440\u0438\u0442 \u043e \u0442\u043e\u043c, \u0447\u0442\u043e \u043d\u0430\u0434\u043e \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c JavaScript \u043e\u0431\u0432\u0435\u0441. <code>--optimizeLevel 3<\/code> \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442 \u043d\u0430 \u0443\u0440\u043e\u0432\u0435\u043d\u044c \u043e\u043f\u0442\u0438\u043c\u0438\u0437\u0430\u0446\u0438\u0438. <code>-Ospeed<\/code> \u0441\u043e\u043e\u0431\u0449\u0430\u0435\u0442, \u0447\u0442\u043e \u043f\u0440\u0438 \u043e\u043f\u0442\u0438\u043c\u0438\u0437\u0430\u0446\u0438\u0438 \u043d\u0430\u0434\u043e \u043d\u0430\u043f\u0438\u0440\u0430\u0442\u044c \u043d\u0435 \u043d\u0430 \u0440\u0430\u0437\u043c\u0435\u0440 \u043c\u043e\u0434\u0443\u043b\u044f, \u0430 \u043d\u0430 \u0435\u0433\u043e \u0431\u044b\u0441\u0442\u0440\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0435. \u041f\u0440\u0438 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0446\u0438\u0438 \u0438\u0442\u043e\u0433\u043e\u0432\u043e\u0433\u043e \u043c\u043e\u0434\u0443\u043b\u044f \u043c\u044b \u043d\u0435 \u0445\u043e\u0442\u0438\u043c, \u0447\u0442\u043e\u0431\u044b \u0432 \u043d\u0435\u0433\u043e \u0432\u043a\u043b\u044e\u0447\u0430\u043b\u0438\u0441\u044c \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0434\u043b\u044f \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0438 WASI, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043d\u0438\u043a\u0430\u043a\u0438\u0445 \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0445 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u043e\u043d\u043d\u044b\u0445 \u0444\u0430\u0439\u043b\u043e\u0432 \u043d\u0435 \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c. \u041d\u0443 \u0438 \u0441\u0430\u043c \u043c\u043e\u0434\u0443\u043b\u044c \u0432\u043e \u0432\u0440\u0435\u043c\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u043a\u043e\u043d\u0435\u0447\u043d\u043e \u0436\u0435 \u043d\u0435 \u0434\u043e\u043b\u0436\u0435\u043d \u0432\u044b\u0437\u044b\u0432\u0430\u0442\u044c \u043d\u0438\u043a\u0430\u043a\u0438\u0445 \u043a\u043e\u043c\u0430\u043d\u0434 \u0432\u0440\u043e\u0434\u0435 <code>console.log<\/code>.<\/p>\n<p>\u0412 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0435 \u043f\u043e\u043b\u0443\u0447\u0438\u043c \u0444\u0430\u0439\u043b <code>delaunay.wasm<\/code> \u0440\u0430\u0437\u043c\u0435\u0440\u043e\u043c 19 \u043a\u0438\u043b\u043e\u0431\u0430\u0439\u0442 \u0438 <code>delaunay.js<\/code> \u0440\u0430\u0437\u043c\u0435\u0440\u043e\u043c 6 \u043a\u0438\u043b\u043e\u0431\u0430\u0439\u0442 (\u0438 \u044d\u0442\u043e \u043d\u0435 \u043c\u0438\u043d\u0438\u0444\u0438\u0446\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0439).<\/p>\n<p>\u041f\u0440\u0438\u043c\u0435\u0440 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f<\/p>\n<pre><code class=\"typescript\">import * as exports from \".\/delaunay.js\";  const coordinates = [ -0.5, 3.0, 8.0, -3.5, -7.0, 3.0, 2.0, -10.0, 7.0, 8.0, 8.0, 5.5]; const triangle_indices = exports.build_triangulation(coordinates); console.log(triangle_indices);  let bvh = exports.build_bvh(coordinates); let s = exports.sample_bvh(bvh, 0.0, 0.0); console.log(s);<\/code><\/pre>\n<p>\u041e\u0442\u0432\u0435\u0442 \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442\u0441\u044f \u0442\u043e\u0436\u0435 \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u044b\u0439.<\/p>\n<h3>wasm-pack \u0438 Rust<\/h3>\n<p>\u0411\u0443\u0434\u0435\u043c \u043f\u0440\u0438\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0442\u044c\u0441\u044f \u0442\u043e\u0433\u043e \u0434\u0435 \u043f\u043e\u0434\u0445\u043e\u0434\u0430, \u0447\u0442\u043e \u0438 \u0432 \u0441\u043b\u0443\u0447\u0430\u0435 c++. \u041f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u0438\u043c, \u0447\u0442\u043e \u043d\u0430\u043c \u043d\u0430\u0434\u043e \u043f\u0440\u043e\u0441\u0442\u043e \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0443 \u0434\u043b\u044f \u043f\u043e\u0441\u0442\u0440\u043e\u0435\u043d\u0438\u044f \u0442\u0440\u0438\u0430\u043d\u0433\u0443\u043b\u044f\u0446\u0438\u0438 \u0414\u0435\u043b\u043e\u043d\u0435 \u043d\u0430 Rust-\u0435. <\/p>\n<h4>\u041f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0430 \u043d\u0430 Rust<\/h4>\n<p>\u041d\u0438\u0447\u0442\u043e\u0436\u0435 \u0441\u0443\u043c\u043d\u044f\u0448\u0435\u0441\u044f \u0441\u043e\u0437\u0434\u0430\u0451\u043c \u043f\u0443\u0441\u0442\u043e\u0439 \u043f\u0440\u043e\u0435\u043a\u0442. \u041f\u043e\u043a\u0430 \u0434\u0430\u0436\u0435 \u0441\u0442\u043e\u0440\u043e\u043d\u043d\u0438\u0435 \u043a\u0440\u044d\u0439\u0442\u044b \u043d\u0438\u043a\u0430\u043a\u0438\u0435 \u043d\u0435 \u043d\u0443\u0436\u043d\u044b.<\/p>\n<pre><code>cargo init<\/code><\/pre>\n<p>\u0414\u0430\u043b\u044c\u0448\u0435 \u0432 \u043f\u0430\u043f\u043a\u0435 <code>.\/src\/<\/code> \u0441\u043e\u0437\u0434\u0430\u0451\u043c \u0442\u0440\u0438 \u0444\u0430\u0439\u043b\u0430 <code>point.rs<\/code>, <code>delaunay.rs<\/code> \u0438 <code>bvh.rs<\/code>. \u0421\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u043e\u0435 \u044d\u0442\u0438\u0445 \u0444\u0430\u0439\u043b\u043e\u0432 \u043f\u0440\u0438\u043c\u0435\u0440\u043d\u043e \u0442\u0430\u043a\u043e\u0435 \u0436\u0435, \u0447\u0442\u043e \u0438 \u0440\u0430\u043d\u044c\u0448\u0435 (\u043d\u043e \u0442\u043e\u043b\u044c\u043a\u043e \u043d\u0430 Rust-\u0435).<\/p>\n<details class=\"spoiler\">\n<summary>point.rs<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"rust\">#[derive(Debug, Clone)] pub struct Point {     pub x: f32,     pub y: f32 }  impl Point {     pub fn new(in_x: f32, in_y: f32) -> Point {         Point{ x: in_x, y: in_y}     } }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<details class=\"spoiler\">\n<summary>delaunay.rs<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"rust\">use crate::point::Point;  const EPSILON: f32 = 0.00001;  #[derive(Debug, Clone)] struct TriangleCircle {     i: usize,     j: usize,     k: usize,      x: f32,     y: f32,      radius_sq: f32 }  fn maximum(a: f32, b: f32) -> f32 {     if a > b { a } else { b } }  fn absolute(a: f32, b: f32) -> f32 {     if a > b { a - b } else { b - a } }  fn build_supertriangle(points: &amp;Vec&lt;Point>) -> Vec&lt;Point> {     let mut x_min: f32 = f32::MAX;     let mut y_min: f32 = f32::MAX;     let mut x_max: f32 = f32::MIN;     let mut y_max: f32 = f32::MIN;      let points_count = points.len();      for i in 0..points_count {         let p = &amp;points[i];         if p.x &lt; x_min { x_min = p.x; }         if p.x > x_max { x_max = p.x; }         if p.y &lt; y_min { y_min = p.y; }         if p.y > y_max { y_max = p.y; }     }      let dx = x_max - x_min;     let dy = y_max - y_min;      let d_max = maximum(dx, dy);     let x_mid = x_min + dx * 0.5;     let y_mid = y_min + dy * 0.5;      vec![Point::new(x_mid - 20.0 * d_max, y_mid - d_max),          Point::new(x_mid, y_mid + 20.0 * d_max),          Point::new(x_mid + 20.0 * d_max, y_mid - d_max)] }  fn circumcircle(points: &amp;Vec&lt;Point>, i: usize, j: usize, k: usize) -> TriangleCircle {     let point_i = &amp;points[i];     let point_j = &amp;points[j];     let point_k = &amp;points[k];      let x_1: f32 = point_i.x;     let y_1: f32 = point_i.y;      let x_2: f32 = point_j.x;     let y_2: f32 = point_j.y;          let x_3: f32 = point_k.x;     let y_3: f32 = point_k.y;      let y1_y2: f32 = absolute(y_1, y_2);     let y2_y3: f32 = absolute(y_2, y_3);      let center_x: f32;     let center_y: f32;     let m_1: f32;     let m_2: f32;     let mx_1: f32;     let mx_2: f32;     let my_1: f32;     let my_2: f32;      if y1_y2 &lt; EPSILON {         m_2 = -(x_3 - x_2) \/ (y_3 - y_2);         mx_2 = (x_2 + x_3) \/ 2.0;         my_2 = (y_2 + y_3) \/ 2.0;         center_x = (x_2 + x_1) \/ 2.0;         center_y = m_2 * (center_x - mx_2) + my_2;     } else if y2_y3 &lt; EPSILON {         m_1 = -(x_2 - x_1) \/ (y_2 - y_1);         mx_1 = (x_1 + x_2) \/ 2.0;         my_1 = (y_1 + y_2) \/ 2.0;         center_x = (x_3 + x_2) \/ 2.0;         center_y = m_1 * (center_x - mx_1) + my_1;     } else {         m_1 = -(x_2 - x_1) \/ (y_2 - y_1);         m_2 = -(x_3 - x_2) \/ (y_3 - y_2);         mx_1 = (x_1 + x_2) \/ 2.0;         mx_2 = (x_2 + x_3) \/ 2.0;         my_1 = (y_1 + y_2) \/ 2.0;         my_2 = (y_2 + y_3) \/ 2.0;         center_x = (m_1 * mx_1 - m_2 * mx_2 + my_2 - my_1) \/ (m_1 - m_2);         center_y = if y1_y2 > y2_y3 { m_1 * (center_x - mx_1) + my_1 } else { m_2 * (center_x - mx_2) + my_2 };     }      let dx = x_2 - center_x;     let dy = y_2 - center_y;      TriangleCircle { i: i, j: j, k: k, x: center_x, y: center_y, radius_sq: dx*dx + dy*dy } }  fn remove_duplicates(edges: &amp;mut Vec&lt;usize>) {     let mut j: usize = edges.len();     while j >= 2 {         j = j - 1;         let b = edges[j];          j = j - 1;         let a = edges[j];          let mut i: usize = j;         while i >= 2 {             i = i - 1;             let n = edges[i];             i = i - 1;             let m = edges[i];              if (a == m &amp;&amp; b == n) || (a == n &amp;&amp; b == m) {                 edges.remove(j + 1); edges.remove(j);                 edges.remove(i + 1); edges.remove(i);                 j = j - 2;                 break;             }         }     } }  pub fn triangulate(in_points: &amp;Vec&lt;Point>) -> Vec&lt;usize> {     let points_count = in_points.len();     if points_count &lt; 3 {         return Vec::new();     }      let mut indices: Vec&lt;usize> = Vec::with_capacity(points_count);     for i in 0..points_count {         indices.push(i);     }      indices.sort_by(|a, b| { in_points[*a].x.partial_cmp(&amp;in_points[*b].x).unwrap() });          \/\/ create copy of the in_points array     let mut points: Vec&lt;Point> = in_points.to_vec();     let mut st = build_supertriangle(&amp;points);     points.append(&amp;mut st);      let mut open_list: Vec&lt;TriangleCircle> = Vec::new();     let mut closed_list: Vec&lt;TriangleCircle> = Vec::new();     let mut edges_list: Vec&lt;usize> = Vec::new();      open_list.push(circumcircle(&amp;points, points_count, points_count + 1, points_count + 2));      for i in 0..points_count {         let c = indices[i];         let p = &amp;points[c];         edges_list.clear();          for j in (0..open_list.len()).rev() {             let t = &amp;open_list[j];              let dx = p.x - t.x;             if dx > 0.0 &amp;&amp; dx*dx > t.radius_sq {                 closed_list.push(t.clone());                 open_list.remove(j);                 continue;             }              let dy = p.y - t.y;             if dx*dx + dy*dy - t.radius_sq > EPSILON {                 continue;             }                          edges_list.push(t.i); edges_list.push(t.j);             edges_list.push(t.j); edges_list.push(t.k);             edges_list.push(t.k); edges_list.push(t.i);              open_list.remove(j);         }          remove_duplicates(&amp;mut edges_list);          let mut k: usize = edges_list.len();         while k >= 2 {             k = k - 1;             let b = edges_list[k];             k = k - 1;             let a = edges_list[k];             open_list.push(circumcircle(&amp;points, a, b, c));         }     }      for i in 0..open_list.len() {         closed_list.push(open_list[i].clone());     }      open_list.clear();     edges_list.clear();      let mut triangles: Vec&lt;usize> = Vec::new();     for i in 0..closed_list.len() {         let t = &amp;closed_list[i];         if t.i &lt; points_count &amp;&amp; t.j &lt; points_count &amp;&amp; t.k &lt; points_count {             triangles.push(t.i);             triangles.push(t.j);             triangles.push(t.k);         }     }      closed_list.clear();      triangles }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<details class=\"spoiler\">\n<summary>bvh.rs<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"typescript\">use crate::point::Point;  fn minimum(a: f32, b: f32) -> f32 {     if a &lt; b { return a; } else { return b; } }  fn maximum(a: f32, b: f32) -> f32 {     if a &lt; b { return b; } else { return a; } }  #[derive(Debug, Clone)] struct AABB {     x_min: f32,     y_min: f32,     x_max: f32,     y_max: f32, }  #[derive(Debug, Clone)] pub struct Triangle {     pub a: Point,     pub b: Point,     pub c: Point,      aabb: AABB,     center: Point }  impl Triangle {     pub fn new(mut vertices: Vec&lt;Point>) -> Triangle {         let mut x_min: f32 = f32::MAX;         let mut y_min: f32 = f32::MAX;         let mut x_max: f32 = f32::MIN;         let mut y_max: f32 = f32::MIN;          let mut x_accum: f32 = 0.0;         let mut y_accum: f32 = 0.0;          for i in 0..vertices.len() {             let v = &amp;vertices[i];             if v.x &lt; x_min { x_min = v.x; }             if v.x > x_max { x_max = v.x; }             if v.y &lt; y_min { y_min = v.y; }             if v.y > y_max { y_max = v.y; }              x_accum += v.x;             y_accum += v.y;         }          let c = vertices.pop().unwrap();         let b = vertices.pop().unwrap();         let a = vertices.pop().unwrap();          Triangle {             a: a,             b: b,             c: c,             aabb: AABB { x_min, y_min, x_max, y_max },             center: Point::new(x_accum \/ 3.0, y_accum \/ 3.0)}     }      fn get_aabb(&amp;self) -> AABB {         self.aabb.clone()     }      fn get_center(&amp;self) -> Point {         self.center.clone()     }      fn is_point_inside(&amp;self, point: &amp;Point) -> bool {         let as_x = point.x - self.a.x;         let as_y = point.y - self.a.y;          let s_ab = ((self.b.x - self.a.x) * as_y - (self.b.y - self.a.y) * as_x) > 0.0;          if ((self.c.x - self.a.x) * as_y - (self.c.y - self.a.y) * as_x > 0.0) == s_ab {             return false;         }         if ((self.c.x - self.b.x) * (point.y - self.b.y) - (self.c.y - self.b.y) * (point.x - self.b.x) > 0.0) != s_ab {             return false;         }         return true;     } }  fn union_aabb(x: AABB, y: AABB) -> AABB {     AABB {         x_min: minimum(x.x_min, y.x_min),         y_min: minimum(x.y_min, y.y_min),         x_max: maximum(x.x_max, y.x_max),         y_max: maximum(x.y_max, y.y_max),     } }  #[derive(Debug)] pub struct BVHNode {     triangle: Option&lt;Triangle>,     left_node: Option&lt;Box&lt;BVHNode>>,     right_node: Option&lt;Box&lt;BVHNode>>,     aabb: AABB }  impl BVHNode {     pub fn new(mut triangles: Vec&lt;Triangle>) -> BVHNode {         let objects_count = triangles.len();         if objects_count == 1 {             let t: Triangle = triangles.pop().unwrap();             let aabb = t.get_aabb();             BVHNode {                 triangle: Some(t),                 left_node: None,                 right_node: None,                 aabb: aabb             }         } else {             let mut x_median: f32 = 0.0;             let mut y_median: f32 = 0.0;              let mut x_min = f32::MAX;             let mut x_max = f32::MIN;             let mut y_min = f32::MAX;             let mut y_max = f32::MIN;              for i in 0..objects_count {                 let t = &amp;triangles[i];                 let c = t.get_center();                 x_median += c.x;                 y_median += c.y;                  if c.x &lt; x_min { x_min = c.x; }                 if c.x > x_max { x_max = c.x; }                 if c.y &lt; y_min { y_min = c.y; }                 if c.y > y_max { y_max = c.y; }             }              let split_axis = if (x_max - x_min) > (y_max - y_min) { 0 } else { 1 };             let median: f32 = if split_axis == 0 { x_median \/ objects_count as f32 } else { y_median \/ objects_count as f32 };              let mut left: Vec&lt;Triangle> = Vec::new();             let mut right: Vec&lt;Triangle> = Vec::new();              for _i in 0..objects_count {                 let t = triangles.pop().unwrap();                 let c = t.get_center();                 let v = if split_axis == 0 { c.x } else { c.y };                 if v &lt; median {                     left.push(t);                 } else {                     right.push(t);                 }             }              if left.len() == 0 {                 left.push(right.pop().unwrap());             }              if right.len() == 0 {                 right.push(left.pop().unwrap());             }              let left_node = BVHNode::new(left);             let right_node = BVHNode::new(right);              let left_aabb = left_node.get_aabb();             let right_aabb = right_node.get_aabb();              BVHNode {                 left_node: Some(Box::new(left_node)),                 right_node: Some(Box::new(right_node)),                 triangle: None,                 aabb: union_aabb(left_aabb, right_aabb)             }         }     }      fn get_aabb(&amp;self) -> AABB {         self.aabb.clone()     }      fn is_inside_aabb(&amp;self, point: &amp;Point) -> bool {         self.aabb.x_min &lt; point.x &amp;&amp; self.aabb.y_min &lt; point.y &amp;&amp; self.aabb.x_max > point.x &amp;&amp; self.aabb.y_max > point.y     }      pub fn sample(&amp;self, point: &amp;Point) -> Option&lt;Triangle> {         if self.is_inside_aabb(point) {            match &amp;self.triangle {                 Some(t) => {                     if t.is_point_inside(point) {                         Some(t.clone())                     } else {                         None                     }                 },                 None => {                     match &amp;self.left_node {                         Some(node) => {                             \/\/ left node exists                             match &amp;self.right_node {                                 Some(other) => {                                     \/\/ left and right are exists                                     let left_sample = node.sample(point);                                     let right_sample = other.sample(point);                                      match left_sample {                                         Some(t) => {                                             \/\/ left sample valid                                             \/\/ check right sample                                             match right_sample {                                                 Some(u) => {                                                     \/\/ both right and left are valid                                                     \/\/ it should not happens, but we select the closest triangle                                                     let l_c = t.get_center();                                                     let r_c = u.get_center();                                                      let l_dist = (l_c.x - point.x)*(l_c.x - point.x) + (l_c.y - point.y)*(l_c.y - point.y);                                                     let r_dist = (r_c.x - point.x)*(r_c.x - point.x) + (r_c.y - point.y)*(r_c.y - point.y);                                                      if l_dist &lt; r_dist {                                                         Some(t)                                                     } else {                                                         Some(u)                                                     }                                                 },                                                 None => {                                                     \/\/ left valid, right empty                                                     Some(t)                                                 },                                             }                                         },                                         None => {                                             \/\/ left sample empty                                             right_sample                                         },                                     }                                 },                                 None => {                                     \/\/ only left                                     node.sample(point)                                 },                             }                         },                         None => {                             \/\/ left node is empty                             match &amp;self.right_node {                                 Some(node) => {                                     \/\/ only right                                     node.sample(point)                                 },                                 None => {                                     \/\/ both nodes are empty                                     None                                 }                             }                         }                     }                 }             }         } else {             None         }     } }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u041d\u0438\u043a\u0430\u043a\u043e\u0439 \u0441\u043f\u0435\u0446\u0438\u0444\u0438\u043a\u0438 \u0442\u0443\u0442 \u043e\u0441\u043e\u0431\u043e \u043d\u0435\u0442. \u041d\u0443 \u043a\u0440\u043e\u043c\u0435 \u0442\u043e\u0439, \u0447\u0442\u043e \u043f\u0440\u0438\u0432\u043d\u043e\u0441\u0438\u0442 \u0441\u0430\u043c Rust.<\/p>\n<p>\u0412 \u0444\u0430\u0439\u043b\u0435 <code>main.rs<\/code> \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c, \u043a\u0430\u043a \u0432\u0441\u0451 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442<\/p>\n<pre><code class=\"rust\">mod point; mod delaunay; mod bvh;  use crate::point::Point; use crate::delaunay::triangulate; use crate::bvh::{Triangle, BVHNode};  fn main() {     let points = vec![         Point::new(-0.5, 3.0),         Point::new(8.0, -3.5),         Point::new(-7.0, 3.0),         Point::new(2.0, -10.0),         Point::new(7.0, 8.0),         Point::new(8.0, 5.5)         ];     let triangle_indices = triangulate(&amp;points);     println!(\"{:?}\", triangle_indices);      let mut triangles: Vec&lt;Triangle> = Vec::with_capacity(triangle_indices.len() \/ 3);     for i in 0..(triangle_indices.len() \/ 3) {         let a = triangle_indices[3*i];         let b = triangle_indices[3*i + 1];         let c = triangle_indices[3*i + 2];         triangles.push(Triangle::new(vec!(points[a].clone(), points[b].clone(), points[c].clone())));     }      let tree = BVHNode::new(triangles);     let s = tree.sample(&amp;Point::new(0.0, 0.0));      println!(\"{:?}\", s); }<\/code><\/pre>\n<p>\u0412\u0441\u0451 \u0434\u043e\u043b\u0436\u043d\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u043d\u043e\u0440\u043c\u0430\u043b\u044c\u043d\u043e.<\/p>\n<h4>\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 wasm-pack<\/h4>\n<p>\u0421\u0430\u043c wasm-pack \u043c\u043e\u0436\u043d\u043e \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c \u0441 <a href=\"https:\/\/rustwasm.github.io\/wasm-pack\/installer\/\" rel=\"noopener noreferrer nofollow\">\u043e\u0444\u0438\u0446\u0438\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u0441\u0430\u0439\u0442\u0430<\/a>. \u0422\u0430\u043a-\u0442\u043e \u0443 \u043d\u0435\u0433\u043e \u043c\u043d\u043e\u0433\u043e \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0435\u0439, \u043d\u043e \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043b\u0438\u0448\u044c \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0435. \u041f\u043e\u0434\u0445\u043e\u0434 \u043a \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0446\u0438\u0438 \u043c\u043e\u0434\u0443\u043b\u044f WebAssembly \u0442\u0443\u0442 \u043f\u0440\u0438\u043c\u0435\u0440\u043d\u043e \u0442\u0430\u043a\u043e\u0439 \u0436\u0435, \u043a\u0430\u043a\u043e\u0439 \u0431\u044b\u043b \u043f\u0440\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0438 Emscripten. \u041d\u0430\u043c \u043f\u043e\u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0445 \u043e\u0431\u0451\u0440\u0442\u043e\u043a \u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u0439, \u0432 \u043a\u043e\u0442\u043e\u0440\u044b\u0445, \u0432 \u0447\u0430\u0441\u0442\u043d\u043e\u0441\u0442\u0438, \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u043c\u0435\u0436\u0434\u0443 \u0434\u0430\u043d\u043d\u044b\u043c\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043f\u0440\u0438\u0445\u043e\u0434\u044f\u0442 \u0438\u0437\u0432\u043d\u0435, \u0438 \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442\u0441\u044f \u0432 \u043d\u0430\u0448\u0438\u0445 \u0443\u0436\u0435 \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u043d\u044b\u0445 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0430\u0445.<\/p>\n<p>\u0418\u0442\u0430\u043a, \u0441\u043e\u0437\u0434\u0430\u0451\u043c \u0432 \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u0438 <code>.\/src\/<\/code> \u0444\u0430\u0439\u043b <code>lib.rs<\/code>. \u0412 \u043d\u0451\u043c-\u0442\u043e \u0438 \u0431\u0443\u0434\u0435\u043c \u0432\u0441\u0451 \u0434\u0435\u043b\u0430\u0442\u044c. \u041d\u043e \u0442\u0435\u043f\u0435\u0440\u044c \u043d\u0430\u043c \u043d\u0430\u0434\u043e \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0432 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u043e\u043d\u043d\u044b\u0439 \u0444\u0430\u0439\u043b <code>Cargo.toml<\/code> \u0440\u0430\u0437\u044a\u044f\u0441\u043d\u0435\u043d\u0438\u044f, \u0447\u0442\u043e\u0431\u044b Rust \u043d\u0435 \u043f\u0443\u0442\u0430\u043b\u0441\u044f. \u0414\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u0442\u0430\u043a\u0438\u0435 \u0441\u0442\u0440\u043e\u0447\u043a\u0438<\/p>\n<pre><code>[lib] name = \"delaunay\" path = \"src\/lib.rs\" crate-type = [\"cdylib\", \"rlib\"]  [[bin]] name = \"delaunay_app\" path = \"src\/main.rs\"<\/code><\/pre>\n<p>\u042d\u0442\u043e \u0433\u043e\u0432\u043e\u0440\u0438\u0442 Rust-\u0443, \u0447\u0442\u043e \u0432 \u0444\u0430\u0439\u043b\u0435 <code>main.rs<\/code> \u043d\u0430\u0447\u0438\u043d\u0430\u0435\u0442\u0441\u044f \u0431\u0438\u043d\u0430\u0440\u043d\u044b\u0439 \u043a\u0440\u044d\u0439\u0442, \u0430 \u0432 \u0444\u0430\u0439\u043b\u0435 <code>lib.rs<\/code> &#8212; \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u0447\u043d\u044b\u0439. \u0415\u0449\u0451 \u0443\u043a\u0430\u0436\u0435\u043c \u0434\u0432\u0435 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043d\u0430\u043c \u043f\u043e\u043d\u0430\u0434\u043e\u0431\u044f\u0442\u0441\u044f<\/p>\n<pre><code>[dependencies] wasm-bindgen = \"0.2.84\" js-sys = \"0.3.61\"<\/code><\/pre>\n<p>\u0412 \u043e\u0442\u043b\u0438\u0447\u0438\u0435 \u043e\u0442 AssemblyScript \u0438 \u043f\u043e\u0434\u043e\u0431\u043d\u043e Emscripten wasm-pack \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u044d\u043a\u0441\u043f\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0432 \u043c\u043e\u0434\u0443\u043b\u044c \u043a\u043b\u0430\u0441\u0441\u044b. \u0415\u0441\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u0435, \u0447\u0442\u043e \u044d\u0442\u0438 \u043a\u043b\u0430\u0441\u0441\u044b \u043c\u043e\u0433\u0443\u0442 \u0438\u043c\u0435\u0442\u044c \u043b\u0438\u0448\u044c \u043e\u0434\u0438\u043d \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u0441\u0435\u0439\u0447\u0430\u0441 \u043d\u0430\u043c \u043d\u0430\u0434\u043e \u044d\u043a\u0441\u043f\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0435:<\/p>\n<ul>\n<li>\n<p>\u0424\u0443\u043d\u043a\u0446\u0438\u044e \u0434\u043b\u044f \u043f\u043e\u0441\u0442\u0440\u043e\u0435\u043d\u0438\u044f \u0442\u0440\u0438\u0430\u043d\u0433\u0443\u043b\u044f\u0446\u0438\u0438<\/p>\n<\/li>\n<li>\n<p>\u041a\u043b\u0430\u0441\u0441 BVHNode \u0441 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440\u043e\u043c, \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u044e\u0449\u0438\u043c \u043c\u0430\u0441\u0441\u0438\u0432 \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442 \u0442\u043e\u0447\u0435\u043a \u043d\u0430 \u043f\u043b\u043e\u0441\u043a\u043e\u0441\u0442\u0438<\/p>\n<\/li>\n<li>\n<p>\u0424\u0443\u043d\u043a\u0446\u0438\u044e, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u043e\u0431\u044a\u0435\u043a\u0442 \u043a\u043b\u0430\u0441\u0441\u0430 BVHNode, \u043f\u043e\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u043e\u0433\u043e \u043f\u043e \u043f\u043e\u0434\u0430\u043d\u043d\u044b\u043c \u043d\u0430 \u0432\u0445\u043e\u0434 \u0434\u0432\u0443\u043c \u043c\u0430\u0441\u0441\u0438\u0432\u0430\u043c, \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0449\u0438\u0445 \u043a\u0430\u043a \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u044b \u0442\u043e\u0447\u0435\u043a, \u0442\u0430\u043a \u0438 \u043d\u043e\u043c\u0435\u0440\u0430 \u0432\u0435\u0440\u0448\u0438\u043d \u0442\u0440\u0435\u0443\u0433\u043e\u043b\u044c\u043d\u0438\u043a\u043e\u0432<\/p>\n<\/li>\n<li>\n<p>\u041c\u0435\u0442\u043e\u0434 \u043a\u043b\u0430\u0441\u0441\u0430 BVHNode, \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u044e\u0449\u0435\u0433\u043e \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u044b \u0432\u0435\u0440\u0448\u0438\u043d \u0442\u0440\u0435\u0443\u0433\u043e\u043b\u044c\u043d\u0438\u043a\u0430, \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0449\u0435\u0433\u043e \u0434\u0430\u043d\u043d\u0443\u044e \u0442\u043e\u0447\u043a\u0443<\/p>\n<\/li>\n<\/ul>\n<p>\u0412 \u043e\u0431\u0449\u0435\u043c \u043f\u0438\u0448\u0435\u043c \u0442\u0430\u043a\u043e\u0435<\/p>\n<details class=\"spoiler\">\n<summary>lib.rs<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"rust\">mod point; mod delaunay; mod bvh;  use crate::point::Point; use crate::delaunay::triangulate; use crate::bvh::{BVHNode, Triangle};  use wasm_bindgen::prelude::*; use js_sys::Array;  #[wasm_bindgen] pub fn build_triangulation(coordinates: &amp;[f32]) -> Array {     let points_count = coordinates.len() \/ 2;     let mut points: Vec&lt;Point> = Vec::with_capacity(points_count);     for i in 0..points_count {         points.push(Point::new(coordinates[2*i], coordinates[2*i + 1]));     }      let triangle_indices = triangulate(&amp;points);      return triangle_indices.into_iter().map(JsValue::from).collect(); }  #[derive(Debug)] #[wasm_bindgen(js_name = BVHNode)] pub struct BVHNodeWrapper {     bvh: BVHNode }  #[wasm_bindgen(js_class = BVHNode)] impl BVHNodeWrapper {     #[wasm_bindgen(constructor)]     pub fn new(coordinates: &amp;[f32]) -> BVHNodeWrapper {         let points_count = coordinates.len() \/ 2;         let mut points: Vec&lt;Point> = Vec::with_capacity(points_count);         for i in 0..points_count {             points.push(Point::new(coordinates[2*i], coordinates[2*i + 1]));         }          let triangle_indices = triangulate(&amp;points);          let mut triangles: Vec&lt;Triangle> = Vec::with_capacity(triangle_indices.len() \/ 3);         for i in 0..(triangle_indices.len() \/ 3) {             let a = triangle_indices[3*i];             let b = triangle_indices[3*i + 1];             let c = triangle_indices[3*i + 2];             triangles.push(Triangle::new(vec!(points[a].clone(), points[b].clone(), points[c].clone())));         }          BVHNodeWrapper {             bvh: BVHNode::new(triangles)         }     }      pub fn new_trianglulation(coordinates: &amp;[f32], triangles: &amp;[i32]) -> BVHNodeWrapper {         let triangles_count = triangles.len() \/ 3;         let mut triangles_array: Vec&lt;Triangle> = Vec::with_capacity(triangles_count);         for i in 0..triangles_count {             let a = triangles[3*i] as usize;             let b = triangles[3*i + 1] as usize;             let c = triangles[3*i + 2] as usize;              triangles_array.push(Triangle::new(vec!(Point::new(coordinates[2*a], coordinates[2*a + 1]), Point::new(coordinates[2*b], coordinates[2*b + 1]), Point::new(coordinates[2*c], coordinates[2*c + 1]))));         }          BVHNodeWrapper {             bvh: BVHNode::new(triangles_array)         }     }      pub fn sample(&amp;self, x: f32, y: f32) -> Array {         let point = Point::new(x, y);         let s = self.bvh.sample(&amp;point);          match s {             Some(t) => {                 let to_return = Array::new_with_length(6);                 to_return.set(0, JsValue::from(t.a.x)); to_return.set(1, JsValue::from(t.a.y));                 to_return.set(2, JsValue::from(t.b.x)); to_return.set(3, JsValue::from(t.b.y));                 to_return.set(4, JsValue::from(t.c.x)); to_return.set(5, JsValue::from(t.c.y));                 to_return             },             None => {                 Array::new()             },         }     } }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u041e\u0441\u043d\u043e\u0432\u043d\u044b\u0435 \u0448\u0430\u0433\u0438, \u0447\u0442\u043e \u0442\u0443\u0442 \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u043e.<\/p>\n<p>\u0421\u043d\u0430\u0447\u0430\u043b\u0430 \u0433\u043e\u0432\u043e\u0440\u0438\u043c<\/p>\n<pre><code class=\"rust\">use wasm_bindgen::prelude::*;<\/code><\/pre>\n<p>\u042d\u0442\u0430 \u043a\u043e\u043c\u0430\u043d\u0434\u0430 \u0434\u0435\u043b\u0430\u0435\u0442 \u0447\u0442\u043e \u043d\u0430\u0434\u043e.<\/p>\n<p>\u041f\u043e\u0442\u043e\u043c \u043e\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u044e \u0434\u043b\u044f \u043f\u043e\u0441\u0442\u0440\u043e\u0435\u043d\u0438\u044f \u0442\u0440\u0438\u0430\u043d\u0433\u0443\u043b\u044f\u0446\u0438\u0438<\/p>\n<pre><code class=\"rust\">#[wasm_bindgen] pub fn build_triangulation(coordinates: &amp;[f32]) -> Array {     let points_count = coordinates.len() \/ 2;     let mut points: Vec&lt;Point> = Vec::with_capacity(points_count);     for i in 0..points_count {         points.push(Point::new(coordinates[2*i], coordinates[2*i + 1]));     }      let triangle_indices = triangulate(&amp;points);      return triangle_indices.into_iter().map(JsValue::from).collect(); }<\/code><\/pre>\n<p>\u0412 \u044d\u0442\u043e\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0441\u0442\u043e\u0438\u0442 \u043e\u0442\u043c\u0435\u0442\u0438\u0442\u044c \u0442\u0440\u0438 \u0432\u0435\u0449\u0438:<\/p>\n<ul>\n<li>\n<p>\u041e\u043d\u0430 \u043f\u043e\u043c\u0435\u0447\u0430\u0435\u0442\u0441\u044f \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u043e\u043c <code>#[wasm_bindgen]<\/code>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043e\u0437\u043d\u0430\u0447\u0430\u0435\u0442, \u0447\u0442\u043e \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u0431\u0443\u0434\u0435\u0442 \u044d\u043a\u0441\u043f\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0430 \u0432 \u043c\u043e\u0434\u0443\u043b\u044c WebAssembly<\/p>\n<\/li>\n<li>\n<p>\u0412\u0445\u043e\u0434\u043d\u043e\u0439 \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442 \u0438\u043c\u0435\u0435\u0442 \u0442\u0438\u043f <code>&amp;[f32]<\/code>. \u041e\u0431\u0432\u044f\u0437\u043a\u0430, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u0442\u0441\u044f wasm-pack, \u0431\u0435\u0437 \u043f\u0440\u043e\u0431\u043b\u0435\u043c \u043a\u043e\u043d\u0432\u0435\u0440\u0442\u0438\u0440\u0443\u0435\u0442 \u0447\u0438\u0441\u043b\u043e\u0432\u044b\u0435 \u043c\u0430\u0441\u0441\u0438\u0432\u044b JavaScript \u0432 \u044d\u0442\u043e\u0442 \u0442\u0438\u043f<\/p>\n<\/li>\n<li>\n<p> \u0422\u0438\u043f \u0432\u044b\u0445\u043e\u0434\u043d\u044b\u0445 \u0434\u0430\u043d\u043d\u044b\u0445 <code>Array<\/code>. \u042d\u0442\u043e\u0442 \u0442\u0438\u043f \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0441\u043e\u0431\u043e\u0439 \u0447\u0442\u043e-\u0442\u043e \u0432\u0440\u043e\u0434\u0435 \u043e\u0431\u043e\u0431\u0449\u0451\u043d\u043d\u043e\u0433\u043e \u043c\u0430\u0441\u0441\u0438\u0432\u0430, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043c\u043e\u0436\u0435\u0442 \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0442\u044c \u0440\u0430\u0437\u043d\u044b\u0435 \u0434\u0430\u043d\u043d\u044b\u0435, \u0438 \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u0443\u0435\u0442\u0441\u044f \u0432 \u043c\u0430\u0441\u0441\u0438\u0432 JavaScript. \u041c\u044b \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u0443\u0435\u043c \u043c\u0430\u0441\u0441\u0438\u0432 \u0442\u0438\u043f\u0430 <code>Vec&lt;usize><\/code> \u0432 <code>Array<\/code> \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043a\u043e\u043c\u0430\u043d\u0434\u044b<\/p>\n<pre><code class=\"rust\">triangle_indices.into_iter().map(JsValue::from).collect();<\/code><\/pre>\n<\/li>\n<\/ul>\n<p>\u0414\u043b\u044f \u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u044d\u043a\u0441\u043f\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043a\u043b\u0430\u0441\u0441, \u043c\u044b \u0441\u043d\u0430\u0447\u0430\u043b\u0430 \u043e\u0431\u044a\u044f\u0432\u043b\u044f\u0435\u043c \u043e\u0431\u0451\u0440\u0442\u044b\u0432\u0430\u044e\u0449\u0443\u044e \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443<\/p>\n<pre><code class=\"rust\">#[wasm_bindgen(js_name = BVHNode)] pub struct BVHNodeWrapper {     bvh: BVHNode }<\/code><\/pre>\n<p>\u041e\u043d\u0430 \u043f\u043e\u043c\u0435\u0447\u0430\u0435\u0442\u0441\u044f \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u043e\u043c <code>#[wasm_bindgen]<\/code>, \u0443 \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u0443\u043a\u0430\u0437\u0430\u043d \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0439 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440 <code>js_name = BVHNode<\/code>. \u041e\u043d \u0437\u0430\u0434\u0430\u0451\u0442 \u0438\u043c\u044f \u043a\u043b\u0430\u0441\u0441\u0430 \u0432\u043d\u0443\u0442\u0440\u0438 \u043c\u043e\u0434\u0443\u043b\u044f.<\/p>\n<p>\u041f\u043e\u0442\u043e\u043c \u043e\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u043c \u043a\u0430\u043a \u0431\u0443\u0434\u0442\u043e \u0431\u044b \u043c\u0435\u0442\u043e\u0434\u044b \u044d\u043a\u0441\u043f\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0433\u043e \u043a\u043b\u0430\u0441\u0441\u0430<\/p>\n<pre><code class=\"rust\">#[wasm_bindgen(js_class = BVHNode)] impl BVHNodeWrapper { }<\/code><\/pre>\n<p>\u0421\u043d\u043e\u0432\u0430 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440 <code>js_class = BVHNode<\/code> \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u0430 <code>wasm_bindgen<\/code> \u0447\u0442\u043e\u0431\u044b \u0443\u043a\u0430\u0437\u0430\u0442\u044c \u0438\u043c\u044f \u043a\u043b\u0430\u0441\u0441\u0430, \u0434\u043b\u044f \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u0431\u0443\u0434\u0443\u0442 \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d\u044b \u043c\u0435\u0442\u043e\u0434\u044b. \u0412\u0441\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0442\u0441\u044f \u0432\u043d\u0443\u0442\u0440\u0438 \u043e\u0431\u043b\u0430\u0441\u0442\u0438 <code>impl<\/code> \u0431\u0443\u0434\u0443\u0442 \u044d\u043a\u0441\u043f\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u044b \u0432 \u043c\u043e\u0434\u0443\u043b\u044c. \u041a\u0430\u0436\u0434\u0443\u044e \u0438\u0437 \u043d\u0438\u0445 \u043f\u043e\u043c\u0435\u0447\u0430\u0442\u044c \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e \u043d\u0435 \u043d\u0430\u0434\u043e.<\/p>\n<p>\u0427\u0442\u043e\u0431\u044b \u043f\u043e\u043c\u0435\u0442\u0438\u0442\u044c \u043c\u0435\u0442\u043e\u0434 \u043a\u0430\u043a \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440 \u043a\u043b\u0430\u0441\u0441\u0430 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0430\u0442\u0440\u0438\u0431\u0443\u0442 <code>#[wasm_bindgen(constructor)]<\/code><\/p>\n<pre><code class=\"rust\">#[wasm_bindgen(constructor)] pub fn new(coordinates: &amp;[f32]) -> BVHNodeWrapper {     \/*...*\/ }<\/code><\/pre>\n<p>\u0414\u0430\u043b\u0435\u0435 \u0441\u0442\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0430\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u0432\u043c\u0435\u0441\u0442\u043e \u0432\u0442\u043e\u0440\u043e\u0433\u043e \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440\u0430 \u043a\u043b\u0430\u0441\u0441\u0430. \u0423 \u043d\u0435\u0451 \u043d\u0435\u0442 \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u0430 <code>&amp;self<\/code><\/p>\n<pre><code class=\"rust\">pub fn new_trianglulation(coordinates: &amp;[f32], triangles: &amp;[i32]) -> BVHNodeWrapper{     \/*...*\/ }<\/code><\/pre>\n<p>\u0418, \u043d\u0430\u043a\u043e\u043d\u0435\u0446, \u043c\u0435\u0442\u043e\u0434 \u0434\u043b\u044f \u043f\u043e\u0438\u0441\u043a\u0430 \u0442\u0440\u0435\u0443\u0433\u043e\u043b\u044c\u043d\u0438\u043a\u0430 \u043f\u043e \u0442\u043e\u0447\u043a\u0435. \u041e\u043d \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 <code>Array<\/code>, \u043a\u0430\u043a \u043c\u044b \u0443\u0436\u0435 \u0443\u043c\u0435\u0435\u043c \u0434\u0435\u043b\u0430\u0442\u044c<\/p>\n<pre><code class=\"rust\">pub fn sample(&amp;self, x: f32, y: f32) -> Array {     \/*...*\/ }<\/code><\/pre>\n<p>\u0412\u043e\u0442 \u0438 \u0432\u0441\u0451. \u0422\u0435\u043f\u0435\u0440\u044c \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u043c \u043a\u043e\u043c\u0430\u043d\u0434\u0443<\/p>\n<pre><code>wasm-pack build<\/code><\/pre>\n<p>\u0412 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0435 \u0432 \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u0438 <code>.\/pkg\/<\/code> \u0431\u0443\u0434\u0443\u0442 \u0441\u043e\u0437\u0434\u0430\u043d\u044b \u0432 \u0442\u043e\u043c \u0447\u0438\u0441\u043b\u0435 \u0434\u0432\u0430 \u0444\u0430\u0439\u043b\u0430: <code>delaunay.js<\/code> \u043e\u0431\u044a\u0451\u043c\u043e\u043c 7 \u043a\u0431 \u0438 <code>delaunay_bg.wasm<\/code> \u043e\u0431\u044a\u0451\u043c\u043e\u043c 31 \u043a\u0431. \u041f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e \u0441\u0440\u0430\u0437\u0443 \u0434\u0435\u043b\u0430\u0435\u0442\u0441\u044f \u0440\u0435\u043b\u0438\u0437\u043d\u044b\u0439 \u0431\u0438\u043b\u0434, \u0442\u0430\u043a \u0447\u0442\u043e \u043d\u0438\u043a\u0430\u043a\u0438\u0445 \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0445 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043e\u0432 \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0442\u044c \u043d\u0435 \u043d\u0430\u0434\u043e. \u0415\u0434\u0438\u043d\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0435, \u043c\u043e\u0436\u043d\u043e \u0443\u043a\u0430\u0437\u0430\u0442\u044c \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0439 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440 <code>--target nodejs<\/code>  \u0435\u0441\u043b\u0438 \u0445\u043e\u0447\u0435\u0442\u0441\u044f \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u043c\u043e\u0434\u0443\u043b\u044c \u0434\u043b\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u0432 NodeJS, \u0438 <code>--target web<\/code>, \u0435\u0441\u043b\u0438 \u0434\u043b\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u0432 \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u0435. \u0425\u043e\u0442\u044f, \u043a\u043e\u043d\u0435\u0447\u043d\u043e, \u0443 \u043a\u043e\u043c\u0430\u043d\u0434\u044b <code>wasm-pack<\/code> \u0435\u0441\u0442\u044c \u043c\u043d\u043e\u0433\u043e \u0434\u0440\u0443\u0433\u0438\u0445 \u043f\u043e\u043b\u0435\u0437\u043d\u044b\u0445 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043e\u0432 \u0438 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0435\u0439.<\/p>\n<h3>\u0418\u0442\u043e\u0433\u043e<\/h3>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u0443 \u043d\u0430\u0441 \u0435\u0441\u0442\u044c \u0442\u0440\u0438 \u043c\u043e\u0434\u0443\u043b\u044f WebAssembly, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0434\u0435\u043b\u0430\u044e\u0442 \u043e\u0434\u043d\u043e \u0438 \u0442\u043e \u0436\u0435, \u043d\u043e \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u044b \u0440\u0430\u0437\u043d\u044b\u043c\u0438 \u0441\u043f\u043e\u0441\u043e\u0431\u0430\u043c\u0438. \u0421\u0430\u043c\u043e\u0435 \u0432\u0440\u0435\u043c\u044f \u0438\u0445 \u0441\u0440\u0430\u0432\u043d\u0438\u0442\u044c.<\/p>\n<p>\u0414\u0438\u0430\u0433\u0440\u0430\u043c\u043c\u0430 \u0440\u0430\u0437\u043c\u0435\u0440\u043e\u0432 \u0441\u043a\u043e\u043c\u043f\u0438\u043b\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0445 <code>*.wasm<\/code> \u0444\u0430\u0439\u043b\u043e\u0432. \u0427\u0435\u043c \u043c\u0435\u043d\u044c\u0448\u0435 &#8212; \u0442\u0435\u043c \u043b\u0443\u0447\u0448\u0435.<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/a7d\/8ab\/831\/a7d8ab831183cf6f9bcde0630217cc18.png\" width=\"894\" height=\"662\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/a7d\/8ab\/831\/a7d8ab831183cf6f9bcde0630217cc18.png\"\/><figcaption><\/figcaption><\/figure>\n<p>\u041c\u044b \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u043b\u0438 \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u043e\u0439 \u0431\u0435\u043d\u0447\u043c\u0430\u0440\u043a \u0434\u043b\u044f \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u0431\u044b\u0441\u0442\u0440\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f \u043c\u043e\u0434\u0443\u043b\u0435\u0439 \u0432 \u0441\u0440\u0435\u0434\u0435 NodeJS. \u042d\u043a\u0441\u043f\u0435\u0440\u0438\u043c\u0435\u043d\u0442 \u0441\u043e\u0441\u0442\u043e\u044f\u043b \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e\u0431\u044b \u043d\u0430\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043a\u0443\u0447\u0443 \u0442\u043e\u0447\u0435\u043a, \u0430 \u043f\u043e\u0442\u043e\u043c \u043f\u043e\u043f\u0440\u043e\u0441\u0438\u0442\u044c \u0432\u0441\u0435 \u0442\u0440\u0438 \u043c\u043e\u0434\u0443\u043b\u044f \u043f\u043e\u0441\u0442\u0440\u043e\u0438\u0442\u044c \u0442\u0440\u0438\u0430\u043d\u0433\u0443\u043b\u044f\u0446\u0438\u0438 \u0434\u043b\u044f \u0440\u0430\u0437\u043d\u043e\u0433\u043e \u0447\u0438\u0441\u043b\u0430 \u0442\u043e\u0447\u0435\u043a. \u041d\u0443 \u0438 \u0437\u0430\u043c\u0435\u0440\u044f\u043b\u043e\u0441\u044c \u0432\u0440\u0435\u043c\u044f \u0432\u044b\u0437\u043e\u0432\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u043f\u043e\u0441\u0442\u0440\u043e\u0435\u043d\u0438\u044f \u0442\u0440\u0438\u0430\u043d\u0433\u0443\u043b\u044f\u0446\u0438\u0438. \u0412\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u0438\u0435 \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u0434\u0430\u043d\u043d\u044b\u0445 \u043c\u0435\u0436\u0434\u0443 JavaScript \u0438 \u043c\u043e\u0434\u0443\u043b\u0435\u043c \u0443\u0447\u0438\u0442\u044b\u0432\u0430\u043b\u0438\u0441\u044c.<\/p>\n<p>\u0412\u043e\u0442 \u0433\u0440\u0430\u0444\u0438\u043a \u0431\u044b\u0441\u0442\u0440\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f \u0434\u043b\u044f \u0440\u0430\u0437\u043d\u043e\u0433\u043e \u0447\u0438\u0441\u043b\u0430 \u0442\u043e\u0447\u0435\u043a. \u0427\u0435\u043c \u043c\u0435\u043d\u044c\u0448\u0435 &#8212; \u0442\u0435\u043c \u043b\u0443\u0447\u0448\u0435.<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/597\/55a\/f95\/59755af95706e61c9d56cd4b051f8f42.png\" width=\"1068\" height=\"653\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/597\/55a\/f95\/59755af95706e61c9d56cd4b051f8f42.png\"\/><figcaption><\/figcaption><\/figure>\n<p>\u0410 \u0432\u043e\u0442 \u0433\u0440\u0430\u0444\u0438\u043a \u0430\u043d\u0430\u043b\u043e\u0433\u0438\u0447\u043d\u043e\u0433\u043e \u044d\u043a\u0441\u043f\u0435\u0440\u0438\u043c\u0435\u043d\u0442\u0430, \u043d\u043e \u043f\u043e \u043f\u043e\u0441\u0442\u0440\u043e\u0435\u043d\u0438\u044e BVH \u0434\u043b\u044f \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u043e\u0433\u043e \u0447\u0438\u0441\u043b\u0430 \u0442\u043e\u0447\u0435\u043a. \u0421\u043d\u043e\u0432\u0430, \u0447\u0435\u043c \u043c\u0435\u043d\u044c\u0448\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 &#8212; \u0442\u0435\u043c \u043b\u0443\u0447\u0448\u0435.<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/0fe\/a8d\/a6e\/0fea8da6e151730b8207b30c2c605b28.png\" width=\"1044\" height=\"630\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/0fe\/a8d\/a6e\/0fea8da6e151730b8207b30c2c605b28.png\"\/><figcaption><\/figcaption><\/figure>\n<p>\u0412\u044b\u0432\u043e\u0434\u044b \u0442\u0430\u043a\u0438\u0435. AssemblyScript \u0445\u043e\u0440\u043e\u0448\u0438\u0439, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u0442 \u0441\u0430\u043c\u044b\u0439 \u043c\u0430\u043b\u0435\u043d\u044c\u043a\u0438\u0439 \u0440\u0430\u0437\u043c\u0435\u0440 \u043c\u043e\u0434\u0443\u043b\u044f, \u0438 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u043d\u0435 \u0442\u0430\u043a \u0447\u0442\u043e\u0431\u044b \u0443\u0436 \u0441\u0438\u043b\u044c\u043d\u043e \u043c\u0435\u0434\u043b\u0435\u043d\u043d\u0435\u0435 \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u044b\u0445. Rust \u0445\u043e\u0440\u043e\u0448\u0438\u0439, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u043f\u0443\u0441\u0442\u044c \u0440\u0430\u0437\u043c\u0435\u0440 \u0435\u0433\u043e \u043c\u043e\u0434\u0443\u043b\u044f \u0438 \u043d\u0435 \u0441\u0430\u043c\u044b\u0439 \u043c\u0430\u043b\u0435\u043d\u044c\u043a\u0438\u0439, \u0437\u0430\u0442\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0431\u044b\u0441\u0442\u0440\u0435\u0435 \u0432\u0441\u0435\u0445. Emscripten \u0442\u043e\u0436\u0435 \u043c\u043e\u043b\u043e\u0434\u0435\u0446.<\/p>\n<p>\u041c\u043d\u0435 \u0431\u043e\u043b\u044c\u0448\u0435 \u043d\u0440\u0430\u0432\u0438\u0442\u0441\u044f AssemblyScript, \u0442\u0430\u043a \u043a\u0430\u043a \u043e\u043d \u043a\u0430\u0436\u0435\u0442\u0441\u044f \u043a\u043e\u043d\u0446\u0435\u043f\u0442\u0443\u0430\u043b\u044c\u043d\u043e \u043f\u0440\u043e\u0449\u0435 \u043f\u043e \u0441\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u044e \u0441 Rust-\u043e\u043c.<\/p>\n<h3>\u0411\u043e\u043d\u0443\u0441 1: \u0434\u0435\u043c\u043e\u043d\u0441\u0442\u0440\u0430\u0446\u0438\u044f<\/h3>\n<p>\u0412 \u044d\u0442\u043e\u043c \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u043e\u043c \u0440\u0430\u0437\u0434\u0435\u043b\u0435 \u043f\u0440\u043e\u0434\u0435\u043c\u043e\u043d\u0441\u0442\u0440\u0438\u0440\u0443\u0435\u043c \u043a\u0430\u043a \u043c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043c\u043e\u0434\u0443\u043b\u044c, \u043e\u0442\u043a\u043e\u043c\u043f\u0438\u043b\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u0438\u0437 Rust-\u0430, \u0432 \u043c\u0430\u043b\u0435\u043d\u044c\u043a\u043e\u043c \u0432\u0440\u043e\u0434\u0435 \u043a\u0430\u043a web-\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0438. \u042d\u0442\u043e web-\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0434\u0435\u043b\u0430\u0435\u0442 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0435:<\/p>\n<ul>\n<li>\n<p>\u041f\u043e \u043d\u0430\u0436\u0430\u0442\u0438\u044e \u043a\u043d\u043e\u043f\u043a\u0438 \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u0442 \u0441\u043b\u0443\u0447\u0430\u0439\u043d\u044b\u0439 \u043d\u0430\u0431\u043e\u0440 \u0442\u043e\u0447\u0435\u043a \u043d\u0430 \u043f\u043b\u043e\u0441\u043a\u043e\u0441\u0442\u0438<\/p>\n<\/li>\n<li>\n<p>\u0421\u0442\u0440\u043e\u0438\u0442 \u0442\u0440\u0438\u0430\u043d\u0433\u0443\u043b\u044f\u0446\u0438\u044e \u043f\u043e \u043f\u043e\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u044b\u043c \u0442\u043e\u0447\u043a\u0430\u043c \u0438 \u0432\u044b\u0432\u043e\u0434\u0438\u0442 \u0435\u0451 \u043d\u0430 \u044d\u043a\u0440\u0430\u043d<\/p>\n<\/li>\n<li>\n<p>\u041f\u0440\u0438 \u043f\u0435\u0440\u0435\u043c\u0435\u0449\u0435\u043d\u0438\u0438 \u0443\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u044f \u043c\u0430\u043d\u0438\u043f\u0443\u043b\u044f\u0442\u043e\u0440\u0430 \u0442\u0438\u043f\u0430 &#171;\u043c\u044b\u0448\u044c&#187; \u0437\u0430\u043a\u0440\u0430\u0448\u0438\u0432\u0430\u0435\u0442 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u043c \u0446\u0432\u0435\u0442\u043e\u043c \u0442\u043e\u0442 \u0442\u0440\u0435\u0443\u0433\u043e\u043b\u044c\u043d\u0438\u043a, \u043d\u0430\u0434 \u043a\u043e\u0442\u043e\u0440\u044b\u043c \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u0443\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u044c<\/p>\n<\/li>\n<\/ul>\n<p>\u0412\u043e\u0442 \u043c\u0430\u043b\u0435\u043d\u044c\u043a\u0430\u044f \u0433\u0438\u0444\u043a\u0430 \u0441 \u0434\u0435\u043c\u043e\u043d\u0441\u0442\u0440\u0430\u0446\u0438\u0435\u0439<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/d1b\/91a\/569\/d1b91a5695bbcff356c315be9d8fcdd9.gif\" width=\"778\" height=\"686\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/d1b\/91a\/569\/d1b91a5695bbcff356c315be9d8fcdd9.gif\"\/><figcaption><\/figcaption><\/figure>\n<p>\u0410 \u0432\u043e\u0442 <a href=\"https:\/\/tugcga.github.io\/web_apps\/delaunay_demo\/\" rel=\"noopener noreferrer nofollow\">\u0441\u0441\u044b\u043b\u043a\u0430<\/a> \u043d\u0430 \u0441\u0430\u043c\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435.<\/p>\n<p>\u0422\u0430\u043a \u043a\u0430\u043a \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u043c\u0430\u043b\u0435\u043d\u044c\u043a\u043e\u0435, \u0442\u043e \u043d\u0435\u0442 \u0440\u0435\u0437\u043e\u043d\u0443 \u0440\u0430\u0437\u0431\u0438\u0432\u0430\u0442\u044c \u0435\u0433\u043e \u043d\u0430 \u043c\u043d\u043e\u0433\u043e \u0444\u0430\u0439\u043b\u043e\u0432 \u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0448\u0438\u0440\u043e\u043a\u0438\u0439 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0439 web-\u0442\u0435\u0445\u043d\u043e\u043b\u043e\u0433\u0438\u0439. \u041d\u0430\u043f\u0438\u0448\u0435\u043c \u0432\u0441\u0451 \u043f\u043e-\u043f\u0440\u043e\u0441\u0442\u043e\u043c\u0443 \u0432 \u043e\u0434\u043d\u043e\u043c html \u0444\u0430\u0439\u043b\u0435.<\/p>\n<details class=\"spoiler\">\n<summary>index.html<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"typescript\">&lt;!DOCTYPE html> &lt;html>     &lt;head>         &lt;meta charset=\"UTF-8\">         &lt;title>Delaunay Demo&lt;\/title>         &lt;style>             body, html {                 height: 100%;                 width: 100%;                 padding: 0px;                 margin: 0px;                 background-color: rgb(40, 40, 40);             }                          div#central_div {                 position: relative;                 width: 100%;                 height: 100%;             }                          .points_button {                 width: 80px;                 height: 35px;                 border: none;                 border-radius: 10px;                 font-size: 14px;                 font-weight: bold;                 position: absolute;                 top: 10px;             }                          .points_button#btn_0 {                 left: 10px;             }                          .points_button#btn_1 {                 left: 100px;             }                          .points_button#btn_2 {                 left: 190px;             }                          .points_button#btn_3 {                 left: 280px;             }         &lt;\/style>     &lt;\/head>     &lt;body>         &lt;div id=\"central_div\">             &lt;button class=\"points_button\" id=\"btn_0\" onclick=\"generate(10)\">10&lt;\/button>             &lt;button class=\"points_button\" id=\"btn_1\" onclick=\"generate(100)\">100&lt;\/button>             &lt;button class=\"points_button\" id=\"btn_2\" onclick=\"generate(1000)\">1000&lt;\/button>             &lt;button class=\"points_button\" id=\"btn_3\"onclick=\"generate(12000)\">12000&lt;\/button>             &lt;canvas id=\"canvas\">&lt;\/canvas>         &lt;\/div>         &lt;script type=\"module\">             import init, { BVHNode, build_triangulation } from \".\/delaunay.js\";              async function wasm_run() {                 await init();                  const canvas = document.getElementById(\"canvas\");                 const ctx = canvas.getContext(\"2d\");                  var canvas_width = document.body.clientWidth;                 var canvas_height = document.body.clientHeight - 3;                  var points = [];                 var triangles = [];                 var bvh = undefined;                 var cursor_position = [0, 0];                 var sample_coordinates = [];                  function draw_canvas() {                     ctx.clearRect(0, 0, canvas_width, canvas_height);                     ctx.save();                     ctx.fillStyle = \"rgb(40, 40, 40)\";                     ctx.fillRect(0, 0, canvas_width, canvas_height);                     ctx.restore();                      if(sample_coordinates.length == 6) {                         ctx.save();                         ctx.beginPath();                         ctx.fillStyle = \"rgb(143, 186, 173)\";                         ctx.strokeStyle = \"rgb(143, 186, 173)\";                         ctx.moveTo(sample_coordinates[0], sample_coordinates[1]);                         ctx.lineTo(sample_coordinates[2], sample_coordinates[3]);                         ctx.lineTo(sample_coordinates[4], sample_coordinates[5]);                         ctx.lineTo(sample_coordinates[0], sample_coordinates[1]);                         ctx.fill();                         ctx.restore();                     }                      ctx.save();                     ctx.fillStyle = \"rgb(129, 129, 129)\";                     const points_count = points.length \/ 2;                     for(let i = 0; i &lt; points_count; i++) {                         const x = points[2*i];                         const y = points[2*i + 1];                         ctx.beginPath();                         ctx.arc(x, y, 2, 0, 2 * Math.PI);                         ctx.fill();                     }                     ctx.restore();                      ctx.save();                     ctx.strokeStyle = \"rgb(129, 129, 129)\";                     const triangles_count = triangles.length \/ 3;                     for(let i = 0; i &lt; triangles_count; i++) {                         ctx.beginPath();                         const a = triangles[3*i]; const a_x = points[2*a]; const a_y = points[2*a + 1];                         const b = triangles[3*i + 1]; const b_x = points[2*b]; const b_y = points[2*b + 1];                         const c = triangles[3*i + 2]; const c_x = points[2*c]; const c_y = points[2*c + 1];                         ctx.moveTo(a_x, a_y);                         ctx.lineTo(b_x, b_y);                         ctx.lineTo(c_x, c_y);                         ctx.lineTo(a_x, a_y);                         ctx.stroke();                     }                     ctx.restore();                 }                  function update_canvas() {                     canvas_width = document.body.clientWidth;                     canvas_height = document.body.clientHeight - 3;                      canvas.width = canvas_width;                     canvas.height = canvas_height;                      draw_canvas();                 }                  onresize = (event) => {                     update_canvas();                 };                 onmousemove = (event) => {                     var rect = canvas.getBoundingClientRect();                     cursor_position[0] = event.clientX - rect.left;                     cursor_position[1] = event.clientY - rect.top;                      if(bvh) {                         sample_coordinates = bvh.sample(cursor_position[0], cursor_position[1]);                     }                      draw_canvas();                 };                  update_canvas();                  generate(10);                  function generate(n) {                     const x_min = 10;                     const y_min = 10;                     const x_max = canvas_width - 10;                     const y_max = canvas_height - 10;                      points = []                      for(let i = 0; i &lt; n; i++) {                         const x = Math.random() * (x_max - x_min) + x_min;                         const y = Math.random() * (y_max - y_min) + y_min;                          points.push(x, y);                     }                      triangles = build_triangulation(points);                     bvh = new BVHNode(points, triangles);                      draw_canvas();                 }                  window.generate = generate;             };              wasm_run();         &lt;\/script>     &lt;\/body> &lt;\/html><\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u0422\u0443\u0442 \u0441\u0442\u043e\u0438\u0442 \u043e\u0442\u043c\u0435\u0442\u0438\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u043e\u0434\u043d\u043e &#8212; \u043a\u0430\u043a \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0430\u0442\u044c \u043c\u043e\u0434\u0443\u043b\u044c \u043f\u0440\u0438 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0435 web-\u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b.<\/p>\n<p>\u0421\u043e\u0437\u0434\u0430\u0451\u043c<\/p>\n<pre><code class=\"typescript\">&lt;script type=\"module\"> &lt;\/script><\/code><\/pre>\n<p>\u0412\u043d\u0443\u0442\u0440\u0438 \u043d\u0435\u0433\u043e \u043f\u0438\u0448\u0435\u043c<\/p>\n<pre><code class=\"typescript\">import init, { BVHNode, build_triangulation } from \".\/delaunay.js\";  async function wasm_run() {     await init();     \/*...*\/ }<\/code><\/pre>\n<p>\u041f\u043e\u0441\u043b\u0435 \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0438\u044f \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u043e\u0433\u043e \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f <code>init()<\/code> \u043c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u043c\u043e\u0434\u0443\u043b\u044f.<\/p>\n<h3>\u0411\u043e\u043d\u0443\u0441 2: \u0438\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u044f \u0432 Python<\/h3>\n<p>\u041e\u0431\u0432\u0435\u0441, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u0442 Rust, \u043d\u0430\u0441\u0442\u043e\u043b\u044c\u043a\u043e \u0447\u0438\u0442\u0430\u0431\u0435\u043b\u044c\u043d\u044b\u0439, \u0447\u0442\u043e \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u043f\u0440\u043e\u0431\u043e\u0432\u0430\u0442\u044c \u043f\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0435\u0433\u043e \u043d\u0430 Python. \u042d\u0442\u043e \u043f\u043e\u0437\u0432\u043e\u043b\u0438\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c WebAssembly \u043c\u043e\u0434\u0443\u043b\u044c \u0438\u0437 Python.<\/p>\n<p>\u0415\u0441\u0442\u044c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043c\u043e\u0434\u0443\u043b\u0435\u0439 \u0434\u043b\u044f Python, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u044e\u0442 \u0437\u0430\u0433\u0440\u0443\u0436\u0430\u0442\u044c \u043c\u043e\u0434\u0443\u043b\u0438 WebAssembly. \u0412\u0441\u0435 \u043e\u043d\u0438 \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u044e\u0442 \u043d\u0438\u0437\u043a\u043e\u0443\u0440\u043e\u0432\u043d\u0435\u0432\u044b\u0439 \u0434\u043e\u0441\u0442\u0443\u043f \u0432 \u0442\u043e\u043c \u0447\u0438\u0441\u043b\u0435 \u043a \u0444\u0443\u043d\u043a\u0446\u0438\u044f\u043c, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u044d\u043a\u0441\u043f\u043e\u0440\u0442\u0438\u0440\u0443\u044e\u0442\u0441\u044f \u0438\u0437 \u043c\u043e\u0434\u0443\u043b\u044f, \u0438 \u043a \u043f\u0430\u043c\u044f\u0442\u0438. \u0410 \u0431\u043e\u043b\u044c\u0448\u0435 \u043d\u0430\u043c \u043d\u0438\u0447\u0435\u0433\u043e \u0438 \u043d\u0435 \u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f. \u0411\u0443\u0434\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c Wasmer.<\/p>\n<pre><code>pip isntall wasmer<\/code><\/pre>\n<p>\u041f\u0440\u0435\u0436\u0434\u0435 \u0447\u0435\u043c \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0438\u0442 \u043a \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0438\u044e \u043a\u043e\u0434\u0430, \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u043f\u043e\u0432\u043d\u0438\u043c\u0430\u0442\u0435\u043b\u044c\u043d\u0435\u0435 \u043d\u0430 \u043c\u043e\u0434\u0443\u043b\u044c, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043e\u0442\u043a\u043e\u043c\u043f\u0438\u043b\u0438\u0440\u043e\u0432\u0430\u043b Rust. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0435\u0433\u043e \u043d\u0430\u0434\u043e \u043b\u044e\u0431\u043e\u0439 \u043f\u043e\u0434\u0445\u043e\u0434\u044f\u0449\u0435\u0439 \u0443\u0442\u0438\u043b\u0438\u0442\u043e\u0439 \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u0442\u044c \u0432 \u0442\u0435\u043a\u0441\u0442\u043e\u0432\u044b\u0439 \u0444\u043e\u0440\u043c\u0430\u0442. \u0410 \u043c\u043e\u0436\u043d\u043e \u0434\u0430\u0436\u0435 \u0438 \u043d\u0435 \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u044b\u0432\u0430\u0442\u044c, \u044f \u0441\u0430\u043c \u044d\u0442\u043e \u0441\u0434\u0435\u043b\u0430\u044e. \u0412 \u043e\u0431\u0449\u0435\u043c \u0442\u0430\u043c \u0431\u0443\u0434\u0435\u0442 \u043c\u043d\u043e\u0433\u043e \u0441\u0442\u0440\u043e\u0447\u0435\u043a, \u043d\u043e \u043d\u0430\u043c \u043d\u0430\u0434\u043e \u0434\u0432\u0430 \u0444\u0440\u0430\u0433\u043c\u0435\u043d\u0442\u0430: \u043f\u043e\u0447\u0442\u0438 \u0432 \u0441\u0430\u043c\u043e\u043c \u043d\u0430\u0447\u0430\u043b\u0435 \u0438 \u043f\u043e\u0447\u0442\u0438 \u0432 \u0441\u0430\u043c\u043e\u043c \u043a\u043e\u043d\u0446\u0435:<\/p>\n<pre><code>(import \"wbg\" \"__wbindgen_number_new\" (func (;0;) (type 23))) (import \"wbg\" \"__wbindgen_object_drop_ref\" (func (;1;) (type 5))) (import \"wbg\" \"__wbg_new_b525de17f44a8943\" (func (;2;) (type 11))) (import \"wbg\" \"__wbg_newwithlength_0da6f12fbc1ab6eb\" (func (;3;) (type 3))) (import \"wbg\" \"__wbg_set_17224bc548dd1d7b\" (func (;4;) (type 2))) (import \"wbg\" \"__wbg_push_49c286f04dd3bf59\" (func (;5;) (type 1))) (import \"wbg\" \"__wbindgen_throw\" (func (;6;) (type 0)))  (export \"build_triangulation\" (func 68)) (export \"wbg_bvhnode_free\" (func 43)) (export \"bvhnode_new\" (func 52)) (export \"bvhnode_new_trianglulation\" (func 48)) (export \"bvhnode_sample\" (func 55)) (export \"__wbindgen_malloc\" (func 63))<\/code><\/pre>\n<p>\u041f\u043e\u0441\u043b\u0435 \u043a\u043b\u044e\u0447\u0435\u0432\u043e\u0433\u043e \u0441\u043b\u043e\u0432\u0430 <code>import<\/code> \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u044b \u0438\u043c\u0435\u043d\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u0439, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0434\u043e\u043b\u0436\u043d\u044b \u0431\u044b\u0442\u044c \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d\u044b \u0432 Python \u0438 \u043f\u0435\u0440\u0435\u0434\u0430\u043d\u044b \u0432 \u043c\u043e\u0434\u0443\u043b\u044c. \u041f\u043e\u0441\u043b\u0435 \u0441\u043b\u043e\u0432\u0430 <code>export<\/code> \u043d\u0430\u043e\u0431\u043e\u0440\u043e\u0442 \u0443\u043a\u0430\u0437\u0430\u043d\u044b \u0438\u043c\u0435\u043d\u0430 \u0442\u0435\u0445 \u0444\u0443\u043d\u043a\u0446\u0438\u0439, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043c\u043e\u0436\u043d\u043e \u0432\u044b\u0437\u044b\u0432\u0430\u0442\u044c \u0438\u0437 \u043c\u043e\u0434\u0443\u043b\u044f.<\/p>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u0441\u043e\u0437\u0434\u0430\u0451\u043c \u0444\u0430\u0439\u043b <code>delaunay_wasm.py<\/code> \u0438 \u043f\u0438\u0448\u0435\u043c \u0432 \u043d\u0451\u043c \u0437\u0430\u0433\u043e\u0442\u043e\u0432\u043a\u0443 \u0434\u043b\u044f \u043a\u043b\u0430\u0441\u0441\u0430 \u0437\u0430\u0433\u0440\u0443\u0437\u0447\u0438\u043a\u0430<\/p>\n<pre><code class=\"python\">from wasmer import Store, Module, Instance, ImportObject, Function  class Loader:     def __init__(self, wasm_path: str):         pass<\/code><\/pre>\n<p>\u0415\u0434\u0438\u043d\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0439 \u0432\u0445\u043e\u0434\u043d\u043e\u0439 \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442 \u0434\u043b\u044f \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440\u0430 &#8212; \u043f\u0443\u0442\u044c \u0434\u043e \u0444\u0430\u0439\u043b\u0430 <code>*.wasm<\/code>.<\/p>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u0441\u043e\u0437\u0434\u0430\u0451\u043c \u0438\u043d\u0441\u0442\u0430\u043d\u0441 WebAssembly \u043c\u043e\u0434\u0443\u043b\u044f \u0438 \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u043c \u0435\u0433\u043e \u0432 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0443\u044e <code>self._wasm<\/code><\/p>\n<pre><code class=\"python\">class Loader:     def __init__(self, wasm_path):         store = Store()         module = Module(store, open(wasm_path, \"rb\").read())         imports = ImportObject()         self._wasm = Instance(module, imports)<\/code><\/pre>\n<p>\u042d\u0442\u043e\u0442 \u043a\u043e\u0434 \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u043d\u0435 \u0431\u0443\u0434\u0435\u0442, \u0442\u0430\u043a \u043a\u0430\u043a \u0432 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0439 <code>imports<\/code> \u043d\u0435 \u043f\u0440\u043e\u043f\u0438\u0441\u0430\u043d\u044b \u0438\u043c\u043f\u043e\u0440\u0442\u044b, \u043a\u043e\u0438\u0445 \u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u0430\u0436 \u0441\u0435\u043c\u044c \u0448\u0442\u0443\u043a. \u041e\u0441\u0442\u0430\u0432\u0438\u043c \u044d\u0442\u043e \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u043d\u0430 \u043f\u043e\u0442\u043e\u043c, \u0442\u0430\u043a \u043a\u0430\u043a \u043d\u0430\u043c \u043d\u0430\u0434\u043e \u0441\u043d\u0430\u0447\u0430\u043b\u0430 \u043f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u0438\u0442\u044c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0445 \u0444\u0443\u043d\u043a\u0446\u0438\u0439, \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u044e\u0449\u0438\u0445 \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u0442\u0440\u0435\u0431\u0443\u0435\u043c\u044b\u0435 \u0438\u043c\u043f\u043e\u0440\u0442\u044b.<\/p>\n<p>\u041d\u043e \u043f\u0435\u0440\u0435\u0434 \u044d\u0442\u0438\u043c \u0441\u0434\u0435\u043b\u0430\u0435\u043c \u0435\u0449\u0451 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0432\u0435\u0449\u0435\u0439. \u041f\u0435\u0440\u0432\u043e\u0435 &#8212; \u0441\u043e\u0445\u0440\u0430\u043d\u0438\u043c \u0441\u0441\u044b\u043b\u043a\u0438 \u043d\u0430 \u0434\u043e\u0441\u0442\u0443\u043f \u043a \u043f\u0430\u043c\u044f\u0442\u0438 \u043c\u043e\u0434\u0443\u043b\u044f<\/p>\n<pre><code class=\"python\">wasm_exports = self._wasm.exports wasm_memory = wasm_exports.memory self._float32_memory = wasm_memory.float32_view() self._uint32_memory = wasm_memory.uint32_view()<\/code><\/pre>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c <code>self._uint32_memory<\/code> \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0441\u043e\u0431\u043e\u0439 \u0441\u0441\u044b\u043b\u043a\u0443 \u043d\u0430 \u043e\u0434\u0438\u043d \u0431\u043e\u043b\u044c\u0448\u043e\u0439 \u043c\u0430\u0441\u0441\u0438\u0432, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0438\u043d\u0442\u0435\u0440\u043f\u0440\u0435\u0442\u0438\u0440\u0443\u0435\u0442 \u043f\u0430\u043c\u044f\u0442\u044c \u043c\u043e\u0434\u0443\u043b\u044f \u043a\u0430\u043a \u043d\u0430\u0431\u043e\u0440 32-\u0431\u0438\u0442\u043d\u044b\u0445 \u0447\u0438\u0441\u0435\u043b. \u0410\u043d\u0430\u043b\u043e\u0433\u0438\u0447\u043d\u044b\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c <code>self._float32_memory<\/code> \u0438\u043d\u0442\u0435\u0440\u043f\u0440\u0435\u0442\u0438\u0440\u0443\u0435\u0442 \u043f\u0430\u043c\u044f\u0442\u044c \u043c\u043e\u0434\u0443\u043b\u044f \u043a\u0430\u043a \u043c\u0430\u0441\u0441\u0438\u0432 32-\u0431\u0438\u0442\u043d\u044b\u0445 \u0447\u0438\u0441\u0435\u043b \u0441 \u043f\u043b\u0430\u0432\u0430\u044e\u0449\u0435\u0439 \u0442\u043e\u0447\u043a\u043e\u0439.<\/p>\n<p>\u0412\u0442\u043e\u0440\u043e\u0435 &#8212; \u0441\u043e\u0445\u0440\u0430\u043d\u0438\u043c \u0432 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0435 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 \u0441\u0441\u044b\u043b\u043a\u0438 \u043d\u0430 \u0432\u0441\u0435 \u043d\u0443\u0436\u043d\u044b\u0435 \u043d\u0430\u043c \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438. \u0417\u043d\u0430\u0447\u0435\u043d\u0438\u0435 <code>wasm_exports<\/code> \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0438\u0442\u0435\u0440\u0430\u0442\u043e\u0440\u043e\u043c \u043f\u043e \u043a\u043e\u0442\u043e\u0440\u043e\u043c\u0443 \u043c\u043e\u0436\u043d\u043e \u043f\u0440\u043e\u0438\u0442\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u0438 \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u043f\u0430\u0440\u044b <code>(\u0438\u043c\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u0438, \u0444\u0443\u043d\u043a\u0446\u0438\u044f)<\/code><\/p>\n<pre><code class=\"python\">for e in wasm_exports:     export_name = e[0]     export_function = e[1]     if export_name == \"build_triangulation\":         self._build_triangulation = export_function     elif export_name == \"bvhnode_new\":         self._new_bvh = export_function     elif export_name == \"bvhnode_new_trianglulation\":         self._new_bvh_triangulation = export_function     elif export_name == \"bvhnode_sample\":         self._bvh_sample = export_function     if export_name == \"__wbindgen_malloc\":         self._malloc = export_function     elif export_name == \"__wbg_bvhnode_free\":         self._bvh_free = export_function<\/code><\/pre>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043c\u043e\u0436\u043d\u043e \u043d\u0430\u0447\u0438\u043d\u0430\u0442\u044c \u043f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u043a\u0443 \u043a \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0438\u043c\u043f\u043e\u0440\u0442\u043e\u0432. \u0421\u043e\u0437\u0434\u0430\u0451\u043c \u0432 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440\u0435 \u043d\u0430\u0448\u0435\u0433\u043e \u043a\u043b\u0430\u0441\u0441\u0430 \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435<\/p>\n<pre><code class=\"python\">self._heap = [None] * 128 self._heap.extend([None, None, True, False]) self._heap_next = len(self._heap) self._wasm_vector_len = 0<\/code><\/pre>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043f\u0438\u0448\u0435\u043c \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e \u0448\u0435\u0441\u0442\u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u0439: <code>_add_heap_object<\/code>, <code>_get_object<\/code>, <code>_drop_object<\/code>, <code>_take_object<\/code>, <code>_pass_array_f32_to_wasm<\/code> \u0438 <code>_pass_array_32_to_wasm<\/code><\/p>\n<pre><code class=\"python\">def _add_heap_object(self, obj: int) -> int:     if self._heap_next == len(self._heap):         self._heap.append(len(self._heap) + 1)      idx = self._heap_next     self._heap_next = self._heap[idx]     self._heap[idx] = obj      return idx  def _get_object(self, idx: int) -> int:     return self._heap[idx]  def _drop_object(self, idx: int):     if idx &lt; 132:         return None      self._heap[idx] = self._heap_next     self._heap_next = idx  def _take_object(self, idx: int):     ret: int = self._get_object(idx)     self._drop_object(idx)     return ret  def _pass_array_f32_to_wasm(self, arg) -> int:     ptr = self._malloc(len(arg) * 4)     for i in range(len(arg)):         self._float32_memory[ptr \/\/ 4 + i] = arg[i]     self._wasm_vector_len = len(arg)     return ptr  def _pass_array_32_to_wasm(self, arg) -> int:     ptr: int = self._malloc(len(arg) * 4)     for i in range(len(arg)):         self._uint32_memory[ptr \/\/ 4 + i] = arg[i]     self._wasm_vector_len = len(arg)     return ptr<\/code><\/pre>\n<p>\u042d\u0442\u0438 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 &#8212; \u043f\u043e\u0447\u0442\u0438 \u0447\u0442\u043e \u0434\u043e\u0441\u043b\u043e\u0432\u043d\u044b\u0439 \u043f\u043e\u0440\u0442 \u0430\u043d\u0430\u043b\u043e\u0433\u0438\u0447\u043d\u044b\u0445 \u0444\u0443\u043d\u043a\u0446\u0438\u0439 \u0438\u0437 \u043e\u0431\u0432\u044f\u0437\u043a\u0438, \u043a\u043e\u0442\u043e\u0440\u0443\u044e \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u0442 Rust.<\/p>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0434\u043b\u044f \u0438\u043c\u043f\u043e\u0440\u0442\u043e\u0432<\/p>\n<pre><code class=\"python\">def _import_number_new(self, arg: \"f64\") -> int:     return self._add_heap_object(arg)  def _import_drop_ref(self, arg: int):     self._take_object(arg)  def _import_new(self) -> int:     return self._add_heap_object([])  def _import_new_with_length(self, arg: int) -> int:     return self._add_heap_object([None] * arg)  def _import_set(self, arg0: int, arg1: int, arg2: int):     self._get_object(arg0)[arg1] = self._take_object(arg2)  def _import_push(self, arg0: int, arg1: int) -> int:     self._get_object(arg0).append(self._get_object(arg1))     return len(self._heap)  def _import_throw(self, arg0: int, arg1: int):     return \"something wrong\"<\/code><\/pre>\n<p>\u0423 \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u043e\u0432 \u044d\u0442\u0438\u0445 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u0434\u043e\u043b\u0436\u043d\u044b \u0431\u044b\u0442\u044c \u0430\u043d\u043d\u043e\u0442\u0430\u0446\u0438\u0438 \u0442\u0438\u043f\u043e\u0432, \u0432 \u043f\u0440\u043e\u0442\u0438\u0432\u043d\u043e\u043c \u0436\u0435 \u0441\u043b\u0443\u0447\u0430\u0435 Wasmer \u0431\u0443\u0434\u0435\u0442 \u0440\u0443\u0433\u0430\u0442\u044c\u0441\u044f. \u0418 \u0435\u0449\u0451 \u0441\u0442\u043e\u0438\u0442 \u043e\u0442\u043c\u0435\u0442\u0438\u0442\u044c, \u0447\u0442\u043e \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442 \u0441\u0430\u043c\u043e\u0439 \u043f\u0435\u0440\u0432\u043e\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0438\u043c\u043f\u043e\u0440\u0442\u0430 <code>_import_number_new<\/code> \u0434\u043e\u043b\u0436\u0435\u043d \u0431\u044b\u0442\u044c \u0442\u0438\u043f\u0430 <code>f64<\/code>. \u041c\u044b \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c \u0435\u0433\u043e \u044f\u0432\u043d\u043e \u0432 \u0432\u0438\u0434\u0435 \u0441\u0442\u0440\u043e\u043a\u0438, \u0442\u0430\u043a \u043a\u0430\u043a \u0442\u0438\u043f <code>float<\/code> \u0438\u043d\u0442\u0435\u0440\u043f\u0440\u0435\u0442\u0438\u0440\u0443\u0435\u0442\u0441\u044f Wasmer-\u043e\u043c \u043a\u0430\u043a <code>f32<\/code>.<\/p>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0430\u0435\u043c \u044d\u0442\u0438 \u0438\u043c\u043f\u043e\u0440\u0442\u044b \u043a \u043c\u043e\u0434\u0443\u043b\u044e. \u0412 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440\u0435 \u0437\u0430\u0433\u0440\u0443\u0437\u0447\u0438\u043a\u0430 \u043f\u0438\u0448\u0435\u043c<\/p>\n<pre><code class=\"python\">imports.register(\"wbg\", {     \"__wbindgen_number_new\": Function(store, self._import_number_new),     \"__wbindgen_object_drop_ref\": Function(store, self._import_drop_ref),     \"__wbg_new_b525de17f44a8943\": Function(store, self._import_new),     \"__wbg_newwithlength_0da6f12fbc1ab6eb\": Function(store, self._import_new_with_length),     \"__wbg_set_17224bc548dd1d7b\": Function(store, self._import_set),     \"__wbg_push_49c286f04dd3bf59\": Function(store, self._import_push),     \"__wbindgen_throw\": Function(store, self._import_throw), })<\/code><\/pre>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u0432\u0441\u0451 \u0434\u043e\u043b\u0436\u043d\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0431\u0435\u0437 \u043e\u0448\u0438\u0431\u043e\u043a. \u041d\u0443 \u043a\u0430\u043a \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c &#8212; \u0435\u0441\u043b\u0438 \u0432 \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u0439 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0435 \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c<\/p>\n<pre><code class=\"python\">loader = Loader(\"delaunay_bg.wasm\")<\/code><\/pre>\n<p>\u0442\u043e \u0432\u0441\u0451 \u0434\u043e\u043b\u0436\u043d\u043e \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u044c\u0441\u044f \u0431\u0435\u0437 \u043e\u0448\u0438\u0431\u043e\u043a. \u0425\u043e\u0442\u044f, \u043a\u043e\u043d\u0435\u0447\u043d\u043e, \u043f\u043e\u043a\u0430 \u043d\u0438\u0447\u0435\u0433\u043e, \u043a\u0440\u043e\u043c\u0435 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u043c\u043e\u0434\u0443\u043b\u044f,  \u0438 \u043d\u0435 \u0434\u0435\u043b\u0430\u0435\u0442\u0441\u044f<\/p>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u0432\u0440\u0435\u043c\u044f \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u0432\u043d\u0443\u0442\u0440\u0438 \u043a\u043b\u0430\u0441\u0441\u0430 <code>Loader<\/code> \u0432\u044b\u0437\u043e\u0432 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0434\u043b\u044f \u043f\u043e\u0441\u0442\u0440\u043e\u0435\u043d\u0438\u044f \u0442\u0440\u0438\u0430\u043d\u0433\u0443\u043b\u044f\u0446\u0438\u0438<\/p>\n<pre><code class=\"python\">def build_triangulation(self, coordinates: list[float]) -> list[int]:     ptr = self._pass_array_f32_to_wasm(coordinates)     length = self._wasm_vector_len     ret = self._build_triangulation(ptr, length)     array = self._take_object(ret)     return [int(v) for v in array]<\/code><\/pre>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u0441\u0434\u0435\u043b\u0430\u0435\u043c \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0439 \u043a\u043b\u0430\u0441\u0441 <code>BVHNode<\/code><\/p>\n<pre><code class=\"python\">class BVHNode:     def __init__(self, loader, coordinates: list[float], triangles=None):         self._loader = loader         if triangles is None:             ptr = loader._pass_array_f32_to_wasm(coordinates)             length = loader._wasm_vector_len             self._ptr = loader._new_bvh(ptr, length)         else:             ptr_0 = loader._pass_array_f32_to_wasm(coordinates)             length_0 = loader._wasm_vector_len             ptr_1 = loader._pass_array_32_to_wasm(triangles)             length_1 = loader._wasm_vector_len             self._ptr = loader._new_bvh_triangulation(ptr_0, length_0, ptr_1, length_1)      def __del__(self):         self._loader._bvh_free(self._ptr)      def sample(self, x:float, y: float) -> list[float]:         return self._loader._take_object(self._loader._bvh_sample(self._ptr, x, y))<\/code><\/pre>\n<p>\u041a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440 \u044d\u0442\u043e\u0433\u043e \u043a\u043b\u0430\u0441\u0441\u0430 \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442 \u0441\u0441\u044b\u043b\u043a\u0443 \u043d\u0430 \u043e\u0431\u044a\u0435\u043a\u0442 \u0437\u0430\u0433\u0440\u0443\u0437\u0447\u0438\u043a\u0430 \u0438 \u0434\u0432\u0430 \u043c\u0430\u0441\u0441\u0438\u0432\u0430. \u0417\u0430\u0433\u0440\u0443\u0437\u0447\u0438\u043a \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0434\u043b\u044f \u0432\u044b\u0437\u043e\u0432\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u0439 \u043c\u043e\u0434\u0443\u043b\u044f. \u041f\u0440\u0438 \u044d\u0442\u043e\u043c \u0435\u0441\u043b\u0438 \u0443\u043a\u0430\u0437\u0430\u043d\u044b \u043e\u0431\u0430 \u0432\u0445\u043e\u0434\u043d\u044b\u0445 \u043c\u0430\u0441\u0441\u0438\u0432\u0430, \u0442\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u043c\u0435\u0442\u043e\u0434 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u043e\u0431\u044a\u0435\u043a\u0442\u0430 \u043f\u043e \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u0430\u043c \u0442\u043e\u0447\u0435\u043a \u0438 \u0442\u0440\u0435\u0443\u0433\u043e\u043b\u044c\u043d\u0438\u043a\u0430\u043c, \u0430 \u0435\u0441\u043b\u0438 \u0442\u043e\u043b\u044c\u043a\u043e \u043e\u0434\u0438\u043d &#8212; \u0442\u043e \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u043e \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u0430\u043c \u0442\u043e\u0447\u0435\u043a.<\/p>\n<p>\u041f\u043e\u043c\u0438\u043c\u043e \u044d\u0442\u043e\u0433\u043e \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d \u043c\u0435\u0442\u043e\u0434 <code>__del__<\/code>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u043f\u0438\u0442\u043e\u043d\u043e\u043c \u0432 \u0441\u043b\u0443\u0447\u0430\u0435 \u0443\u0434\u0430\u043b\u0435\u043d\u0438\u044f \u043e\u0431\u044a\u0435\u043a\u0442\u0430. \u041c\u044b \u0432 \u0441\u0432\u043e\u044e \u043e\u0447\u0435\u0440\u0435\u0434\u044c \u043f\u0440\u0438 \u044d\u0442\u043e\u043c \u0434\u043e\u043b\u0436\u043d\u044b \u0432\u044b\u0437\u0432\u0430\u0442\u044c \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0443\u044e \u0444\u0443\u043d\u043a\u0446\u0438\u044e \u043c\u043e\u0434\u0443\u043b\u044f \u0434\u043b\u044f \u0443\u0434\u0430\u043b\u0435\u043d\u0438\u044f \u044d\u0442\u043e\u0433\u043e \u043e\u0431\u044a\u0435\u043a\u0442\u0430 \u0438\u0437 \u043f\u0430\u043c\u044f\u0442\u0438.<\/p>\n<p>\u0412\u0441\u0451. \u0412\u043e\u0442 \u0438\u0442\u043e\u0433\u043e\u0432\u044b\u0439 \u0444\u0430\u0439\u043b <code>delaunay_wasm.py<\/code><\/p>\n<details class=\"spoiler\">\n<summary>delaunay_wasm.py<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"python\">from wasmer import Store, Module, Instance, ImportObject, Function  class Loader:     def __init__(self, wasm_path):         self._heap = [None] * 128         self._heap.extend([None, None, True, False])          self._heap_next = len(self._heap)          self._wasm_vector_len = 0          store = Store()         module = Module(store, open(wasm_path, \"rb\").read())          imports = ImportObject()         imports.register(\"wbg\", {             \"__wbindgen_number_new\": Function(store, self._import_number_new),             \"__wbindgen_object_drop_ref\": Function(store, self._import_drop_ref),             \"__wbg_new_b525de17f44a8943\": Function(store, self._import_new),             \"__wbg_newwithlength_0da6f12fbc1ab6eb\": Function(store, self._import_new_with_length),             \"__wbg_set_17224bc548dd1d7b\": Function(store, self._import_set),             \"__wbg_push_49c286f04dd3bf59\": Function(store, self._import_push),             \"__wbindgen_throw\": Function(store, self._import_throw),         })          self._wasm = Instance(module, imports)         wasm_exports = self._wasm.exports         wasm_memory = wasm_exports.memory         self._float32_memory = wasm_memory.float32_view()         self._uint32_memory = wasm_memory.uint32_view()          for e in wasm_exports:             export_name = e[0]             export_function = e[1]             if export_name == \"build_triangulation\":                 self._build_triangulation = export_function             elif export_name == \"bvhnode_new\":                 self._new_bvh = export_function             elif export_name == \"bvhnode_new_trianglulation\":                 self._new_bvh_triangulation = export_function             elif export_name == \"bvhnode_sample\":                 self._bvh_sample = export_function             if export_name == \"__wbindgen_malloc\":                 self._malloc = export_function             elif export_name == \"__wbg_bvhnode_free\":                 self._bvh_free = export_function      def _import_number_new(self, arg: \"f64\") -> int:         return self._add_heap_object(arg)      def _import_drop_ref(self, arg: int):         self._take_object(arg)      def _import_new(self) -> int:         return self._add_heap_object([])      def _import_new_with_length(self, arg: int) -> int:         return self._add_heap_object([None] * arg)      def _import_set(self, arg0: int, arg1: int, arg2: int):         self._get_object(arg0)[arg1] = self._take_object(arg2)      def _import_push(self, arg0: int, arg1: int) -> int:         self._get_object(arg0).append(self._get_object(arg1))         return len(self._heap)      def _import_throw(self, arg0: int, arg1: int):         return \"something wrong\"      def _add_heap_object(self, obj: int) -> int:         if self._heap_next == len(self._heap):             self._heap.append(len(self._heap) + 1)          idx = self._heap_next         self._heap_next = self._heap[idx]         self._heap[idx] = obj          return idx      def _get_object(self, idx: int) -> int:         return self._heap[idx]      def _drop_object(self, idx: int):         if idx &lt; 132:             return None          self._heap[idx] = self._heap_next         self._heap_next = idx      def _take_object(self, idx: int):         ret: int = self._get_object(idx)         self._drop_object(idx)         return ret      def _pass_array_f32_to_wasm(self, arg) -> int:         ptr = self._malloc(len(arg) * 4)         for i in range(len(arg)):             self._float32_memory[ptr \/\/ 4 + i] = arg[i]         self._wasm_vector_len = len(arg)         return ptr      def _pass_array_32_to_wasm(self, arg) -> int:         ptr: int = self._malloc(len(arg) * 4)         for i in range(len(arg)):             self._uint32_memory[ptr \/\/ 4 + i] = arg[i]         self._wasm_vector_len = len(arg)         return ptr      def build_triangulation(self, coordinates: list[float]) -> list[int]:         ptr = self._pass_array_f32_to_wasm(coordinates)         length = self._wasm_vector_len         ret = self._build_triangulation(ptr, length)         array = self._take_object(ret)         return [int(v) for v in array]  class BVHNode:     def __init__(self, loader, coordinates: list[float], triangles=None):         self._loader = loader         if triangles is None:             ptr = loader._pass_array_f32_to_wasm(coordinates)             length = loader._wasm_vector_len             self._ptr = loader._new_bvh(ptr, length)         else:             ptr_0 = loader._pass_array_f32_to_wasm(coordinates)             length_0 = loader._wasm_vector_len             ptr_1 = loader._pass_array_32_to_wasm(triangles)             length_1 = loader._wasm_vector_len             self._ptr = loader._new_bvh_triangulation(ptr_0, length_0, ptr_1, length_1)      def __del__(self):         self._loader._bvh_free(self._ptr)      def sample(self, x:float, y: float) -> list[float]:         return self._loader._take_object(self._loader._bvh_sample(self._ptr, x, y))<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u041c\u043e\u0434\u0443\u043b\u044c WebAssembly \u043c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c<\/p>\n<pre><code class=\"python\">loader = Loader(\"delaunay_bg.wasm\") coordinates = [-0.5, 3.0, 8.0, -3.5, -7.0, 3.0, 2.0, -10.0, 7.0, 8.0, 8.0, 5.5] t = loader.build_triangulation(coordinates) print(t)  bvh = BVHNode(loader, coordinates, t) print(bvh.sample(0.0, 0.0))<\/code><\/pre>\n<p>\u0412 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0435 \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u0432\u0435\u0434\u0435\u043d\u043e<\/p>\n<pre><code>[2, 0, 3, 0, 2, 4, 3, 0, 1, 1, 0, 5, 0, 4, 5] [-7.0, 3.0, -0.5, 3.0, 2.0, -10.0]<\/code><\/pre>\n<p>\u042d\u0442\u043e \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u044b\u0439 \u043e\u0442\u0432\u0435\u0442.<\/p>\n<p>\u041f\u043e \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u0438 Wasmer \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442 \u043a\u043e\u0434 \u043f\u0440\u0438\u043c\u0435\u0440\u043d\u043e \u0432 1.3 &#8212; 1.4 \u0440\u0430\u0437\u0430 \u043c\u0435\u0434\u043b\u0435\u043d\u043d\u0435\u0435, \u0447\u0435\u043c NodeJS. \u0412 \u0446\u0435\u043b\u043e\u043c \u043d\u0435\u043f\u043b\u043e\u0445\u043e. \u0421 \u044d\u0442\u043e\u0439 \u0442\u043e\u0447\u043a\u0438 \u0437\u0440\u0435\u043d\u0438\u044f \u043c\u043e\u0436\u043d\u043e \u0432\u043e\u0441\u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0442\u044c WebAssembly \u043a\u0430\u043a \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u043e \u043d\u0435\u0437\u0430\u0432\u0438\u0441\u0438\u043c\u0443\u044e \u0430\u043b\u044c\u0442\u0435\u0440\u043d\u0430\u0442\u0438\u0432\u0443 \u043e\u0431\u044b\u0447\u043d\u044b\u043c \u0431\u0438\u043d\u0430\u0440\u043d\u044b\u043c \u043f\u0438\u0442\u043e\u043d\u043e\u0432\u0441\u043a\u0438\u043c \u043c\u043e\u0434\u0443\u043b\u044f\u043c, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043e\u0431\u044b\u0447\u043d\u043e \u043a\u043e\u043c\u043f\u0438\u043b\u0438\u0440\u0443\u044e\u0442\u0441\u044f \u0438\u0437 \u0442\u043e\u0433\u043e \u0436\u0435 c++ \u0434\u043b\u044f \u0443\u0441\u043a\u043e\u0440\u0435\u043d\u0438\u044f \u0442\u044f\u0436\u0451\u043b\u044b\u0445 \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u0439.<\/p>\n<\/p>\n<\/div>\n<\/div>\n<\/div>\n<p> <!----> <!----><\/div>\n<p> <!----> <!----><br \/> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habr.com\/ru\/post\/718874\/\"> https:\/\/habr.com\/ru\/post\/718874\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<div><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<p>\u0412 \u044d\u0442\u043e\u0439 \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u043e\u0439 \u0437\u0430\u043c\u0435\u0442\u043a\u0435 \u043f\u0440\u0435\u0434\u043b\u0430\u0433\u0430\u0435\u0442\u0441\u044f \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0441\u043f\u043e\u0441\u043e\u0431\u043e\u0432 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0446\u0438\u0438 \u043c\u043e\u0434\u0443\u043b\u044f \u0434\u043b\u044f WebAssembly, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f \u0442\u0440\u0438 \u0440\u0430\u0437\u043d\u044b\u0445 \u043f\u043e\u0434\u0445\u043e\u0434\u0430. \u041c\u044b \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u043c \u0440\u0435\u0448\u0435\u043d\u0438\u0435 \u043e\u0434\u043d\u043e\u0439 \u0438 \u0442\u043e\u0439 \u0436\u0435 \u0437\u0430\u0434\u0430\u0447\u043a\u0438 \u043d\u0430 \u0442\u0440\u0451\u0445 \u044f\u0437\u044b\u043a\u0430\u0445 \u0438 \u0441\u043a\u043e\u043c\u043f\u0438\u043b\u0438\u0440\u0443\u0435\u043c \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u044b\u0439 \u043a\u043e\u0434 \u0432 \u043c\u043e\u0434\u0443\u043b\u044c WebAssembly. \u0411\u0443\u0434\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c:<\/p>\n<ul>\n<li>\n<p>Emscripten \u0434\u043b\u044f \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0446\u0438\u0438 \u043a\u043e\u0434\u0430, \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u043d\u043e\u0433\u043e \u043d\u0430 c++<\/p>\n<\/li>\n<li>\n<p>AssemblyScript \u0434\u043b\u044f \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0446\u0438\u0438 \u043a\u043e\u0434\u0430, \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u043d\u043e\u0433\u043e \u043d\u0430, \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u043e, AssemblyScript<\/p>\n<\/li>\n<li>\n<p>wasm-pack \u0434\u043b\u044f \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0446\u0438\u0438 \u043a\u043e\u0434\u0430, \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u043d\u043e\u0433\u043e \u043d\u0430 Rust<\/p>\n<\/li>\n<\/ul>\n<p>\u041f\u043b\u0430\u043d \u0442\u0430\u043a\u043e\u0439:<\/p>\n<ul>\n<li>\n<p>\u0412\u043e \u0432\u0432\u0435\u0434\u0435\u043d\u0438\u0438 \u043c\u044b \u043e\u0431\u0441\u0443\u0434\u0438\u043c \u043f\u043e\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0443 \u0437\u0430\u0434\u0430\u0447\u0438 \u0438 \u043d\u0435\u043c\u043d\u043e\u0436\u043a\u043e \u043f\u043e\u0433\u043e\u0432\u043e\u0440\u0438\u043c \u043e \u0442\u0435\u0445\u043d\u043e\u043b\u043e\u0433\u0438\u0438 WebAssembly<\/p>\n<\/li>\n<li>\n<p>\u0412 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u043d\u043e\u0439 \u0447\u0430\u0441\u0442\u0438 \u043c\u044b \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u043e\u0441\u0442\u044c \u043c\u043e\u0434\u0443\u043b\u044f \u043d\u0430 \u0442\u0440\u0451\u0445 \u044f\u0437\u044b\u043a\u0430\u0445: c++, AssemblyScript \u0438 Rust. \u041f\u043e\u0433\u043e\u0432\u043e\u0440\u0438\u043c \u043e \u0442\u043e\u043c, \u043a\u0430\u043a\u0438\u0435 \u043f\u0440\u0438 \u044d\u0442\u043e\u043c \u0432\u043e\u0437\u043d\u0438\u043a\u0430\u044e\u0442 \u0441\u043b\u043e\u0436\u043d\u043e\u0441\u0442\u0438 \u0438 \u043a\u0430\u043a \u0438\u0445 \u043c\u043e\u0436\u043d\u043e \u043e\u0431\u043e\u0439\u0442\u0438<\/p>\n<\/li>\n<li>\n<p>\u041f\u043e\u0434\u0432\u0435\u0434\u0451\u043c \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u043e\u0439 \u0438\u0442\u043e\u0433. \u0421\u0442\u0430\u043d\u0435\u0442 \u0432\u0438\u0434\u043d\u043e, \u043a\u0430\u043a\u0430\u044f \u0442\u0435\u0445\u043d\u043e\u043b\u043e\u0433\u0438\u044f \u0445\u043e\u0440\u043e\u0448\u0430\u044f, \u0430 \u043a\u0430\u043a\u0430\u044f \u043d\u0435 \u043e\u0447\u0435\u043d\u044c<\/p>\n<\/li>\n<\/ul>\n<p>\u0412 \u043a\u043e\u043d\u0446\u0435 \u043f\u043b\u0430\u043d\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u0434\u0432\u0430 \u0431\u043e\u043d\u0443\u0441\u0430. \u041f\u0435\u0440\u0432\u044b\u0439 \u0431\u043e\u043d\u0443\u0441 &#8212; \u044d\u0442\u043e \u043f\u0440\u0438\u043c\u0435\u0440 \u043f\u0440\u043e\u0441\u0442\u043e\u0433\u043e web-\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0449\u0435\u0433\u043e \u043e\u0434\u0438\u043d \u0438\u0437 \u0441\u043a\u043e\u043c\u043f\u0438\u043b\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0445 \u043d\u0430\u043c\u0438 \u043c\u043e\u0434\u0443\u043b\u0435\u0439. \u0412\u0442\u043e\u0440\u043e\u0439 \u0431\u043e\u043d\u0443\u0441 &#8212; \u0434\u0435\u043c\u043e\u043d\u0441\u0442\u0440\u0430\u0446\u0438\u044f \u0442\u043e\u0433\u043e, \u043a\u0430\u043a \u044d\u0442\u043e\u0442 \u043c\u043e\u0434\u0443\u043b\u044c \u043c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0432 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0435 \u043d\u0430 Python.<\/p>\n<h2>\u0412\u0432\u0435\u0434\u0435\u043d\u0438\u0435<\/h2>\n<p>\u041f\u0440\u0435\u0434\u043f\u043e\u043b\u0430\u0433\u0430\u0435\u0442\u0441\u044f, \u0447\u0442\u043e \u0447\u0438\u0442\u0430\u0442\u0435\u043b\u044c \u0437\u043d\u0430\u043a\u043e\u043c \u0445\u043e\u0442\u044f \u0431\u044b \u043f\u043e\u043d\u0430\u0441\u043b\u044b\u0448\u043a\u0435 \u0441 \u0442\u0435\u0445\u043d\u043e\u043b\u043e\u0433\u0438\u0435\u0439 WebAssembly \u0438 \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u043b \u043e\u0434\u0438\u043d \u0438\u0437 HelloWorld \u0442\u0443\u0442\u043e\u0440\u0438\u0430\u043b\u043e\u0432 \u0434\u043b\u044f \u043e\u0434\u043d\u043e\u0439 \u0438\u0437 \u043f\u0435\u0440\u0435\u0447\u0438\u0441\u043b\u0435\u043d\u043d\u044b\u0445 \u0432\u044b\u0448\u0435 \u0442\u0435\u0445\u043d\u043e\u043b\u043e\u0433\u0438\u0439. \u0412\u043f\u0440\u043e\u0447\u0435\u043c, \u043c\u043e\u0436\u043d\u043e \u0431\u044b\u043b\u043e \u0438 \u043d\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0442\u044c. \u041e\u0431\u044b\u0447\u043d\u043e \u044d\u0442\u0438 HelloWorld-\u044b  \u043e\u043f\u0438\u0441\u044b\u0432\u0430\u044e\u0442 \u0442\u043e, \u043a\u0430\u043a \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u043c\u043e\u0434\u0443\u043b\u044c \u0434\u043b\u044f \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u044f \u0447\u0438\u0441\u0435\u043b \u0424\u0438\u0431\u043e\u043d\u0430\u0447\u0447\u0438, \u043d\u0443 \u0438\u043b\u0438 \u0432 \u043a\u0440\u0430\u0439\u043d\u0435\u043c \u0441\u043b\u0443\u0447\u0430\u0435 &#8212; \u0434\u043b\u044f \u043d\u0430\u0445\u043e\u0436\u0434\u0435\u043d\u0438\u044f \u0447\u0438\u0441\u043b\u0430 \u0434\u0435\u043b\u0438\u0442\u0435\u043b\u0435\u0439 \u0434\u0430\u043d\u043d\u043e\u0433\u043e \u0447\u0438\u0441\u043b\u0430. \u0422\u0435\u043a\u0443\u0449\u0430\u044f \u0437\u0430\u043c\u0435\u0442\u043a\u0430 \u043f\u0440\u0435\u0434\u043b\u0430\u0433\u0430\u0435\u0442 \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u043c\u0430\u043b\u0435\u043d\u044c\u043a\u0438\u0439 (\u043d\u0443 \u0432\u043e\u0442 \u0431\u0443\u043a\u0432\u0430\u043b\u044c\u043d\u043e \u0432\u0441\u0435\u0433\u043e \u043d\u0438\u0447\u0435\u0433\u043e) \u0448\u0430\u0436\u043e\u043a \u043e\u0442 HelloWorld-\u0430 \u0438 \u0440\u0435\u0448\u0438\u0442\u044c \u0447\u0443\u0442\u044c \u0431\u043e\u043b\u0435\u0435 \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0442\u0435\u043b\u044c\u043d\u0443\u044e \u0437\u0430\u0434\u0430\u0447\u0443 \u043f\u043e \u0441\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u044e \u0441 \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u0435\u043c \u0447\u0438\u0441\u0435\u043b \u0424\u0438\u0431\u043e\u043d\u0430\u0447\u0447\u0438.<\/p>\n<p>\u0418\u0442\u0430\u043a, \u0437\u0430\u0434\u0430\u0447\u0430. \u041f\u0440\u0435\u0434\u043b\u0430\u0433\u0430\u0435\u0442\u0441\u044f \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u043c\u043e\u0434\u0443\u043b\u044c, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0435. \u041d\u0430 \u0432\u0445\u043e\u0434 \u043f\u043e\u0434\u0430\u0451\u0442\u0441\u044f \u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u043e \u0442\u043e\u0447\u0435\u043a \u043d\u0430 \u043f\u043b\u043e\u0441\u043a\u043e\u0441\u0442\u0438. \u041c\u043e\u0434\u0443\u043b\u044c \u0441\u0442\u0440\u043e\u0438\u0442 \u0442\u0440\u0438\u0430\u043d\u0433\u0443\u043b\u044f\u0446\u0438\u044e \u0414\u0435\u043b\u043e\u043d\u0435 \u0441 \u0432\u0435\u0440\u0448\u0438\u043d\u0430\u043c\u0438 \u0432 \u044d\u0442\u0438\u0445 \u0442\u043e\u0447\u043a\u0430\u0445, \u0443\u043f\u0430\u043a\u043e\u0432\u044b\u0432\u0430\u0435\u0442 \u043f\u043e\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u044b\u0435 \u0442\u0440\u0435\u0443\u0433\u043e\u043b\u044c\u043d\u0438\u043a\u0438 \u0432 BVH \u0438 \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u0442 \u043c\u0435\u0442\u043e\u0434 \u043f\u043e\u0438\u0441\u043a\u0430 \u0442\u0440\u0435\u0443\u0433\u043e\u043b\u044c\u043d\u0438\u043a\u0430, \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0449\u0435\u0433\u043e \u043b\u044e\u0431\u0443\u044e \u0443\u043a\u0430\u0437\u0430\u043d\u043d\u0443\u044e \u0442\u043e\u0447\u043a\u0443.<\/p>\n<p>\u0411\u0443\u0434\u0435\u043c \u0441\u0447\u0438\u0442\u0430\u0442\u044c, \u0447\u0442\u043e \u043c\u044b \u0437\u043d\u0430\u0435\u043c, \u0447\u0442\u043e \u0442\u0430\u043a\u043e\u0435 \u0442\u0440\u0438\u0430\u043d\u0433\u0443\u043b\u044f\u0446\u0438\u044f \u0414\u0435\u043b\u043e\u043d\u0435. \u0415\u0441\u043b\u0438 \u043a\u0442\u043e \u0437\u0430\u0431\u044b\u043b (\u0438\u043b\u0438 \u043d\u0435 \u0437\u043d\u0430\u043b) &#8212; \u043c\u043e\u0436\u043d\u043e \u0432\u0441\u043f\u043e\u043c\u043d\u0438\u0442\u044c \u043d\u0430 <a href=\"https:\/\/ru.wikipedia.org\/wiki\/%D0%A2%D1%80%D0%B8%D0%B0%D0%BD%D0%B3%D1%83%D0%BB%D1%8F%D1%86%D0%B8%D1%8F_%D0%94%D0%B5%D0%BB%D0%BE%D0%BD%D0%B5\" rel=\"noopener noreferrer nofollow\">\u0412\u0438\u043a\u0438\u043f\u0435\u0434\u0438\u0438<\/a>. \u0415\u0441\u0442\u044c \u043c\u043d\u043e\u0433\u043e \u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c\u043e\u0432 \u0435\u0451 \u043f\u043e\u0441\u0442\u0440\u043e\u0435\u043d\u0438\u044f. \u041f\u0440\u0435\u0434\u043b\u0430\u0433\u0430\u0435\u0442\u0441\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043e\u0434\u0438\u043d \u0438\u0437 \u043d\u0438\u0445 \u0432\u043e\u0442 <a href=\"https:\/\/github.com\/darkskyapp\/delaunay-fast\" rel=\"noopener noreferrer nofollow\">\u043e\u0442\u0441\u044e\u0434\u0430<\/a>. \u041c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u044d\u0442\u043e\u0442 \u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c \u043d\u0435 \u0441\u0438\u043b\u044c\u043d\u043e \u0431\u044b\u0441\u0442\u0440\u044b\u0439, \u043d\u043e \u043f\u043e \u043a\u0440\u0430\u0439\u043d\u0435\u0439 \u043c\u0435\u0440\u0435 \u043f\u0440\u043e\u0441\u0442\u043e\u0439 \u0438 \u0435\u0433\u043e \u043c\u043e\u0436\u043d\u043e \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u043a\u043e\u0440\u043e\u0442\u043a\u043e\u0439 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u043e\u0439. \u0412 \u043b\u044e\u0431\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u0441\u0430\u043c \u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c \u043d\u0435 \u0438\u043c\u0435\u0435\u0442 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f. \u0417\u0430\u043c\u0435\u0442\u043a\u0430 \u0432\u0435\u0434\u044c \u043d\u0435 \u043e\u0431 \u044d\u0442\u043e\u043c.<\/p>\n<p>\u0427\u0442\u043e \u0442\u0430\u043a\u043e\u0435 BVH (Bounding Volume Hierarhy) \u0442\u043e\u0436\u0435, \u043d\u0430\u0432\u0435\u0440\u043d\u043e\u0435, \u0432\u0441\u0435 \u0437\u043d\u0430\u044e\u0442. \u0415\u0449\u0451 \u0432 \u0448\u043a\u043e\u043b\u0435, \u043f\u043e\u0434\u0438, \u0432 \u0432\u043e\u0441\u044c\u043c\u043e\u043c \u043a\u043b\u0430\u0441\u0441\u0435 \u043f\u0438\u0441\u0430\u043b\u0438 \u0440\u0430\u0437\u043d\u044b\u0435 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438. \u041d\u0443 \u0430 \u0435\u0441\u043b\u0438 \u043a\u043e\u043c\u0443 \u043d\u0435 \u043f\u043e\u0432\u0435\u0437\u043b\u043e \u0438\u043b\u0438 \u043e\u043d \u0437\u0430\u0431\u044b\u043b \u0441\u0432\u043e\u0451 \u0441\u0447\u0430\u0441\u0442\u043b\u0438\u0432\u043e\u0435 \u0434\u0435\u0442\u0441\u0442\u0432\u043e &#8212; \u043c\u043e\u0436\u043d\u043e \u0442\u043e\u0436\u0435 \u043e\u0437\u043d\u0430\u043a\u043e\u043c\u0438\u0442\u044c\u0441\u044f \u0441 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u0435\u043c \u043d\u0430 <a href=\"https:\/\/en.wikipedia.org\/wiki\/Bounding_volume_hierarchy\" rel=\"noopener noreferrer nofollow\">\u0412\u0438\u043a\u0438\u043f\u0435\u0434\u0438\u0438<\/a>. \u0418 \u0441\u043d\u043e\u0432\u0430, \u043f\u043e \u0431\u043e\u043b\u044c\u0448\u043e\u043c\u0443 \u0441\u0447\u0451\u0442\u0443, \u0447\u0442\u043e \u044d\u0442\u043e \u0442\u0430\u043a\u043e\u0435 \u043d\u0435 \u043e\u0441\u043e\u0431\u043e \u0432\u0430\u0436\u043d\u043e.<\/p>\n<p>\u0418 \u0435\u0449\u0451 \u043f\u0430\u0440\u0443 \u0441\u043b\u043e\u0432 \u043e \u0442\u043e\u043c, \u0447\u0442\u043e \u0442\u0430\u043a\u043e\u0435 WebAssembly. \u0415\u0441\u0442\u044c \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u0435 \u043d\u0430 \u0432\u0441\u0451 \u0442\u043e\u0439 \u0436\u0435 <a href=\"https:\/\/ru.wikipedia.org\/wiki\/WebAssembly\" rel=\"noopener noreferrer nofollow\">\u0412\u0438\u043a\u0438\u043f\u0435\u0434\u0438\u0438<\/a>, \u0435\u0441\u0442\u044c \u0432 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438 <a href=\"https:\/\/developer.mozilla.org\/ru\/docs\/WebAssembly\" rel=\"noopener noreferrer nofollow\">Mozill-\u044b<\/a>. \u041c\u043e\u0436\u043d\u043e \u043f\u043e \u0440\u0430\u0437\u043d\u043e\u043c\u0443 \u0440\u0430\u0441\u0441\u0442\u0430\u0432\u043b\u044f\u0442\u044c \u0430\u043a\u0446\u0435\u043d\u0442\u044b \u0432 \u0432\u043e\u043f\u0440\u043e\u0441\u0430\u0445 \u043e \u0442\u043e\u043c, \u043a\u0430\u043a \u043e\u0442\u043d\u043e\u0441\u0438\u0442\u044c\u0441\u044f \u043a \u0442\u0435\u0445\u043d\u043e\u043b\u043e\u0433\u0438\u0438 WebAssembly \u0438 \u0434\u043b\u044f \u0447\u0435\u0433\u043e \u0435\u0451 \u043c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c. \u041d\u0430 \u043c\u043e\u0439 \u0432\u0437\u0433\u043b\u044f\u0434 \u043e\u0434\u043d\u043e \u0438\u0437 \u043f\u0440\u0435\u0438\u043c\u0443\u0449\u0435\u0441\u0442\u0432\u043e \u043c\u043e\u0434\u0443\u043b\u0435\u0439 WebAssembly &#8212; \u044d\u0442\u043e \u0438\u0445 \u0443\u043d\u0438\u0432\u0435\u0440\u0441\u0430\u043b\u044c\u043d\u043e\u0441\u0442\u044c \u0432 \u0441\u043c\u044b\u0441\u043b\u0435 \u043d\u0435\u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043e\u0442 \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u044b. \u042d\u0442\u0438 \u043c\u043e\u0434\u0443\u043b\u0438 \u043c\u043e\u0436\u043d\u043e (\u0438 \u043d\u0443\u0436\u043d\u043e) \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0442\u044c \u043d\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u0432 \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u0435 \u0438 NodeJS. \u0415\u0441\u0442\u044c \u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u043e \u0441\u0442\u0430\u0446\u0438\u043e\u043d\u0430\u0440\u043d\u044b\u0445 \u0438\u0442\u0435\u0440\u043f\u0440\u0435\u0442\u0430\u0442\u043e\u0440\u043e\u0432 \u0438 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440\u043e\u0432 \u0432 \u043d\u0430\u0441\u0442\u043e\u044f\u0449\u0438\u0435 \u043c\u0430\u0448\u0438\u043d\u043d\u044b\u0435 \u043a\u043e\u0434\u044b. <a href=\"https:\/\/github.com\/appcypher\/awesome-wasm-runtimes\" rel=\"noopener noreferrer nofollow\">\u0412\u043e\u0442 \u0442\u0443\u0442<\/a> \u0431\u043e\u043b\u044c\u0448\u043e\u0439 \u0441\u043f\u0438\u0441\u043e\u043a \u0440\u0430\u0437\u043d\u044b\u0445 \u0442\u0430\u043a\u0438\u0445 \u043f\u0440\u043e\u0435\u043a\u0442\u043e\u0432. \u041f\u043e\u043c\u0438\u043c\u043e \u044d\u0442\u043e\u0433\u043e \u043c\u043e\u0434\u0443\u043b\u0438 WebAssembly \u043c\u043e\u0436\u043d\u043e \u0432\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u0442\u044c \u0432 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b \u0441\u043a\u0440\u0438\u043f\u0442\u043e\u0432\u044b\u0445 (\u0447\u0438\u0442\u0430\u0439 \u043c\u0435\u0434\u043b\u0435\u043d\u043d\u044b\u0445) \u044f\u0437\u044b\u043a\u0430\u0445 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f, \u0438 \u0442\u0435\u043c \u0441\u0430\u043c\u044b\u043c \u043a\u0430\u043a\u0438\u0435-\u0442\u043e \u0432\u044b\u0447\u0438\u0441\u043b\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0442\u044f\u0436\u0451\u043b\u044b\u0435 \u043a\u0443\u0441\u043a\u0438 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0442\u044c \u0433\u043e\u0440\u0430\u0437\u0434\u043e \u0431\u044b\u0441\u0442\u0440\u0435\u0435. \u0422\u0435\u0445\u043d\u043e\u043b\u043e\u0433\u0438\u044f <a href=\"https:\/\/github.com\/wasmerio\/wasmer\" rel=\"noopener noreferrer nofollow\">Wasmer<\/a> \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442, \u0432 \u0447\u0430\u0441\u0442\u043d\u043e\u0441\u0442\u0438, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043c\u043e\u0434\u0443\u043b\u0438 WebAssembly \u0432\u043d\u0443\u0442\u0440\u0438 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c \u043a\u0430\u043a \u043d\u0430 Python, \u0442\u0430\u043a \u0438 \u043d\u0430 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u0434\u0440\u0443\u0433\u0438\u0445 \u044f\u0437\u044b\u043a\u0430\u0445 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f.<\/p>\n<p>\u041f\u0438\u0441\u0430\u0442\u044c \u043a\u043e\u0434 \u043d\u0435\u043f\u043e\u0441\u0440\u0435\u0434\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u043d\u0430 WebAssembly \u043c\u043e\u0436\u043d\u043e. \u041d\u043e \u043d\u0443\u0436\u043d\u043e \u044d\u0442\u043e \u043f\u0440\u0438\u043c\u0435\u0440\u043d\u043e \u0441\u0442\u043e\u043b\u044c\u043a\u043e \u0436\u0435 \u0440\u0430\u0437, \u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043f\u0438\u0441\u0430\u0442\u044c \u043d\u0430 \u043e\u0431\u044b\u0447\u043d\u043e\u043c \u0430\u0441\u0441\u0435\u043c\u0431\u043b\u0435\u0440\u0435, \u0438 \u0434\u0430\u0436\u0435 \u0440\u0435\u0436\u0435. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u043e\u0431\u044b\u0447\u043d\u043e \u043f\u0438\u0448\u0443\u0442 \u043d\u0430 \u043a\u0430\u043a\u043e\u043c-\u043d\u0438\u0431\u0443\u0434\u044c \u0447\u0435\u043b\u043e\u0432\u0435\u0447\u0435\u0441\u043a\u043e\u043c \u044f\u0437\u044b\u043a\u0435, \u0430 \u043f\u043e\u0442\u043e\u043c \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u0443\u044e \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0443 \u043a\u043e\u043c\u043f\u0438\u043b\u0438\u0440\u0443\u044e\u0442 \u0432 WebAssembly. \u0418 \u0432\u043e\u0442 \u0442\u0443\u0442 \u0432\u043e\u0442 \u0438 \u043a\u0440\u043e\u0435\u0442\u0441\u044f \u043e\u0434\u043d\u0430 \u0438\u0437 \u043f\u0440\u043e\u0431\u043b\u0435\u043c. \u0414\u0435\u043b\u043e \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u043c\u043d\u043e\u0433\u043e \u044f\u0437\u044b\u043a\u043e\u0432 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u043a\u043e\u043c\u043f\u0438\u043b\u0438\u0440\u0443\u044e\u0442\u0441\u044f \u0432 WebAssembly. <a href=\"https:\/\/github.com\/appcypher\/awesome-wasm-langs\" rel=\"noopener noreferrer nofollow\">\u0412\u043e\u0442 \u0442\u0443\u0442<\/a> \u0435\u0441\u0442\u044c \u0441\u043f\u0438\u0441\u043e\u043a. \u041c\u043d\u043e\u0433\u043e \u0442\u0430\u043c \u0432\u0441\u044f\u043a\u043e\u0433\u043e \u0440\u0430\u0437\u043d\u043e\u0433\u043e \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u043e. \u041d\u043e \u043c\u0430\u043b\u043e \u043c\u043e\u0434\u0443\u043b\u044c \u0441\u043a\u043e\u043c\u043f\u0438\u043b\u0438\u0440\u043e\u0432\u0430\u0442\u044c, \u0435\u0433\u043e \u0432\u0435\u0434\u044c \u043f\u043e\u0442\u043e\u043c \u043d\u0430\u0434\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0438\u0437 \u043a\u0430\u043a\u043e\u0433\u043e-\u0442\u043e \u0434\u0440\u0443\u0433\u043e\u0433\u043e \u043c\u0435\u0441\u0442\u0430. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0432\u044b\u0437\u0432\u0430\u0442\u044c \u0444\u0443\u043d\u043a\u0446\u0438\u044e, \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d\u043d\u0443\u044e \u0432 \u043c\u043e\u0434\u0443\u043b\u0435, \u0438 \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442. \u041d\u043e \u0432\u043e\u0442 \u0431\u0435\u0434\u0430, \u044f\u0437\u044b\u043a WebAssembly \u043f\u043e\u043d\u0438\u043c\u0430\u0435\u0442 \u0442\u043e\u043b\u044c\u043a\u043e \u0447\u0438\u0441\u043b\u043e\u0432\u044b\u0435 \u0442\u0438\u043f\u044b \u0434\u0430\u043d\u043d\u044b\u0445: \u0446\u0435\u043b\u044b\u0435 \u0438 \u0441 \u043f\u043b\u0430\u0432\u0430\u044e\u0449\u0435\u0439 \u0442\u043e\u0447\u043a\u043e\u0439 \u0440\u0430\u0437\u043d\u043e\u0439 \u0431\u0438\u0442\u043d\u043e\u0441\u0442\u0438. \u0418 \u0441 \u044d\u0442\u0438\u043c \u043d\u0435\u0442 \u043f\u0440\u043e\u0431\u043b\u0435\u043c, \u0435\u0441\u043b\u0438 \u043c\u044b \u0445\u043e\u0442\u0438\u043c \u0432\u044b\u0437\u0432\u0430\u0442\u044c \u0444\u0443\u043d\u043a\u0446\u0438\u044e, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442 \u0442\u043e\u043b\u044c\u043a\u043e \u0447\u0438\u0441\u043b\u043e\u0432\u044b\u0435 \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u044b \u0438 \u0432\u044b\u0434\u0430\u0451\u0442 \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0430 \u0442\u043e\u0436\u0435 \u0447\u0438\u0441\u043b\u043e. \u0410 \u0435\u0441\u043b\u0438 \u043c\u044b, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0445\u043e\u0442\u0438\u043c \u043f\u043e\u0441\u0447\u0438\u0442\u0430\u0442\u044c \u0441\u0443\u043c\u043c\u0443 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432 \u043c\u0430\u0441\u0441\u0438\u0432\u0430. \u042d\u0442\u043e \u0432\u0435\u0434\u044c \u043d\u0430\u0434\u043e \u043a\u0430\u043a-\u0442\u043e \u043f\u0435\u0440\u0435\u0434\u0430\u0442\u044c \u043c\u0430\u0441\u0441\u0438\u0432 \u0432 \u043c\u043e\u0434\u0443\u043b\u044c. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0435\u0433\u043e \u043d\u0430\u0434\u043e \u0440\u0430\u0437\u043c\u0435\u0441\u0442\u0438\u0442\u044c \u0432 \u043f\u0430\u043c\u044f\u0442\u0438 \u043c\u043e\u0434\u0443\u043b\u044f, \u0430 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0430 \u0443\u0436\u0435 \u0434\u043e\u043b\u0436\u043d\u0430 \u0441\u0430\u043c\u0430 \u0443\u043c\u0435\u0442\u044c \u0435\u0433\u043e \u0438\u0437 \u044d\u0442\u043e\u0439 \u043f\u0430\u043c\u044f\u0442\u0438 \u0432\u0437\u044f\u0442\u044c. \u0412\u043e\u0442 \u0438 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0430: \u043e\u0442\u043a\u0443\u0434\u0430 \u044f \u043a\u0430\u043a \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0441\u0442 \u0437\u043d\u0430\u044e \u0432 \u043a\u0430\u043a\u043e\u043c \u0432\u0438\u0434\u0435 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0430 \u043f\u0430\u043c\u044f\u0442\u044c \u043c\u043e\u0434\u0443\u043b\u044f \u043f\u043e\u0441\u043b\u0435 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0446\u0438\u0438, \u043a\u0430\u043a \u043e\u0442\u0442\u0443\u0434\u0430 \u0447\u0442\u043e-\u0442\u043e \u0431\u0440\u0430\u0442\u044c \u0438, \u043f\u0440\u043e\u0441\u0442\u0438 \u0433\u043e\u0441\u043f\u043e\u0434\u0438, \u0447\u0442\u043e-\u0442\u043e \u0442\u0443\u0434\u0430 \u043a\u043b\u0430\u0441\u0442\u044c? \u0413\u043e\u0432\u043e\u0440\u044e \u0436\u0435 &#8212; \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u044b. \u0414\u0430, \u043e\u043d\u0438 \u0440\u0435\u0448\u0430\u044e\u0442\u0441\u044f, \u043d\u043e \u043f\u0440\u043e\u0446\u0435\u0434\u0443\u0440\u0430 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u043e\u0442\u043a\u043e\u043c\u043f\u0438\u043b\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0433\u043e \u043c\u043e\u0434\u0443\u043b\u044f \u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u0441\u044f \u0432\u0435\u0441\u044c\u043c\u0430 \u043d\u0435\u0442\u0440\u0438\u0432\u0438\u0430\u043b\u044c\u043d\u043e\u0439.<\/p>\n<p>\u041e\u0434\u043d\u0430\u043a\u043e \u043d\u0435 \u0432\u0441\u0451 \u0442\u0430\u043a \u043f\u043b\u043e\u0445\u043e. \u0415\u0441\u0442\u044c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0442\u0435\u0445\u043d\u043e\u043b\u043e\u0433\u0438\u0439, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043d\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u043a\u043e\u043c\u043f\u0438\u043b\u0438\u0440\u0443\u044e\u0442 \u043c\u043e\u0434\u0443\u043b\u044c WebAssembly, \u043d\u043e \u0438 \u0441\u043e\u0437\u0434\u0430\u044e\u0442 \u043e\u0431\u0432\u0435\u0441 (\u0442\u0430\u043a \u043d\u0430\u0437\u044b\u0432\u0430\u0435\u043c\u044b\u0439 gluing code), \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0438 \u0434\u0435\u043b\u0430\u0435\u0442 \u0432\u0441\u0435 \u0432\u043e\u0442 \u044d\u0442\u0438 \u043d\u0435\u0443\u0434\u043e\u0431\u043d\u044b\u0435 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f, \u0437\u0430\u0441\u0442\u0430\u0432\u043b\u044f\u044e\u0449\u0438\u0435 \u0437\u0430\u0434\u0443\u043c\u044b\u0432\u0430\u0442\u044c\u0441\u044f \u0438 \u043e\u0442\u0447\u0430\u0438\u0432\u0430\u0442\u044c\u0441\u044f. \u042d\u0442\u0438 \u0442\u0435\u0445\u043d\u043e\u043b\u043e\u0433\u0438\u0438 \u043f\u0435\u0440\u0435\u0447\u0438\u0441\u043b\u0435\u043d\u044b \u0432 \u0441\u0430\u043c\u043e\u043c \u043d\u0430\u0447\u0430\u043b\u0435. \u041c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u0435\u0441\u0442\u044c \u0435\u0449\u0451 \u043a\u0430\u043a\u0438\u0435-\u0442\u043e \u0434\u0440\u0443\u0433\u0438\u0435, \u043d\u043e \u0434\u0430\u0432\u0430\u0439\u0442\u0435 \u0434\u043b\u044f \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0451\u043d\u043d\u043e\u0441\u0442\u0438 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0438\u043c\u0441\u044f \u044d\u0442\u0438\u043c\u0438 \u0442\u0440\u0435\u043c\u044f. \u041e\u043d\u0438, \u0432\u0441\u0451-\u0442\u0430\u043a\u0438, \u043d\u0430\u0438\u0431\u043e\u043b\u0435\u0435 \u043f\u043e\u043f\u0443\u043b\u044f\u0440\u043d\u044b. <\/p>\n<h2>\u041f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u043d\u0430\u044f \u0447\u0430\u0441\u0442\u044c<\/h2>\n<p>\u0418\u0442\u0430\u043a, \u043f\u0440\u0438\u0441\u0442\u0443\u043f\u0438\u043c \u043a \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044e. \u0415\u0449\u0451 \u0440\u0430\u0437 \u043f\u043e\u0432\u0442\u043e\u0440\u044e, \u0447\u0442\u043e \u043d\u0430\u0448\u0430 \u0446\u0435\u043b\u044c \u0441\u043e\u0441\u0442\u043e\u0438\u0442 \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e\u0431\u044b \u0437\u0430\u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0443\u043f\u0430\u043a\u043e\u0432\u043a\u0443 \u0432 BVH \u0442\u0440\u0435\u0443\u0433\u043e\u043b\u044c\u043d\u0438\u043a\u043e\u0432 \u0442\u0440\u0438\u0430\u043d\u0433\u0443\u043b\u044f\u0446\u0438\u0438 \u0414\u0435\u043b\u043e\u043d\u0435. \u041d\u0430\u0447\u043d\u0451\u043c \u0441 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u043d\u0430 c++, \u043f\u043e\u0442\u043e\u043c \u0441\u0434\u0435\u043b\u0430\u0435\u043c \u0442\u043e \u0436\u0435 \u0441\u0430\u043c\u043e\u0435 \u043d\u0430 AssemblyScript, \u0430 \u0437\u0430\u043a\u043e\u043d\u0447\u0438\u043c \u043d\u0430 Rust.<\/p>\n<h3>Emscripten \u0438 c++<\/h3>\n<p>\u041f\u0440\u0435\u0434\u043b\u0430\u0433\u0430\u0435\u0442\u0441\u044f \u0440\u0430\u0437\u044b\u0433\u0440\u0430\u0442\u044c \u0442\u0430\u043a\u043e\u0439 \u0441\u0446\u0435\u043d\u0430\u0440\u0438\u0439. \u041f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u0438\u043c, \u0447\u0442\u043e \u043c\u044b \u043a\u0430\u043a \u0431\u0443\u0434\u0442\u043e \u0431\u044b \u043f\u0438\u0448\u0435\u043c \u043e\u0431\u044b\u0447\u043d\u0443\u044e \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0443 \u043d\u0430 c++, \u043d\u0435 \u0438\u043c\u0435\u044f \u0432\u0432\u0438\u0434\u0443 \u043a\u0430\u043a\u0443\u044e-\u0442\u043e \u043f\u043e\u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0443\u044e \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0446\u0438\u044e \u0432 WebAssembly. \u042d\u0442\u043e \u0443\u0434\u043e\u0431\u043d\u043e, \u0442\u0430\u043a \u043a\u0430\u043a \u043c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043f\u0440\u0438\u0432\u044b\u0447\u043d\u044b\u0435 \u0441\u0440\u0435\u0434\u0441\u0442\u0432\u0430 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438, \u043e\u0442\u043b\u0430\u0434\u043a\u0438 \u0438 \u0447\u0435\u0433\u043e \u0442\u0430\u043c \u0435\u0449\u0451 \u043d\u0443\u0436\u043d\u043e. \u042f \u043d\u0430 c++ \u043d\u0438\u043a\u043e\u0433\u0434\u0430 \u043e\u0441\u043e\u0431\u043e \u043d\u0438\u0447\u0435\u0433\u043e \u043d\u0435 \u043f\u0438\u0441\u0430\u043b, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0431\u0443\u0434\u0443 \u0434\u0435\u043b\u0430\u0442\u044c \u0432\u0441\u0451 \u0432 VisualStudio, \u0441\u043e\u0437\u0434\u0430\u0432 \u043f\u0440\u043e\u0435\u043a\u0442 \u0434\u043b\u044f \u043e\u0431\u044b\u0447\u043d\u043e\u0433\u043e \u043a\u043e\u043d\u0441\u043e\u043b\u044c\u043d\u043e\u0433\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f. \u041f\u043e\u0442\u043e\u043c, \u043a\u043e\u0433\u0434\u0430 \u0443\u0436\u0435 \u0432\u0441\u0451 \u043d\u0430\u043f\u0438\u0448\u0435\u043c, \u0442\u043e\u0433\u0434\u0430 \u0438 \u0431\u0443\u0434\u0435\u043c \u0434\u0443\u043c\u0430\u0442\u044c \u043e \u0442\u043e\u043c, \u043a\u0430\u043a \u0432\u0441\u0451 \u044d\u0442\u043e \u0434\u0435\u043b\u043e \u0441\u043a\u043e\u043c\u043f\u0438\u043b\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0432 WebAssembly.<\/p>\n<h4>\u041f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0430 \u043d\u0430 c++<\/h4>\n<p>\u0418\u0442\u0430\u043a, \u0441\u043e\u0437\u0434\u0430\u0451\u043c \u043f\u044f\u0442\u044c \u0444\u0430\u0439\u043b\u043e\u0432: <code>point.h<\/code> <code>delaunay.h<\/code> <code>delaunay.cpp<\/code> <code>bvh.h<\/code> \u0438 <code>bvh.cpp<\/code><\/p>\n<p>\u0424\u0430\u0439\u043b <code>point.h<\/code> \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443 \u0434\u043b\u044f \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u044f \u0442\u043e\u0447\u043a\u0438 \u043d\u0430 \u043f\u043b\u043e\u0441\u043a\u043e\u0441\u0442\u0438.<\/p>\n<details class=\"spoiler\">\n<summary>point.h<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"cpp\">#pragma once  #include &lt;string>  struct Point { Point() : x(0.0f), y(0.0f) { } Point(float _x, float _y) : x(_x), y(_y) { }  std::string to_string() const { return \"(\" + std::to_string(x) + \", \" + std::to_string(y) + \")\"; }  float x; float y; };<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u0424\u0430\u0439\u043b <code>delaunay.h<\/code> \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u0442\u043e\u043b\u044c\u043a\u043e \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u0441\u0438\u0433\u043d\u0430\u0442\u0443\u0440\u044b \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0434\u043b\u044f \u043f\u043e\u0441\u0442\u0440\u043e\u0435\u043d\u0438\u044f \u0442\u0440\u0438\u0430\u043d\u0433\u0443\u043b\u044f\u0446\u0438\u0438 \u0414\u0435\u043b\u043e\u043d\u0435. \u041d\u0430 \u0432\u0445\u043e\u0434 \u043e\u043d\u0430 \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442 \u043c\u0430\u0441\u0441\u0438\u0432 \u0442\u043e\u0447\u0435\u043a, \u0430 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u043c\u0430\u0441\u0441\u0438\u0432 \u0438\u043d\u0434\u0435\u043a\u0441\u043e\u0432 \u044d\u0442\u0438\u0445 \u0442\u043e\u0447\u0435\u043a, \u043e\u043f\u0438\u0441\u044b\u0432\u0430\u044e\u0449\u0438\u0445 \u0442\u0440\u0435\u0443\u0433\u043e\u043b\u044c\u043d\u0438\u043a\u0438. \u041f\u0440\u0435\u0434\u043f\u043e\u043b\u0430\u0433\u0430\u0435\u0442\u0441\u044f, \u0447\u0442\u043e \u043f\u0435\u0440\u0432\u044b\u0435 \u0442\u0440\u0438 \u0447\u0438\u0441\u043b\u0430 \u0438\u0442\u043e\u0433\u043e\u0432\u043e\u0433\u043e \u043c\u0430\u0441\u0441\u0438\u0432\u0430 &#8212; \u044d\u0442\u043e \u0438\u043d\u0434\u0435\u043a\u0441\u044b \u0432\u0435\u0440\u0448\u0438\u043d \u043f\u0435\u0440\u0432\u043e\u0433\u043e \u0442\u0440\u0435\u0443\u0433\u043e\u043b\u044c\u043d\u0438\u043a\u0430, \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u0442\u0440\u0438 &#8212; \u0432\u0442\u043e\u0440\u043e\u0433\u043e, \u0438 \u0442\u0430\u043a \u0434\u0430\u043b\u0435\u0435.<\/p>\n<details class=\"spoiler\">\n<summary>delaunay.h<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"cpp\">std::vector&lt;int> triangulate(std::vector&lt;Point>&amp; points);<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u0424\u0430\u0439\u043b <code>delaunay.cpp<\/code> \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u043d\u0435\u043f\u043e\u0441\u0440\u0435\u0434\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e \u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c\u0430 \u043f\u043e\u0441\u0442\u0440\u043e\u0435\u043d\u0438\u044f \u0442\u0440\u0438\u0430\u043d\u0433\u0443\u043b\u044f\u0446\u0438\u0438 \u0414\u0435\u043b\u043e\u043d\u0435. \u0422\u0430\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0432\u0441\u043f\u043e\u043c\u043e\u0433\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u0445 \u0444\u0443\u043d\u043a\u0446\u0438\u0439 \u0438 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440, \u043d\u043e \u0432 \u0446\u0435\u043b\u043e\u043c \u043d\u0438\u0447\u0435\u0433\u043e \u0441\u043b\u043e\u0436\u043d\u043e\u0433\u043e. \u041a\u0430\u043a\u043e\u0433\u043e \u0431\u044b \u0442\u043e \u043d\u0438 \u0431\u044b\u043b\u043e, \u0440\u0430\u0437\u0431\u043e\u0440\u0430 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0449\u0435\u0433\u043e\u0441\u044f \u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c\u0430 \u0437\u0434\u0435\u0441\u044c \u0434\u0430\u0432\u0430\u0442\u044c \u043d\u0435 \u0431\u0443\u0434\u0435\u043c, \u0442\u0430\u043a \u043a\u0430\u043a \u044d\u0442\u043e \u0443\u0432\u0435\u0434\u0451\u0442 \u043d\u0430\u0441 \u0434\u0430\u043b\u0435\u043a\u043e \u0432 \u0441\u0442\u043e\u0440\u043e\u043d\u0443.<\/p>\n<details class=\"spoiler\">\n<summary>delaunay.cpp<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"cpp\">#include \"point.h\"  #include &lt;vector> #include &lt;iostream> #include &lt;algorithm> #include &lt;float.h>  struct TriangleCircle {     \/\/ triangle point indices     int i;     int j;     int k;      \/\/ circle center     float x;     float y;      \/\/ the square of the circle radius     float radius_sq;      std::string to_string() const     {         return \"&lt;\" + std::to_string(i) + \", \" + std::to_string(j) + \", \" + std::to_string(k) + \"|\" + std::to_string(x) + \", \" + std::to_string(y) + \"|\" + std::to_string(radius_sq) + \">\";     } };  std::vector&lt;Point> build_supertriangle(const std::vector&lt;Point> &amp;points) {     float x_min = FLT_MAX;     float y_min = FLT_MAX;     float x_max = FLT_MIN;     float y_max = FLT_MIN;      for (size_t i = 0; i &lt; points.size(); i++)     {         const Point p = points[i];         if (p.x &lt; x_min) { x_min = p.x; }         if (p.x > x_max) { x_max = p.x; }         if (p.y &lt; y_min) { y_min = p.y; }         if (p.y > y_max) { y_max = p.y; }     }      float dx = x_max - x_min;     float dy = y_max - y_min;      float d_max = std::max(dx, dy);     float x_mid = x_min + dx * 0.5f;     float y_mid = y_min + dy * 0.5f;      return {          Point(x_mid - 20.0f * d_max, y_mid - d_max),         Point(x_mid, y_mid + 20.0f * d_max),         Point(x_mid + 20.0f * d_max, y_mid - d_max) }; }  TriangleCircle circumcircle(const std::vector&lt;Point> &amp;points, int i, int j, int k) {     const Point point_i = points[i];     const Point point_j = points[j];     const Point point_k = points[k];      float x_1 = point_i.x;     float y_1 = point_i.y;      float x_2 = point_j.x;     float y_2 = point_j.y;      float x_3 = point_k.x;     float y_3 = point_k.y;      float y1_y2 = std::abs(y_1 - y_2);     float y2_y3 = std::abs(y_2 - y_3);      float center_x = 0.0f;     float center_y = 0.0f;     float m_1 = 0.0f;     float m_2 = 0.0f;     float mx_1 = 0.0f;     float mx_2 = 0.0f;     float my_1 = 0.0f;     float my_2 = 0.0f;      float EPSILON = 0.00001f;      if (y1_y2 &lt; EPSILON)     {         m_2 = -(x_3 - x_2) \/ (y_3 - y_2);         mx_2 = (x_2 + x_3) \/ 2.0f;         my_2 = (y_2 + y_3) \/ 2.0f;         center_x = (x_2 + x_1) \/ 2.0f;         center_y = m_2 * (center_x - mx_2) + my_2;     }     else if (y2_y3 &lt; EPSILON)     {         m_1 = -(x_2 - x_1) \/ (y_2 - y_1);         mx_1 = (x_1 + x_2) \/ 2.0f;         my_1 = (y_1 + y_2) \/ 2.0f;         center_x = (x_3 + x_2) \/ 2.0f;         center_y = m_1 * (center_x - mx_1) + my_1;     }     else     {         m_1 = -(x_2 - x_1) \/ (y_2 - y_1);         m_2 = -(x_3 - x_2) \/ (y_3 - y_2);         mx_1 = (x_1 + x_2) \/ 2.0f;         mx_2 = (x_2 + x_3) \/ 2.0f;         my_1 = (y_1 + y_2) \/ 2.0f;         my_2 = (y_2 + y_3) \/ 2.0f;         center_x = (m_1 * mx_1 - m_2 * mx_2 + my_2 - my_1) \/ (m_1 - m_2);         center_y = y1_y2 > y2_y3 ? (m_1 *<\/code><\/pre>\n<\/div>\n<\/details>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-345850","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/345850","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=345850"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/345850\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=345850"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=345850"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=345850"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}