{"id":319334,"date":"2021-03-10T15:01:31","date_gmt":"2021-03-10T15:01:31","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=319334"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=319334","title":{"rendered":"\u0422\u0440\u0430\u0441\u0441\u0438\u0440\u043e\u0432\u0449\u0438\u043a \u043b\u0443\u0447\u0435\u0439 \u0441 \u043d\u0443\u043b\u044f \u0437\u0430 100 \u0441\u0442\u0440\u043e\u0447\u0435\u043a Python"},"content":{"rendered":"\n<div class=\"post__text post__text_v2\" id=\"post-content-body\">\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/bdf\/95c\/6f1\/bdf95c6f104d77651c5aeb2ada2cdabc.png\" alt=\"\u0420\u0438\u0441\u0443\u043d\u043e\u043a 1\" title=\"\u0420\u0438\u0441\u0443\u043d\u043e\u043a 1\" width=\"1400\" height=\"787\"><figcaption>\u0420\u0438\u0441\u0443\u043d\u043e\u043a 1<\/figcaption><\/figure>\n<p>\u0412 \u044d\u0442\u043e\u043c \u043f\u043e\u0441\u0442\u0435 \u043c\u044b \u0437\u0430\u0433\u043b\u044f\u043d\u0435\u043c \u043f\u043e\u0434 \u043a\u0430\u043f\u043e\u0442 \u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c\u043e\u0432 \u043a\u043e\u043c\u043f\u044c\u044e\u0442\u0435\u0440\u043d\u043e\u0439 \u0433\u0440\u0430\u0444\u0438\u043a\u0438, \u043f\u043e\u0448\u0430\u0433\u043e\u0432\u043e \u0440\u0430\u0437\u0431\u0435\u0440\u0435\u043c \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u0435 \u043f\u0440\u0438\u043d\u0446\u0438\u043f\u044b \u0442\u0440\u0430\u0441\u0441\u0438\u0440\u043e\u0432\u043a\u0438 \u043b\u0443\u0447\u0435\u0439 \u0438 \u043d\u0430\u043f\u0438\u0448\u0435\u043c \u0435\u0435 \u043f\u0440\u043e\u0441\u0442\u0443\u044e \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e \u043d\u0430 Python. \u041d\u0438\u043a\u0430\u043a\u0438\u0445 \u0441\u0442\u043e\u0440\u043e\u043d\u043d\u0438\u0445 \u0433\u0440\u0430\u0444\u0438\u0447\u0435\u0441\u043a\u0438\u0445 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a \u2014 \u0442\u043e\u043b\u044c\u043a\u043e <em>NumPy <\/em>\u0438 \u0433\u043e\u043b\u044b\u0439 \u043a\u043e\u0434 \u0432 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440\u0435.<\/p>\n<p><em>\u041f\u0440\u0438\u043c\u0435\u0447\u0430\u043d\u0438\u0435:<\/em> \u042d\u0442\u0430 \u0441\u0442\u0430\u0442\u044c\u044f \u043d\u0438 \u0432 \u043a\u043e\u0435\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u043d\u0435 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043f\u043e\u043b\u043d\u044b\u043c \u0440\u0443\u043a\u043e\u0432\u043e\u0434\u0441\u0442\u0432\u043e\u043c\/\u043e\u0431\u044a\u044f\u0441\u043d\u0435\u043d\u0438\u0435\u043c \u0442\u0440\u0430\u0441\u0441\u0438\u0440\u043e\u0432\u043a\u0438 \u043b\u0443\u0447\u0435\u0439, \u043f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u044d\u0442\u0430 \u0442\u0435\u043c\u0430 \u0441\u043b\u0438\u0448\u043a\u043e\u043c \u043e\u0431\u0448\u0438\u0440\u043d\u0430, \u0430 \u0441\u043a\u043e\u0440\u0435\u0435 \u043f\u0440\u043e\u0441\u0442\u043e \u0432\u0432\u0435\u0434\u0435\u043d\u0438\u0435\u043c \u0434\u043b\u044f \u043b\u044e\u0431\u043e\u043f\u044b\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0445.<\/p>\n<h3>\u041f\u0440\u0435\u0434\u043f\u043e\u0441\u044b\u043b\u043a\u0438<\/h3>\n<p>\u041d\u0430\u043c \u043f\u043e\u043d\u0430\u0434\u043e\u0431\u0438\u0442\u0441\u044f \u0442\u043e\u043b\u044c\u043a\u043e \u0441\u0430\u043c\u0430\u044f \u0431\u0430\u0437\u043e\u0432\u0430\u044f \u0432\u0435\u043a\u0442\u043e\u0440\u043d\u0430\u044f \u0433\u0435\u043e\u043c\u0435\u0442\u0440\u0438\u044f:<\/p>\n<ul>\n<li>\n<p>\u041f\u0443\u0441\u0442\u044c \u0443 \u043d\u0430\u0441 \u0435\u0441\u0442\u044c \u0434\u0432\u0435 \u0442\u043e\u0447\u043a\u0438 A \u0438 B \u2014 \u043d\u0435\u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e \u043e\u0442 \u0440\u0430\u0437\u043c\u0435\u0440\u043d\u043e\u0441\u0442\u0438: 1, 2, 3,\u2026, n, \u2014 \u0442\u043e\u0433\u0434\u0430 \u0432\u0435\u043a\u0442\u043e\u0440, \u0438\u0434\u0443\u0449\u0438\u0439 \u043e\u0442 A \u043a B, \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u043d\u0430\u0439\u0434\u0435\u043d \u043f\u0443\u0442\u0435\u043c \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u044f B \u2014 A (\u043f\u043e\u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043d\u043e);<\/p>\n<\/li>\n<li>\n<p>\u0414\u043b\u0438\u043d\u0443 \u0432\u0435\u043a\u0442\u043e\u0440\u0430 \u2014 \u043d\u0435\u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e \u043e\u0442 \u0435\u0433\u043e \u0440\u0430\u0437\u043c\u0435\u0440\u043d\u043e\u0441\u0442\u0438 \u2014 \u043c\u043e\u0436\u043d\u043e \u043d\u0430\u0439\u0442\u0438, \u0432\u044b\u0447\u0438\u0441\u043b\u0438\u0432 \u043a\u0432\u0430\u0434\u0440\u0430\u0442\u043d\u044b\u0439 \u043a\u043e\u0440\u0435\u043d\u044c \u0438\u0437 \u0441\u0443\u043c\u043c\u044b \u0432\u043e\u0437\u0432\u0435\u0434\u0435\u043d\u043d\u044b\u0445 \u0432 \u043a\u0432\u0430\u0434\u0440\u0430\u0442 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432. \u0414\u043b\u0438\u043d\u0430 \u0432\u0435\u043a\u0442\u043e\u0440\u0430 v \u043e\u0431\u043e\u0437\u043d\u0430\u0447\u0430\u0435\u0442\u0441\u044f ||v||;<\/p>\n<\/li>\n<li>\n<p><em>\u0415\u0434\u0438\u043d\u0438\u0447\u043d\u044b\u0439 \u0432\u0435\u043a\u0442\u043e\u0440<\/em> \u2014 \u044d\u0442\u043e \u0432\u0435\u043a\u0442\u043e\u0440 \u0434\u043b\u0438\u043d\u044b 1: ||v|| = 1;<\/p>\n<\/li>\n<li>\n<p>\u0414\u043b\u044f \u0434\u0430\u043d\u043d\u043e\u0433\u043e \u0432\u0435\u043a\u0442\u043e\u0440\u0430 \u0434\u0440\u0443\u0433\u043e\u0439 \u0432\u0435\u043a\u0442\u043e\u0440, \u0438\u0434\u0443\u0449\u0438\u0439 \u0432 \u0442\u043e\u043c \u0436\u0435 \u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0438, \u043d\u043e \u0438\u043c\u0435\u044e\u0449\u0438\u0439 \u0434\u043b\u0438\u043d\u0443 1, \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u043d\u0430\u0439\u0434\u0435\u043d \u043f\u0443\u0442\u0435\u043c \u0434\u0435\u043b\u0435\u043d\u0438\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430 \u043f\u0435\u0440\u0432\u043e\u0433\u043e \u0432\u0435\u043a\u0442\u043e\u0440\u0430 \u043d\u0430 \u0435\u0433\u043e \u0434\u043b\u0438\u043d\u0443 \u2014 \u044d\u0442\u043e \u043d\u0430\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u043d\u043e\u0440\u043c\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0435\u0439: u = v\/||v||;<\/p>\n<\/li>\n<li>\n<p>\u0422\u043e\u0447\u0435\u0447\u043d\u043e\u0435 \u043f\u0440\u043e\u0438\u0437\u0432\u0435\u0434\u0435\u043d\u0438\u0435 \u0434\u043b\u044f \u0432\u0435\u043a\u0442\u043e\u0440\u043e\u0432 \u0432\u044b\u0447\u0438\u0441\u043b\u044f\u0435\u0442\u0441\u044f \u043a\u0430\u043a: &lt;v, v&gt; = ||v||\u00b2.<\/p>\n<\/li>\n<\/ul>\n<h3>\u0410\u043b\u0433\u043e\u0440\u0438\u0442\u043c \u0442\u0440\u0430\u0441\u0441\u0438\u0440\u043e\u0432\u043a\u0438 \u043b\u0443\u0447\u0435\u0439<\/h3>\n<p><em>\u0422\u0440\u0430\u0441\u0441\u0438\u0440\u043e\u0432\u043a\u0430 \u043b\u0443\u0447\u0435\u0439<\/em> \u2014 \u044d\u0442\u043e \u043c\u0435\u0442\u043e\u0434 <strong>\u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433\u0430<\/strong>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0438\u043c\u0438\u0442\u0438\u0440\u0443\u0435\u0442 <strong>\u043f\u0443\u0442\u044c \u0441\u0432\u0435\u0442\u0430<\/strong> \u0438 <strong>\u043f\u0435\u0440\u0435\u0441\u0435\u0447\u0435\u043d\u0438\u044f \u0441 \u043e\u0431\u044a\u0435\u043a\u0442\u0430\u043c\u0438<\/strong> \u0438 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u0441 \u0432\u044b\u0441\u043e\u043a\u043e\u0439 \u0441\u0442\u0435\u043f\u0435\u043d\u044c\u044e \u0440\u0435\u0430\u043b\u0438\u0437\u043c\u0430. \u0411\u043e\u043b\u0435\u0435 \u043e\u043f\u0442\u0438\u043c\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u044b \u044d\u0442\u043e\u0433\u043e \u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c\u0430 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442\u0441\u044f \u0432 \u0432\u0438\u0434\u0435\u043e\u0438\u0433\u0440\u0430\u0445.<\/p>\n<p>\u0427\u0442\u043e\u0431\u044b \u043e\u0431\u044a\u044f\u0441\u043d\u0438\u0442\u044c \u0440\u0430\u0431\u043e\u0442\u0443 \u044d\u0442\u043e\u0433\u043e \u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c\u0430, \u0441\u043d\u0430\u0447\u0430\u043b\u0430 \u043d\u0443\u0436\u043d\u043e \u043d\u0430\u0441\u0442\u0440\u043e\u0438\u0442\u044c \u0441\u0446\u0435\u043d\u0443:<\/p>\n<ul>\n<li>\n<p><strong>\u0422\u0440\u0435\u0445\u043c\u0435\u0440\u043d\u043e\u0435 \u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u043e<\/strong> (\u043c\u044b \u0441\u043e\u0431\u0438\u0440\u0430\u0435\u043c\u0441\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0442\u0440\u0438 \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u044b \u0434\u043b\u044f \u043f\u043e\u0437\u0438\u0446\u0438\u043e\u043d\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432 \u0432 \u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u0435);<\/p>\n<\/li>\n<li>\n<p><strong>\u041e\u0431\u044a\u0435\u043a\u0442\u044b<\/strong> \u0432 \u044d\u0442\u043e\u043c \u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u0435 (\u043f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u043c\u044b \u0441\u043e\u0431\u0438\u0440\u0430\u0435\u043c\u0441\u044f \u0432\u043e\u0441\u043f\u0440\u043e\u0438\u0437\u0432\u0435\u0441\u0442\u0438 \u0440\u0438\u0441. 1, \u0442\u043e \u0432\u043e\u0437\u044c\u043c\u0435\u043c \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432 \u0441\u0444\u0435\u0440\u044b);<\/p>\n<\/li>\n<li>\n<p><strong>\u0418\u0441\u0442\u043e\u0447\u043d\u0438\u043a \u0441\u0432\u0435\u0442\u0430<\/strong> (\u0432 \u043d\u0430\u0448\u0435\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u044d\u0442\u043e \u043e\u0434\u043d\u0430 \u0442\u043e\u0447\u043a\u0430, \u0438\u0437\u043b\u0443\u0447\u0430\u044e\u0449\u0430\u044f \u0441\u0432\u0435\u0442 \u0432\u043e \u0432\u0441\u0435\u0445 \u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f\u0445);<\/p>\n<\/li>\n<li>\n<p><strong>\u041a\u0430\u043c\u0435\u0440\u0430<\/strong> \u0434\u043b\u044f \u043d\u0430\u0431\u043b\u044e\u0434\u0435\u043d\u0438\u044f \u0437\u0430 \u0441\u0446\u0435\u043d\u043e\u0439;<\/p>\n<\/li>\n<li>\n<p><strong>\u042d\u043a\u0440\u0430\u043d<\/strong>, \u0447\u0435\u0440\u0435\u0437 \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043a\u0430\u043c\u0435\u0440\u0430 \u0441\u043c\u043e\u0442\u0440\u0438\u0442 \u043d\u0430 \u043e\u0431\u044a\u0435\u043a\u0442\u044b (\u0447\u0435\u0442\u044b\u0440\u0435 \u0442\u043e\u0447\u043a\u0438 \u0434\u043b\u044f \u0447\u0435\u0442\u044b\u0440\u0435\u0445 \u0443\u0433\u043b\u043e\u0432 \u043f\u0440\u044f\u043c\u043e\u0443\u0433\u043e\u043b\u044c\u043d\u043e\u0433\u043e \u044d\u043a\u0440\u0430\u043d\u0430).<\/p>\n<\/li>\n<\/ul>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/891\/7d4\/d5b\/8917d4d5bbe8ec837628b3f5ba362f27.png\" alt=\"\u0420\u0438\u0441\u0443\u043d\u043e\u043a 2\" title=\"\u0420\u0438\u0441\u0443\u043d\u043e\u043a 2\" width=\"1600\" height=\"1160\"><figcaption>\u0420\u0438\u0441\u0443\u043d\u043e\u043a 2<\/figcaption><\/figure>\n<p><strong><em>\u042d\u043a\u0440\u0430\u043d<\/em><\/strong> \u2014 \u044d\u0442\u043e \u043d\u0435\u043a\u0430\u044f \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u0430\u044f \u0432\u0430\u043c\u0438 \u0433\u0435\u043e\u043c\u0435\u0442\u0440\u0438\u0447\u0435\u0441\u043a\u0430\u044f \u0444\u0438\u0433\u0443\u0440\u0430 (\u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u043f\u0440\u044f\u043c\u043e\u0443\u0433\u043e\u043b\u044c\u043d\u0438\u043a 3&#215;2). \u041d\u043e \u0441\u0430\u043c\u0438 \u043f\u043e \u0441\u0435\u0431\u0435 \u0446\u0438\u0444\u0440\u044b 3 \u0438 2 \u043d\u0438 \u043e \u0447\u0435\u043c \u043d\u0430\u043c \u043d\u0435 \u0433\u043e\u0432\u043e\u0440\u044f\u0442 \u0438 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u043d\u0430\u0447\u0438\u043d\u0430\u044e\u0442 \u043f\u0440\u0438\u043e\u0431\u0440\u0435\u0442\u0430\u0442\u044c \u043a\u0430\u043a\u043e\u0435-\u0442\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u0440\u0438 \u0441\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u0438 \u0438\u0445 \u0441 \u0440\u0430\u0437\u043c\u0435\u0440\u0430\u043c\u0438 \u0434\u0440\u0443\u0433\u0438\u0445 \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432. \u0417\u0434\u0435\u0441\u044c \u0432\u0430\u0436\u043d\u043e \u0442\u043e, \u043a\u0430\u043a \u0432\u044b \u0440\u0430\u0437\u0434\u0435\u043b\u0438\u0442\u0435 \u0432\u0430\u0448 \u043f\u0440\u044f\u043c\u043e\u0443\u0433\u043e\u043b\u044c\u043d\u0438\u043a \u043d\u0430 \u0431\u043e\u043b\u0435\u0435 \u043c\u0435\u043b\u043a\u0438\u0435 \u043a\u0432\u0430\u0434\u0440\u0430\u0442\u044b (\u043f\u0438\u043a\u0441\u0435\u043b\u0438), \u043a\u0430\u043a \u043d\u0430 \u0440\u0438\u0441\u0443\u043d\u043a\u0435 \u0432\u044b\u0448\u0435. \u042d\u0442\u043e \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u0442 \u0440\u0430\u0437\u043c\u0435\u0440 \u043a\u043e\u043d\u0435\u0447\u043d\u043e\u0433\u043e \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f. \u0414\u0440\u0443\u0433\u0438\u043c\u0438 \u0441\u043b\u043e\u0432\u0430\u043c\u0438, \u043c\u043e\u0436\u043d\u043e \u0432\u0437\u044f\u0442\u044c \u043f\u0440\u044f\u043c\u043e\u0443\u0433\u043e\u043b\u044c\u043d\u0438\u043a 3&#215;2 \u0438 \u0440\u0430\u0437\u0434\u0435\u043b\u0438\u0442\u044c \u0435\u0433\u043e \u043d\u0430 300&#215;200 \u043f\u0438\u043a\u0441\u0435\u043b\u0435\u0439.<\/p>\n<p>\u041d\u0430\u043f\u0438\u0448\u0435\u043c \u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c \u0442\u0440\u0430\u0441\u0441\u0438\u0440\u043e\u0432\u043a\u0438 \u043b\u0443\u0447\u0435\u0439 \u0441 \u0443\u0447\u0435\u0442\u043e\u043c \u0437\u0430\u0434\u0430\u043d\u043d\u043e\u0439 <strong>\u0441\u0446\u0435\u043d\u044b<\/strong>:<\/p>\n<blockquote>\n<p><em>\u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u043f\u0438\u043a\u0441\u0435\u043b\u044f <\/em><strong><em>p<\/em><\/strong><em>(x, y, z) \u044d\u043a\u0440\u0430\u043d\u0430:<\/em><\/p>\n<p><em>&nbsp;&nbsp;&nbsp;\u0430\u0441\u0441\u043e\u0446\u0438\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0447\u0435\u0440\u043d\u044b\u0439 \u0446\u0432\u0435\u0442 \u0441 <\/em><strong><em>p<\/em><\/strong><\/p>\n<p><em>&nbsp;&nbsp;&nbsp;\u0435\u0441\u043b\u0438 \u043b\u0443\u0447 (\u043b\u0438\u043d\u0438\u044f), \u043d\u0430\u0447\u0438\u043d\u0430\u044e\u0449\u0438\u0439\u0441\u044f \u043e\u0442 <\/em><strong><em>\u043a\u0430\u043c\u0435\u0440\u044b<\/em><\/strong><em> \u0438 \u0438\u0434\u0443\u0449\u0438\u0439 \u043a \u0442\u043e\u0447\u043a\u0435 <\/em><strong><em>p<\/em><\/strong><em>, \u043f\u0435\u0440\u0435\u0441\u0435\u043a\u0430\u0435\u0442 \u043b\u044e\u0431\u043e\u0439 \u043e\u0431\u044a\u0435\u043a\u0442 \u0441\u0446\u0435\u043d\u044b, \u0442\u043e:<\/em><\/p>\n<p><em>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\u0432\u044b\u0447\u0438\u0441\u043b\u0438\u0442\u044c <\/em><strong><em>\u0442\u043e\u0447\u043a\u0443 \u043f\u0435\u0440\u0435\u0441\u0435\u0447\u0435\u043d\u0438\u044f<\/em><\/strong><em> \u0441 \u0431\u043b\u0438\u0436\u0430\u0439\u0448\u0438\u043c \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u043c<\/em><\/p>\n<p><em>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\u0435\u0441\u043b\u0438 \u043c\u0435\u0436\u0434\u0443 <\/em><strong><em>\u0442\u043e\u0447\u043a\u043e\u0439 \u043f\u0435\u0440\u0435\u0441\u0435\u0447\u0435\u043d\u0438\u044f<\/em><\/strong><em> \u0438 \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a\u043e\u043c <\/em><strong><em>\u0441\u0432\u0435\u0442\u0430<\/em><\/strong><em> \u043d\u0435\u0442 \u043e\u0431\u044a\u0435\u043a\u0442\u0430, \u0442\u043e\u0433\u0434\u0430:<\/em><\/p>\n<p><em>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\u0440\u0430\u0441\u0441\u0447\u0438\u0442\u0430\u0442\u044c \u0446\u0432\u0435\u0442 <\/em><strong><em>\u0442\u043e\u0447\u043a\u0438 \u043f\u0435\u0440\u0435\u0441\u0435\u0447\u0435\u043d\u0438\u044f<\/em><\/strong><\/p>\n<p><em>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\u0441\u043e\u043f\u043e\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u0446\u0432\u0435\u0442 <\/em><strong><em>\u0442\u043e\u0447\u043a\u0438 \u043f\u0435\u0440\u0435\u0441\u0435\u0447\u0435\u043d\u0438\u044f<\/em><\/strong><em> \u0441 <\/em><strong><em>p<\/em><\/strong><\/p>\n<\/blockquote>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/e63\/a89\/0cd\/e63a890cdc86d47dad9a95e6cc604d95.png\" alt=\"\u0420\u0438\u0441\u0443\u043d\u043e\u043a 3\" title=\"\u0420\u0438\u0441\u0443\u043d\u043e\u043a 3\" width=\"1600\" height=\"1254\"><figcaption>\u0420\u0438\u0441\u0443\u043d\u043e\u043a 3<\/figcaption><\/figure>\n<p><em>\u041e\u0431\u0440\u0430\u0442\u0438\u0442\u0435 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435, \u0447\u0442\u043e \u044d\u0442\u043e\u0442 \u043f\u0440\u043e\u0446\u0435\u0441\u0441 \u043d\u0430 \u0434\u0435\u043b\u0435 \u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u043e\u0431\u0440\u0430\u0442\u043d\u044b\u043c \u0440\u0435\u0430\u043b\u044c\u043d\u043e\u043c\u0443 \u043e\u0441\u0432\u0435\u0449\u0435\u043d\u0438\u044e. \u0412\u0435\u0434\u044c \u0440\u0435\u0430\u043b\u044c\u043d\u044b\u0439 \u0441\u0432\u0435\u0442 \u0432\u044b\u0445\u043e\u0434\u0438\u0442 \u0438\u0437 \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a\u0430 \u0432\u043e \u0432\u0441\u0435\u0445 \u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f\u0445, \u043e\u0442\u0440\u0430\u0436\u0430\u0435\u0442\u0441\u044f \u043e\u0442 \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432 \u0438 \u043f\u043e\u043f\u0430\u0434\u0430\u0435\u0442 \u0432 \u043a\u0430\u043c\u0435\u0440\u0443. \u041e\u0434\u043d\u0430\u043a\u043e, \u043f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u043d\u0435 \u0432\u0441\u0435 \u043b\u0443\u0447\u0438, \u0432\u044b\u0445\u043e\u0434\u044f\u0449\u0438\u0435 \u0438\u0437 \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a\u0430 \u0441\u0432\u0435\u0442\u0430, \u043f\u043e\u043f\u0430\u0434\u0443\u0442 \u0432 \u043a\u0430\u043c\u0435\u0440\u0443, \u0442\u0440\u0430\u0441\u0441\u0438\u0440\u043e\u0432\u043a\u0430 \u043b\u0443\u0447\u0435\u0439 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442 \u043e\u0431\u0440\u0430\u0442\u043d\u044b\u0439 \u043f\u0440\u043e\u0446\u0435\u0441\u0441 \u0434\u043b\u044f \u044d\u043a\u043e\u043d\u043e\u043c\u0438\u0438 \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u0439 (\u043e\u0442\u0441\u043b\u0435\u0436\u0438\u0432\u0430\u0435\u0442 \u043b\u0443\u0447\u0438 \u043e\u0442 \u043a\u0430\u043c\u0435\u0440\u044b \u043e\u0431\u0440\u0430\u0442\u043d\u043e \u043a \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a\u0443 \u0441\u0432\u0435\u0442\u0430).<\/em><\/p>\n<h3>\u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430 \u0441\u0446\u0435\u043d\u044b<\/h3>\n<p>\u041f\u0435\u0440\u0435\u0434 \u0442\u0435\u043c, \u043a\u0430\u043a \u043d\u0430\u0447\u0430\u0442\u044c \u043f\u0438\u0441\u0430\u0442\u044c \u043a\u043e\u0434, \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u043d\u0430\u0441\u0442\u0440\u043e\u0438\u0442\u044c \u0441\u0446\u0435\u043d\u0443. \u0412 \u043f\u0435\u0440\u0432\u0443\u044e \u043e\u0447\u0435\u0440\u0435\u0434\u044c \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u043c\u0441\u044f, \u0433\u0434\u0435 \u0440\u0430\u0441\u043f\u043e\u043b\u043e\u0436\u0435\u043d\u044b <strong><em>\u043a\u0430\u043c\u0435\u0440\u0430<\/em><\/strong> \u0438 <strong><em>\u044d\u043a\u0440\u0430\u043d<\/em><\/strong>. \u0414\u043b\u044f \u044d\u0442\u043e\u0439 \u0446\u0435\u043b\u0438 \u043f\u0440\u0438\u043c\u0435\u043c \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0443\u043f\u0440\u043e\u0449\u0435\u043d\u0438\u044f, \u0441\u043e\u0432\u043c\u0435\u0441\u0442\u0438\u0432 \u043e\u0431\u044a\u0435\u043a\u0442\u044b \u0441 \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u043d\u044b\u043c\u0438 \u043e\u0441\u044f\u043c\u0438.<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/921\/886\/1a9\/9218861a9f5b97fe715bc02f5b43ba1d.png\" alt=\"\u0420\u0438\u0441\u0443\u043d\u043e\u043a 4\" title=\"\u0420\u0438\u0441\u0443\u043d\u043e\u043a 4\" width=\"1600\" height=\"1489\"><figcaption>\u0420\u0438\u0441\u0443\u043d\u043e\u043a 4<\/figcaption><\/figure>\n<p>\u0414\u043e\u043f\u0443\u0441\u0442\u0438\u043c, <strong><em>\u043a\u0430\u043c\u0435\u0440\u0430<\/em><\/strong> \u0440\u0430\u0441\u043f\u043e\u043b\u043e\u0436\u0435\u043d\u0430 \u0432 \u0442\u043e\u0447\u043a\u0435 (<strong>x = 0<\/strong>, <strong>y = 0<\/strong>, <strong>z = 1<\/strong>), \u0430 <strong><em>\u044d\u043a\u0440\u0430\u043d<\/em><\/strong> \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0447\u0430\u0441\u0442\u044c\u044e \u043f\u043b\u043e\u0441\u043a\u043e\u0441\u0442\u0438, \u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u043d\u043e\u0439 \u043e\u0441\u044f\u043c\u0438 <strong><em>x<\/em><\/strong> \u0438 <strong><em>y<\/em><\/strong>. \u0422\u0435\u043f\u0435\u0440\u044c \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u0441\u043a\u0435\u043b\u0435\u0442 \u043d\u0430\u0448\u0435\u0433\u043e \u043a\u043e\u0434\u0430.<\/p>\n<details class=\"spoiler\">\n<summary>\u041f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u043a\u043e\u0434<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"python\">import numpy as np import matplotlib.pyplot as plt width = 300 height = 200 camera = np.array([0, 0, 1]) ratio = float(width) \/ height screen = (-1, 1 \/ ratio, 1, -1 \/ ratio) # \u0441\u043b\u0435\u0432\u0430, \u0441\u0432\u0435\u0440\u0445\u0443, \u0441\u043f\u0440\u0430\u0432\u0430, \u0441\u043d\u0438\u0437\u0443 image = np.zeros((height, width, 3)) for i, y in enumerate(np.linspace(screen[1], screen[3], height)): &nbsp; &nbsp; for j, x in enumerate(np.linspace(screen[0], screen[2], width)): &nbsp; &nbsp; &nbsp; &nbsp; # image[i, j] = ... &nbsp; &nbsp; &nbsp; &nbsp; print(\"progress: %d\/%d\" % (i + 1, height)) plt.imsave('image.png', image)<\/code><\/pre>\n<\/div>\n<\/details>\n<ul>\n<li>\n<p><strong><em>\u041a\u0430\u043c\u0435\u0440\u0430<\/em><\/strong> \u2014 \u044d\u0442\u043e \u043f\u0440\u043e\u0441\u0442\u043e \u0442\u043e\u0447\u043a\u0430, \u0438\u043c\u0435\u044e\u0449\u0430\u044f \u0442\u0440\u0438 \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u044b;<\/p>\n<\/li>\n<li>\n<p>\u0421 \u0434\u0440\u0443\u0433\u043e\u0439 \u0441\u0442\u043e\u0440\u043e\u043d\u044b, <strong><em>\u044d\u043a\u0440\u0430\u043d<\/em><\/strong> \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u0442\u0441\u044f \u0447\u0435\u0442\u044b\u0440\u044c\u043c\u044f \u0447\u0438\u0441\u043b\u0430\u043c\u0438 (\u0438\u043b\u0438 \u0434\u0432\u0443\u043c\u044f \u0442\u043e\u0447\u043a\u0430\u043c\u0438): <em>\u0441\u043b\u0435\u0432\u0430, \u0441\u0432\u0435\u0440\u0445\u0443, \u0441\u043f\u0440\u0430\u0432\u0430, \u0441\u043d\u0438\u0437\u0443<\/em>. \u041e\u043d \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u0432 \u0434\u0438\u0430\u043f\u0430\u0437\u043e\u043d\u0435 \u043e\u0442 -1 \u0434\u043e 1 \u0432 \u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0438 <strong><em>x<\/em><\/strong> \u0438 \u043e\u0442 -1\/ratio \u0434\u043e 1\/ratio \u0432 \u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0438 <strong><em>y<\/em><\/strong>, \u0433\u0434\u0435 ratio \u2014 \u0448\u0438\u0440\u0438\u043d\u0430 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f, \u0434\u0435\u043b\u0435\u043d\u043d\u0430\u044f \u043d\u0430 \u0435\u0433\u043e \u0432\u044b\u0441\u043e\u0442\u0443. \u042d\u0442\u043e \u0432\u044b\u0442\u0435\u043a\u0430\u0435\u0442 \u0438\u0437 \u0442\u043e\u0433\u043e, \u0447\u0442\u043e \u043c\u044b \u0445\u043e\u0442\u0438\u043c, \u0447\u0442\u043e\u0431\u044b <strong><em>\u044d\u043a\u0440\u0430\u043d<\/em><\/strong> \u0438\u043c\u0435\u043b \u0442\u0430\u043a\u043e\u0435 \u0436\u0435 \u0441\u043e\u043e\u0442\u043d\u043e\u0448\u0435\u043d\u0438\u0435 \u0441\u0442\u043e\u0440\u043e\u043d, \u0447\u0442\u043e \u0438 \u0444\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u0435 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435. \u041f\u0440\u0438 \u0442\u0430\u043a\u043e\u0439 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0435 <strong><em>\u044d\u043a\u0440\u0430\u043d\u0430<\/em><\/strong> \u0431\u0443\u0434\u0435\u0442 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043e \u0441\u043e\u043e\u0442\u043d\u043e\u0448\u0435\u043d\u0438\u0435 \u0441\u0442\u043e\u0440\u043e\u043d (\u0448\u0438\u0440\u0438\u043d\u0430 \u043a \u0432\u044b\u0441\u043e\u0442\u0435): 2 \/(2\/ratio) = ratio, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u0438 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0441\u043e\u043e\u0442\u043d\u043e\u0448\u0435\u043d\u0438\u0435\u043c \u0441\u0442\u043e\u0440\u043e\u043d \u0436\u0435\u043b\u0430\u0435\u043c\u043e\u0433\u043e \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f 300&#215;200;<\/p>\n<\/li>\n<li>\n<p>\u0426\u0438\u043a\u043b \u0441\u043e\u0441\u0442\u043e\u0438\u0442 \u0438\u0437 \u0440\u0430\u0437\u0434\u0435\u043b\u0435\u043d\u0438\u044f \u044d\u043a\u0440\u0430\u043d\u0430 \u043d\u0430 \u0442\u043e\u0447\u043a\u0438 \u0432 \u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f\u0445 <strong><em>x<\/em><\/strong> \u0438 <strong><em>y<\/em><\/strong>, \u0437\u0430\u0442\u0435\u043c \u0432\u044b\u0447\u0438\u0441\u043b\u044f\u0435\u0442\u0441\u044f \u0446\u0432\u0435\u0442 \u0442\u0435\u043a\u0443\u0449\u0435\u0433\u043e \u043f\u0438\u043a\u0441\u0435\u043b\u044f;<\/p>\n<\/li>\n<li>\n<p>\u041f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u044b\u0439 \u043a\u043e\u0434 \u0441\u043e\u0437\u0434\u0430\u0441\u0442 \u2014 \u043a\u0430\u043a \u0438 \u043e\u0436\u0438\u0434\u0430\u043b\u043e\u0441\u044c \u043d\u0430 \u0434\u0430\u043d\u043d\u043e\u043c \u044d\u0442\u0430\u043f\u0435 \u2014 \u0447\u0435\u0440\u043d\u043e\u0435 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435.&nbsp;<\/p>\n<\/li>\n<\/ul>\n<h3>\u041f\u0435\u0440\u0435\u0441\u0435\u0447\u0435\u043d\u0438\u0435 \u043b\u0443\u0447\u0435\u0439<\/h3>\n<p>\u0421\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u0448\u0430\u0433 \u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c\u0430: <em>\u0435\u0441\u043b\u0438 \u043b\u0443\u0447 (\u043b\u0438\u043d\u0438\u044f), \u043d\u0430\u0447\u0438\u043d\u0430\u044e\u0449\u0438\u0439\u0441\u044f \u043e\u0442 <\/em><strong><em>\u043a\u0430\u043c\u0435\u0440\u044b<\/em><\/strong><em> \u0438 \u043f\u0440\u043e\u0445\u043e\u0434\u044f\u0449\u0438\u0439 \u043a \u0442\u043e\u0447\u043a\u0435 <\/em><strong><em>p<\/em><\/strong><em>, \u043f\u0435\u0440\u0435\u0441\u0435\u043a\u0430\u0435\u0442 \u043e\u0431\u044a\u0435\u043a\u0442 \u0441\u0446\u0435\u043d\u044b, \u0442\u043e\u0433\u0434\u0430&#8230;<\/em><\/p>\n<p>\u0420\u0430\u0437\u043e\u0431\u044c\u0435\u043c \u0435\u0433\u043e \u043d\u0430 \u0434\u0432\u0435 \u0447\u0430\u0441\u0442\u0438. \u0418 \u043d\u0430\u0447\u043d\u0435\u043c \u0441 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u044f \u0442\u043e\u0433\u043e, \u043a\u0430\u043a\u043e\u0439 \u043b\u0443\u0447 (\u043b\u0438\u043d\u0438\u044f) \u043d\u0430\u0447\u0438\u043d\u0430\u0435\u0442\u0441\u044f \u043e\u0442 <strong><em>\u043a\u0430\u043c\u0435\u0440\u044b<\/em><\/strong> \u0438 \u0438\u0434\u0435\u0442 \u043a \u0442\u043e\u0447\u043a\u0435 <strong><em>p<\/em><\/strong>?<\/p>\n<h3>\u041e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u0435 \u043b\u0443\u0447\u0430<\/h3>\n<p>\u041a\u043e\u0433\u0434\u0430 \u043c\u044b \u0433\u043e\u0432\u043e\u0440\u0438\u043c \u00ab<em>\u043b\u0443\u0447<\/em>\u00bb, \u043d\u0430 \u0441\u0430\u043c\u043e\u043c \u0434\u0435\u043b\u0435 \u043c\u044b \u0438\u043c\u0435\u0435\u043c \u0432 \u0432\u0438\u0434\u0443 \u0441\u043a\u043e\u0440\u0435\u0435 \u00ab<em>\u043b\u0438\u043d\u0438\u044e<\/em>\u00bb. \u0412\u0441\u044f\u043a\u0438\u0439 \u0440\u0430\u0437 \u043f\u0440\u0438 \u0440\u0430\u0431\u043e\u0442\u0435 \u0441 \u0433\u0435\u043e\u043c\u0435\u0442\u0440\u0438\u0435\u0439 \u043b\u0443\u0447\u0448\u0435 \u043e\u0442\u0434\u0430\u0442\u044c \u043f\u0440\u0435\u0434\u043f\u043e\u0447\u0442\u0435\u043d\u0438\u0435 \u0432\u0435\u043a\u0442\u043e\u0440\u0430\u043c, \u0447\u0435\u043c \u0440\u0435\u0430\u043b\u044c\u043d\u044b\u043c \u043b\u0438\u043d\u0435\u0439\u043d\u044b\u043c \u0443\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u044f\u043c: \u0441 \u043d\u0438\u043c\u0438 \u043b\u0435\u0433\u0447\u0435 \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c, \u0438 \u043e\u043d\u0438 \u0433\u043e\u0440\u0430\u0437\u0434\u043e \u043c\u0435\u043d\u0435\u0435 \u043f\u043e\u0434\u0432\u0435\u0440\u0436\u0435\u043d\u044b \u043e\u0448\u0438\u0431\u043a\u0430\u043c, \u0442\u0430\u043a\u0438\u043c \u043a\u0430\u043a \u0434\u0435\u043b\u0435\u043d\u0438\u0435 \u043d\u0430 \u043d\u043e\u043b\u044c.<\/p>\n<p>\u0418\u0442\u0430\u043a, \u043f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u043b\u0443\u0447 \u043d\u0430\u0447\u0438\u043d\u0430\u0435\u0442\u0441\u044f \u043e\u0442 <strong><em>\u043a\u0430\u043c\u0435\u0440\u044b<\/em><\/strong> \u0438 \u0438\u0434\u0435\u0442 \u0432 \u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0438 \u0442\u0435\u043a\u0443\u0449\u0435\u0433\u043e \u0446\u0435\u043b\u0435\u0432\u043e\u0433\u043e <strong><em>\u043f\u0438\u043a\u0441\u0435\u043b\u044f<\/em><\/strong>, \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u0442\u044c \u0435\u0434\u0438\u043d\u0438\u0447\u043d\u044b\u0439 \u0432\u0435\u043a\u0442\u043e\u0440, \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u044e\u0449\u0438\u0439 \u0432 \u0442\u043e\u043c \u0436\u0435 \u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0438. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u043c\u044b \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u043c \u043d\u0430\u0448 \u043b\u0443\u0447 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u0443\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u0435\u043c:<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/162\/7a4\/7fd\/1627a47fdcfdd604bd30c97656823d1c.png\" width=\"524\" height=\"73\"><figcaption><\/figcaption><\/figure>\n<p>\u041f\u043e\u043c\u043d\u0438\u0442\u0435, \u0447\u0442\u043e <strong><em>\u043a\u0430\u043c\u0435\u0440\u0430<\/em><\/strong> \u0438 <strong><em>\u043f\u0438\u043a\u0441\u0435\u043b\u044c<\/em><\/strong> \u2014 \u044d\u0442\u043e 3D-\u0442\u043e\u0447\u043a\u0438. \u041f\u0440\u0438 t = 0 \u0432\u044b \u043e\u043a\u0430\u0436\u0435\u0442\u0435\u0441\u044c \u0432 \u043f\u043e\u043b\u043e\u0436\u0435\u043d\u0438\u0438 <strong><em>\u043a\u0430\u043c\u0435\u0440\u044b<\/em><\/strong>, \u043d\u043e \u0441 \u0443\u0432\u0435\u043b\u0438\u0447\u0435\u043d\u0438\u0435\u043c t \u0431\u0443\u0434\u0435\u0442\u0435 \u0443\u0434\u0430\u043b\u044f\u0442\u044c\u0441\u044f \u043e\u0442 \u043d\u0435\u0435 \u0432 \u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0438 <strong><em>\u043f\u0438\u043a\u0441\u0435\u043b\u044f<\/em><\/strong>. \u042d\u0442\u043e \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0438\u0447\u0435\u0441\u043a\u043e\u0435 \u0443\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u0435, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u0434\u0430\u0441\u0442 <strong><em>\u0442\u043e\u0447\u043a\u0443<\/em><\/strong> \u0432\u0434\u043e\u043b\u044c \u043b\u0438\u043d\u0438\u0438 \u0434\u043b\u044f \u043b\u044e\u0431\u043e\u0433\u043e t.<\/p>\n<p>\u041a\u043e\u043d\u0435\u0447\u043d\u043e, \u0442\u043e\u0447\u043d\u043e \u0442\u0430\u043a \u0436\u0435 \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u043f\u0435\u0440\u0435\u043f\u0438\u0441\u0430\u0442\u044c \u0443\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u0435 \u0438 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u0442\u044c \u043b\u0443\u0447, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043d\u0430\u0447\u0438\u043d\u0430\u0435\u0442\u0441\u044f \u0432 \u0438\u0441\u0445\u043e\u0434\u043d\u043e\u0439 \u0442\u043e\u0447\u043a\u0435 (O) \u0438 \u0438\u0434\u0435\u0442 \u043a \u043c\u0435\u0441\u0442\u0443 \u043d\u0430\u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f (D) \u043a\u0430\u043a:<\/p>\n<figure class=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/8f1\/955\/346\/8f195534634dd508cb0997ad5fcd001b.png\" width=\"327\" height=\"113\"><figcaption><\/figcaption><\/figure>\n<p>\u0414\u043b\u044f \u0443\u0434\u043e\u0431\u0441\u0442\u0432\u0430 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u043c <strong><em>d<\/em><\/strong> \u043a\u0430\u043a \u0432\u0435\u043a\u0442\u043e\u0440 <strong><em>\u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f<\/em><\/strong>.<\/p>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043a \u043d\u0430\u0448\u0435\u043c\u0443 \u043a\u043e\u0434\u0443 \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u0435 \u043b\u0443\u0447\u0430:<\/p>\n<details class=\"spoiler\">\n<summary>\u041f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u043a\u043e\u0434<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"python\">import numpy as np import matplotlib.pyplot as plt def normalize(vector):     return vector \/ np.linalg.norm(vector) width = 300 height = 200 camera = np.array([0, 0, 1]) ratio = float(width) \/ height screen = (-1, 1 \/ ratio, 1, -1 \/ ratio) # \u0441\u043b\u0435\u0432\u0430, \u0441\u0432\u0435\u0440\u0445\u0443, \u0441\u043f\u0440\u0430\u0432\u0430, \u0441\u043d\u0438\u0437\u0443 image = np.zeros((height, width, 3)) for i, y in enumerate(np.linspace(screen[1], screen[3], height)):     for j, x in enumerate(np.linspace(screen[0], screen[2], width)):         pixel = np.array([x, y, 0])         origin = camera         direction = normalize(pixel - origin)         # image[i, j] = ...     print(\"progress: %d\/%d\" % (i + 1, height)) plt.imsave('image.png', image)<\/code><\/pre>\n<\/div>\n<\/details>\n<ul>\n<li>\n<p>\u041c\u044b \u0434\u043e\u0431\u0430\u0432\u0438\u043b\u0438 \u0432 \u043a\u043e\u0434 \u0444\u0443\u043d\u043a\u0446\u0438\u044e normalize(vector), \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442&#8230; \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u043e, \u043d\u043e\u0440\u043c\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u0432\u0435\u043a\u0442\u043e\u0440;<\/p>\n<\/li>\n<li>\n<p>\u0422\u0430\u043a\u0436\u0435 \u043c\u044b \u0434\u043e\u0431\u0430\u0432\u0438\u043b\u0438 \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u0435 \u0438\u0441\u0445\u043e\u0434\u043d\u043e\u0439 \u0442\u043e\u0447\u043a\u0438 \u0438 \u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0432\u043c\u0435\u0441\u0442\u0435 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u044e\u0442 \u043b\u0443\u0447. \u041e\u0431\u0440\u0430\u0442\u0438\u0442\u0435 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435, \u0447\u0442\u043e <strong><em>\u043f\u0438\u043a\u0441\u0435\u043b\u044c<\/em><\/strong> \u0438\u043c\u0435\u0435\u0442 \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u0443 z = 0, \u043f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u043e\u043d \u043b\u0435\u0436\u0438\u0442 \u043d\u0430 \u044d\u043a\u0440\u0430\u043d\u0435, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u0432 \u043f\u043b\u043e\u0441\u043a\u043e\u0441\u0442\u0438, \u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u043d\u043e\u0439 \u043e\u0441\u044f\u043c\u0438 <strong><em>x<\/em><\/strong> \u0438 <strong><em>y<\/em><\/strong>;<\/p>\n<\/li>\n<\/ul>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043f\u0435\u0440\u0435\u0439\u0434\u0435\u043c \u043a\u043e \u0432\u0442\u043e\u0440\u043e\u0439 \u0447\u0430\u0441\u0442\u0438, \u0433\u0434\u0435 \u043b\u0443\u0447 \u043f\u0435\u0440\u0435\u0441\u0435\u043a\u0430\u0435\u0442 \u043e\u0431\u044a\u0435\u043a\u0442 \u0441\u0446\u0435\u043d\u044b.  \u0414\u043b\u044f \u043f\u0440\u043e\u0441\u0442\u043e\u0442\u044b \u0431\u0443\u0434\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u0441\u0444\u0435\u0440\u044b.<\/p>\n<h3>\u041e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u0435 \u0441\u0444\u0435\u0440\u044b<\/h3>\n<p>\u0421\u0444\u0435\u0440\u0430 \u2014 \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u043f\u0440\u043e\u0441\u0442\u043e\u0439 \u043c\u0430\u0442\u0435\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u043e\u0431\u044a\u0435\u043a\u0442. \u041e\u043d\u0430 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u0442\u0441\u044f \u043a\u0430\u043a <em>\u043d\u0430\u0431\u043e\u0440 \u0442\u043e\u0447\u0435\u043a, \u043d\u0430\u0445\u043e\u0434\u044f\u0449\u0438\u0445\u0441\u044f \u043d\u0430 \u043e\u0434\u0438\u043d\u0430\u043a\u043e\u0432\u043e\u043c \u0440\u0430\u0441\u0441\u0442\u043e\u044f\u043d\u0438\u0438 r (\u0440\u0430\u0434\u0438\u0443\u0441) \u043e\u0442 \u0437\u0430\u0434\u0430\u043d\u043d\u043e\u0439 \u0442\u043e\u0447\u043a\u0438 (\u0446\u0435\u043d\u0442\u0440\u0430)<\/em>.<\/p>\n<p>\u0421\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e, \u0441 \u0443\u0447\u0435\u0442\u043e\u043c \u0446\u0435\u043d\u0442\u0440\u0430 <strong><em>C<\/em><\/strong> \u0441\u0444\u0435\u0440\u044b \u0438 \u0435\u0435 \u0440\u0430\u0434\u0438\u0443\u0441\u0430 <strong><em>r<\/em><\/strong> \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u043b\u044c\u043d\u0430\u044f \u0442\u043e\u0447\u043a\u0430 <strong><em>X<\/em><\/strong> \u043b\u0435\u0436\u0438\u0442 \u043d\u0430 \u0441\u0444\u0435\u0440\u0435 \u0442\u043e\u0433\u0434\u0430, \u043a\u043e\u0433\u0434\u0430:<\/p>\n<figure class=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/16d\/6b0\/423\/16d6b0423fd9e1742526671d03033f5a.png\" width=\"178\" height=\"31\"><figcaption><\/figcaption><\/figure>\n<p>\u0414\u043b\u044f \u0443\u0434\u043e\u0431\u0441\u0442\u0432\u0430 \u0432\u043e\u0437\u0432\u0435\u0434\u0435\u043c \u043e\u0431\u0435 \u0441\u0442\u043e\u0440\u043e\u043d\u044b \u0432 \u043a\u0432\u0430\u0434\u0440\u0430\u0442, \u0447\u0442\u043e\u0431\u044b \u0438\u0437\u0431\u0430\u0432\u0438\u0442\u044c\u0441\u044f \u043e\u0442 \u043a\u0432\u0430\u0434\u0440\u0430\u0442\u043d\u043e\u0433\u043e \u043a\u043e\u0440\u043d\u044f, \u043e\u0431\u0443\u0441\u043b\u043e\u0432\u043b\u0435\u043d\u043d\u043e\u0433\u043e \u0432\u0435\u043b\u0438\u0447\u0438\u043d\u043e\u0439 X \u2014 C:<\/p>\n<figure class=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/1a2\/821\/e80\/1a2821e801deaed49177423000bf52d7.png\" width=\"203\" height=\"35\"><figcaption><\/figcaption><\/figure>\n<p>\u041f\u043e\u0441\u043b\u0435 \u044d\u0442\u043e\u0433\u043e \u043c\u044b \u0441\u043c\u043e\u0436\u0435\u043c \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u0442\u044c \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0441\u0444\u0435\u0440\u044b \u0441\u0440\u0430\u0437\u0443 \u043f\u043e\u0441\u043b\u0435 \u043e\u0431\u044a\u044f\u0432\u043b\u0435\u043d\u0438\u044f \u044d\u043a\u0440\u0430\u043d\u0430:<\/p>\n<pre><code class=\"python\">objects = [    { 'center': np.array([-0.2, 0, -1]), 'radius': 0.7 },    { 'center': np.array([0.1, -0.3, 0]), 'radius': 0.1 },    { 'center': np.array([-0.3, 0, 0]), 'radius': 0.15 } ]<\/code><\/pre>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u0432\u044b\u0447\u0438\u0441\u043b\u0438\u043c \u043f\u0435\u0440\u0435\u0441\u0435\u0447\u0435\u043d\u0438\u0435 \u043b\u0443\u0447\u0430 \u0438 \u0441\u0444\u0435\u0440\u044b.<\/p>\n<h3>\u041f\u0435\u0440\u0435\u0441\u0435\u0447\u0435\u043d\u0438\u0435 \u0441\u043e \u0441\u0444\u0435\u0440\u043e\u0439<\/h3>\n<p>\u041c\u044b \u0437\u043d\u0430\u0435\u043c \u0443\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u0435 \u043b\u0443\u0447\u0435\u0439 \u0438 \u0437\u043d\u0430\u0435\u043c, \u043a\u0430\u043a\u043e\u043c\u0443 \u0443\u0441\u043b\u043e\u0432\u0438\u044e \u0434\u043e\u043b\u0436\u043d\u0430 \u0443\u0434\u043e\u0432\u043b\u0435\u0442\u0432\u043e\u0440\u044f\u0442\u044c \u0442\u043e\u0447\u043a\u0430, \u0447\u0442\u043e\u0431\u044b \u043e\u043d\u0430 \u043b\u0435\u0436\u0430\u043b\u0430 \u043d\u0430 \u0441\u0444\u0435\u0440\u0435. \u0412\u0441\u0435, \u0447\u0442\u043e \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c, \u044d\u0442\u043e \u043f\u043e\u0434\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u043e\u0434\u043d\u043e \u0443\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u0435 \u0432 \u0434\u0440\u0443\u0433\u043e\u0435 \u0438 \u0440\u0435\u0448\u0438\u0442\u044c \u0435\u0433\u043e \u043e\u0442\u043d\u043e\u0441\u0438\u0442\u0435\u043b\u044c\u043d\u043e t. \u0422\u043e \u0435\u0441\u0442\u044c, \u043d\u0430\u0439\u0442\u0438 \u043e\u0442\u0432\u0435\u0442 \u043d\u0430 \u0432\u043e\u043f\u0440\u043e\u0441: <em>\u0434\u043b\u044f \u043a\u0430\u043a\u043e\u0433\u043e t \u0442\u043e\u0447\u043a\u0430 \u043b\u0443\u0447\u0430 ray(t) \u043e\u043a\u0430\u0436\u0435\u0442\u0441\u044f \u043d\u0430 \u0441\u0444\u0435\u0440\u0435<\/em>?<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/c53\/b9e\/190\/c53b9e190246848d06c29aa6fd3cd195.png\" width=\"1400\" height=\"497\"><figcaption><\/figcaption><\/figure>\n<p>\u042d\u0442\u043e \u043e\u0431\u044b\u0447\u043d\u043e\u0435 \u043a\u0432\u0430\u0434\u0440\u0430\u0442\u043d\u043e\u0435 \u0443\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u0435, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u043f\u0440\u043e\u0441\u0442\u043e \u0440\u0435\u0448\u0430\u0435\u0442\u0441\u044f \u043e\u0442\u043d\u043e\u0441\u0438\u0442\u0435\u043b\u044c\u043d\u043e t. \u041c\u044b \u0431\u0443\u0434\u0435\u043c \u0432\u044b\u0437\u044b\u0432\u0430\u0442\u044c \u043a\u043e\u044d\u0444\u0444\u0438\u0446\u0438\u0435\u043d\u0442\u044b, \u0441\u0432\u044f\u0437\u0430\u043d\u043d\u044b\u0435 \u0441 t\u00b2, t\u00b9, t\u2070, <strong><em>a<\/em><\/strong>, <strong><em>b<\/em><\/strong> \u0438 <strong><em>c<\/em><\/strong>, \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0435\u043d\u043d\u043e. \u0412\u044b\u0447\u0438\u0441\u043b\u0438\u043c \u0434\u0438\u0441\u043a\u0440\u0438\u043c\u0438\u043d\u0430\u043d\u0442 \u044d\u0442\u043e\u0433\u043e \u0443\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u044f:<\/p>\n<figure class=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/cdf\/1c4\/282\/cdf1c42826aa6655ca506d375f827db6.png\" width=\"251\" height=\"167\"><figcaption><\/figcaption><\/figure>\n<p>\u041f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435 <strong><em>d<\/em><\/strong> \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0435\u0434\u0438\u043d\u0438\u0447\u043d\u044b\u043c \u0432\u0435\u043a\u0442\u043e\u0440\u043e\u043c, \u043f\u043e\u043b\u0443\u0447\u0438\u043c <strong><em>a<\/em><\/strong> = 1. \u041f\u043e\u0441\u043b\u0435 \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u044f \u0434\u0438\u0441\u043a\u0440\u0438\u043c\u0438\u043d\u0430\u043d\u0442\u0430 \u0443 \u043d\u0430\u0441 \u0435\u0441\u0442\u044c \u0442\u0440\u0438 \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u0430:<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/cc1\/2fa\/14e\/cc12fa14e2b01227f718e1059685ca1e.png\" alt=\"\u0420\u0438\u0441\u0443\u043d\u043e\u043a 5\" title=\"\u0420\u0438\u0441\u0443\u043d\u043e\u043a 5\" width=\"1400\" height=\"679\"><figcaption>\u0420\u0438\u0441\u0443\u043d\u043e\u043a 5<\/figcaption><\/figure>\n<p>\u0414\u043b\u044f \u043e\u0431\u043d\u0430\u0440\u0443\u0436\u0435\u043d\u0438\u044f \u043f\u0435\u0440\u0435\u0441\u0435\u0447\u0435\u043d\u0438\u0439 \u0431\u0443\u0434\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e <strong>\u0442\u0440\u0435\u0442\u0438\u0439<\/strong> \u0441\u043b\u0443\u0447\u0430\u0439. \u0417\u0430\u043f\u0438\u0448\u0435\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u044e, \u043e\u0442\u0432\u0435\u0447\u0430\u044e\u0449\u0443\u044e \u0437\u0430 \u043e\u0431\u043d\u0430\u0440\u0443\u0436\u0435\u043d\u0438\u0435 \u043f\u0435\u0440\u0435\u0441\u0435\u0447\u0435\u043d\u0438\u044f \u043b\u0443\u0447\u0430 \u0438 \u0441\u0444\u0435\u0440\u044b. \u041e\u043d\u0430 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u0440\u0430\u0441\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u043e\u0442 <strong><em>\u043d\u0430\u0447\u0430\u043b\u0430 \u043b\u0443\u0447\u0430<\/em><\/strong> \u0434\u043e <strong><em>\u0431\u043b\u0438\u0436\u0430\u0439\u0448\u0435\u0439 \u0442\u043e\u0447\u043a\u0438 \u043f\u0435\u0440\u0435\u0441\u0435\u0447\u0435\u043d\u0438\u044f<\/em><\/strong>, \u0435\u0441\u043b\u0438 \u043b\u0443\u0447 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u043f\u0435\u0440\u0435\u0441\u0435\u043a\u0430\u0435\u0442 \u0441\u0444\u0435\u0440\u0443, \u0438\u043d\u0430\u0447\u0435 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 None:<\/p>\n<details class=\"spoiler\">\n<summary>\u041f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u043a\u043e\u0434<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"python\">def sphere_intersect(center, radius, ray_origin, ray_direction):    b = 2 * np.dot(ray_direction, ray_origin \u2014 center)    c = np.linalg.norm(ray_origin \u2014 center) ** 2 \u2014 radius ** 2    delta = b ** 2 \u2014 4 * c    if delta &gt; 0:        t1 = (-b + np.sqrt(delta)) \/ 2        t2 = (-b \u2014 np.sqrt(delta)) \/ 2        if t1 &gt; 0 and t2 &gt; 0:            return min(t1, t2)    return None<\/code><\/pre>\n<\/div>\n<\/details>\n<p>\u041e\u0431\u0440\u0430\u0442\u0438\u0442\u0435 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435, \u0447\u0442\u043e \u043c\u044b \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c \u0442\u043e\u043b\u044c\u043a\u043e <strong>\u0431\u043b\u0438\u0436\u0430\u0439\u0448\u0435\u0435<\/strong> \u043f\u0435\u0440\u0435\u0441\u0435\u0447\u0435\u043d\u0438\u0435 \u0438\u0437 \u0434\u0432\u0443\u0445 \u0442\u043e\u0433\u0434\u0430, \u043a\u043e\u0433\u0434\u0430 \u043e\u0431\u0430 t1 \u0438 t2 \u043f\u043e\u043b\u043e\u0436\u0438\u0442\u0435\u043b\u044c\u043d\u044b. \u042d\u0442\u043e \u0441\u0432\u044f\u0437\u0430\u043d\u043e \u0441 \u0442\u0435\u043c, \u0447\u0442\u043e \u043e\u0442\u0432\u0435\u0442 \u0443\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u044f \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u043e\u0442\u0440\u0438\u0446\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u043c, \u0438 \u0432 \u0442\u0430\u043a\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u043b\u0443\u0447, \u043f\u0435\u0440\u0435\u0441\u0435\u043a\u0430\u044e\u0449\u0438\u0439 \u0441\u0444\u0435\u0440\u0443, \u0431\u0443\u0434\u0435\u0442 \u0438\u043c\u0435\u0442\u044c \u043d\u0435 <strong><em>d<\/em><\/strong> \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0432\u0435\u043a\u0442\u043e\u0440\u0430 \u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f, \u0430 &#8212;<strong><em>d<\/em><\/strong> (\u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0435\u0441\u043b\u0438 \u0441\u0444\u0435\u0440\u0430 \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u0437\u0430 \u043a\u0430\u043c\u0435\u0440\u043e\u0439 \u0438 \u044d\u043a\u0440\u0430\u043d\u043e\u043c).<\/p>\n<h3>\u0411\u043b\u0438\u0436\u0430\u0439\u0448\u0438\u0439 \u043f\u0435\u0440\u0435\u0441\u0435\u043a\u0430\u0435\u043c\u044b\u0439 \u043e\u0431\u044a\u0435\u043a\u0442<\/h3>\n<p>\u041f\u043e\u043a\u0430 \u043c\u044b \u0432\u0441\u0435 \u0435\u0449\u0435 \u043d\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u043b\u0438 \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u044e \u0438\u0437 \u043f\u0441\u0435\u0432\u0434\u043e\u043a\u043e\u0434\u0430: <em>\u0435\u0441\u043b\u0438 \u043b\u0443\u0447 (\u043b\u0438\u043d\u0438\u044f), \u043d\u0430\u0447\u0438\u043d\u0430\u044e\u0449\u0438\u0439\u0441\u044f \u043e\u0442 <\/em><strong><em>\u043a\u0430\u043c\u0435\u0440\u044b<\/em><\/strong><em> \u0438 \u0438\u0434\u0443\u0449\u0438\u0439 \u043a \u0442\u043e\u0447\u043a\u0435 <\/em><strong><em>p<\/em><\/strong><em>, \u043f\u0435\u0440\u0435\u0441\u0435\u043a\u0430\u0435\u0442 \u043b\u044e\u0431\u043e\u0439 \u043e\u0431\u044a\u0435\u043a\u0442 \u0441\u0446\u0435\u043d\u044b, \u0442\u043e [&#8230;]<\/em>. \u0422\u0435\u043f\u0435\u0440\u044c \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u0432\u044b\u0447\u0438\u0441\u043b\u0438\u0442\u044c <strong><em>\u0442\u043e\u0447\u043a\u0443 \u043f\u0435\u0440\u0435\u0441\u0435\u0447\u0435\u043d\u0438\u044f<\/em><\/strong> \u0441 \u0431\u043b\u0438\u0436\u0430\u0439\u0448\u0438\u043c \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u043c.<\/p>\n<p>\u041d\u0430\u043f\u0438\u0448\u0435\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u044e, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 sphere_intersect() \u0434\u043b\u044f \u043f\u043e\u0438\u0441\u043a\u0430 \u0431\u043b\u0438\u0436\u0430\u0439\u0448\u0435\u0433\u043e \u043e\u0431\u044a\u0435\u043a\u0442\u0430, \u0441 \u043a\u043e\u0442\u043e\u0440\u044b\u043c \u043f\u0435\u0440\u0435\u0441\u0435\u043a\u0430\u0435\u0442\u0441\u044f \u043b\u0443\u0447, \u0435\u0441\u043b\u0438 \u043e\u043d \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442. \u041f\u0440\u043e\u0441\u0442\u043e \u043f\u0435\u0440\u0435\u0431\u0438\u0440\u0430\u0435\u043c \u0432\u0441\u0435 \u0441\u0444\u0435\u0440\u044b, \u0438\u0449\u0435\u043c \u043f\u0435\u0440\u0435\u0441\u0435\u0447\u0435\u043d\u0438\u044f \u0438 \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u043c \u0431\u043b\u0438\u0436\u0430\u0439\u0448\u0443\u044e \u0441\u0444\u0435\u0440\u0443:<\/p>\n<details class=\"spoiler\">\n<summary>\u041f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u043a\u043e\u0434<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"python\">def nearest_intersected_object(objects, ray_origin, ray_direction):    distances = [sphere_intersect(obj['center'], obj['radius'], ray_origin, ray_direction) for obj in objects]    nearest_object = None    min_distance = np.inf    for index, distance in enumerate(distances):        if distance and distance &lt; min_distance:            min_distance = distance            nearest_object = objects[index]    return nearest_object, min_distance<\/code><\/pre>\n<\/div>\n<\/details>\n<p>\u041f\u0440\u0438 \u0432\u044b\u0437\u043e\u0432\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438, \u0435\u0441\u043b\u0438 nearest_object = None, \u043b\u0443\u0447 \u043d\u0435 \u043f\u0435\u0440\u0435\u0441\u0435\u043a\u0430\u0435\u0442 \u043d\u0438\u043a\u0430\u043a\u043e\u0433\u043e \u043e\u0431\u044a\u0435\u043a\u0442\u0430, \u0438\u043d\u0430\u0447\u0435 \u0435\u0433\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435\u043c \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f <strong>\u0431\u043b\u0438\u0436\u0430\u0439\u0448\u0438\u0439 \u043f\u0435\u0440\u0435\u0441\u0435\u043a\u0430\u0435\u043c\u044b\u0439 \u043e\u0431\u044a\u0435\u043a\u0442<\/strong>, \u0438 \u043c\u044b \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c min_distance \u2014 \u0440\u0430\u0441\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u043e\u0442 <em>\u043d\u0430\u0447\u0430\u043b\u0430 \u043b\u0443\u0447\u0430<\/em> \u0434\u043e <em>\u0442\u043e\u0447\u043a\u0438 \u043f\u0435\u0440\u0435\u0441\u0435\u0447\u0435\u043d\u0438\u044f<\/em>.<\/p>\n<h3>\u0422\u043e\u0447\u043a\u0430 \u043f\u0435\u0440\u0435\u0441\u0435\u0447\u0435\u043d\u0438\u044f<\/h3>\n<p>\u0427\u0442\u043e\u0431\u044b \u0432\u044b\u0447\u0438\u0441\u043b\u0438\u0442\u044c <strong><em>\u0442\u043e\u0447\u043a\u0443 \u043f\u0435\u0440\u0435\u0441\u0435\u0447\u0435\u043d\u0438\u044f<\/em><\/strong>, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0443\u044e \u0444\u0443\u043d\u043a\u0446\u0438\u044e:<\/p>\n<pre><code class=\"python\">nearest_object, distance = nearest_intersected_object(objects, o, d) if nearest_object: &nbsp;&nbsp;&nbsp;intersection_point = o + d * distance<\/code><\/pre>\n<p>\u0412 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0435 \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u043a\u043e\u0434:<\/p>\n<details class=\"spoiler\">\n<summary>\u041f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u043a\u043e\u0434<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"python\">import numpy as np import matplotlib.pyplot as plt def normalize(vector):    return vector \/ np.linalg.norm(vector) def sphere_intersect(center, radius, ray_origin, ray_direction):    b = 2 * np.dot(ray_direction, ray_origin \u2014 center)    c = np.linalg.norm(ray_origin \u2014 center) ** 2 \u2014 radius ** 2    delta = b ** 2 \u2014 4 * c    if delta &gt; 0:        t1 = (-b + np.sqrt(delta)) \/ 2        t2 = (-b \u2014 np.sqrt(delta)) \/ 2        if t1 &gt; 0 and t2 &gt; 0:            return min(t1, t2)    return None def nearest_intersected_object(objects, ray_origin, ray_direction):    distances = [sphere_intersect(obj['center'], obj['radius'], ray_origin, ray_direction) for obj in objects]    nearest_object = None    min_distance = np.inf    for index, distance in enumerate(distances):        if distance and distance &lt; min_distance:            min_distance = distance            nearest_object = objects[index]    return nearest_object, min_distance width = 300 height = 200 camera = np.array([0, 0, 1]) ratio = float(width) \/ height screen = (-1, 1 \/ ratio, 1, -1 \/ ratio) # \u0441\u043b\u0435\u0432\u0430, \u0441\u0432\u0435\u0440\u0445\u0443, \u0441\u043f\u0440\u0430\u0432\u0430, \u0441\u043d\u0438\u0437\u0443 objects = [    { 'center': np.array([-0.2, 0, -1]), 'radius': 0.7 },    { 'center': np.array([0.1, -0.3, 0]), 'radius': 0.1 },    { 'center': np.array([-0.3, 0, 0]), 'radius': 0.15 } ] image = np.zeros((height, width, 3)) for i, y in enumerate(np.linspace(screen[1], screen[3], height)):    for j, x in enumerate(np.linspace(screen[0], screen[2], width)):        pixel = np.array([x, y, 0])        origin = camera        direction = normalize(pixel \u2014 origin)        # \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u043f\u0435\u0440\u0435\u0441\u0435\u0447\u0435\u043d\u0438\u0439        nearest_object, min_distance = nearest_intersected_object(objects, origin, direction)        if nearest_object is None:            continue        # \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u044f \u043f\u0435\u0440\u0435\u0441\u0435\u0447\u0435\u043d\u0438\u0439 \u043c\u0435\u0436\u0434\u0443 \u043b\u0443\u0447\u043e\u043c \u0438 \u0431\u043b\u0438\u0436\u0430\u0439\u0448\u0438\u043c \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u043c        intersection = origin + min_distance * direction        # image[i, j] = ...        print(\"%d\/%d\" % (i + 1, height)) plt.imsave('image.png', image)<\/code><\/pre>\n<\/div>\n<\/details>\n<h3>\u041f\u0435\u0440\u0435\u0441\u0435\u0447\u0435\u043d\u0438\u044f \u0441\u0432\u0435\u0442\u0430<\/h3>\n<p>\u0418\u0442\u0430\u043a, \u043c\u044b \u043d\u0430\u0448\u043b\u0438 \u043f\u0440\u044f\u043c\u0443\u044e \u043b\u0438\u043d\u0438\u044e, \u0438\u0434\u0443\u0449\u0443\u044e \u043e\u0442 \u043a\u0430\u043c\u0435\u0440\u044b \u043a \u043e\u0431\u044a\u0435\u043a\u0442\u0443, \u0438 \u0437\u043d\u0430\u0435\u043c, \u0447\u0442\u043e \u044d\u0442\u043e \u0437\u0430 \u043e\u0431\u044a\u0435\u043a\u0442, \u0430 \u0442\u0430\u043a\u0436\u0435 \u043d\u0430 \u043a\u0430\u043a\u0443\u044e \u0447\u0430\u0441\u0442\u044c \u043e\u0431\u044a\u0435\u043a\u0442\u0430 \u043c\u044b \u0441\u043c\u043e\u0442\u0440\u0438\u043c. \u041d\u043e \u043c\u044b \u043f\u043e\u043a\u0430 \u043d\u0435 \u0437\u043d\u0430\u0435\u043c, \u043e\u0441\u0432\u0435\u0449\u0435\u043d\u0430 \u043b\u0438 \u0432\u043e\u043e\u0431\u0449\u0435 \u044d\u0442\u0430 \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u0430\u044f \u0442\u043e\u0447\u043a\u0430. \u0412\u043e\u0437\u043c\u043e\u0436\u043d\u043e, \u0441\u0432\u0435\u0442 \u043d\u0435 \u043f\u043e\u043f\u0430\u0434\u0430\u0435\u0442 \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e \u043d\u0430 \u043d\u0435\u0435, \u0438 \u043d\u0435\u0442 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0441\u0442\u0438 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u044c \u0440\u0430\u0441\u0447\u0435\u0442\u044b \u0434\u0430\u043b\u044c\u0448\u0435, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u043c\u044b \u0435\u0435 \u043d\u0435 \u0432\u0438\u0434\u0438\u043c. \u0421\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e, \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u0448\u0430\u0433 \u2014 \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c, \u043d\u0435\u0442 \u043b\u0438 \u043d\u0438\u043a\u0430\u043a\u0438\u0445 \u043f\u043e\u0441\u0442\u043e\u0440\u043e\u043d\u043d\u0438\u0445 \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432 \u043c\u0435\u0436\u0434\u0443 <strong><em>\u0442\u043e\u0447\u043a\u043e\u0439 \u043f\u0435\u0440\u0435\u0441\u0435\u0447\u0435\u043d\u0438\u044f<\/em><\/strong> \u0438 <strong><em>\u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a\u043e\u043c \u0441\u0432\u0435\u0442\u0430<\/em><\/strong>.<\/p>\n<p>\u0423 \u043d\u0430\u0441 \u0443\u0436\u0435 \u0435\u0441\u0442\u044c \u0444\u0443\u043d\u043a\u0446\u0438\u044f, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043d\u0430\u043c \u043c\u043e\u0436\u0435\u0442 \u043f\u043e\u043c\u043e\u0447\u044c: near_intersected_object(). \u0418 \u043c\u044b \u0445\u043e\u0442\u0438\u043c \u0437\u043d\u0430\u0442\u044c, \u043f\u0435\u0440\u0435\u0441\u0435\u043a\u0430\u0435\u0442 \u043b\u0438 \u043b\u0443\u0447, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043d\u0430\u0447\u0438\u043d\u0430\u0435\u0442\u0441\u044f \u0432 <strong><em>\u0442\u043e\u0447\u043a\u0435 \u043f\u0435\u0440\u0435\u0441\u0435\u0447\u0435\u043d\u0438\u044f<\/em><\/strong> \u0438 \u0438\u0434\u0435\u0442 \u043a <strong><em>\u0441\u0432\u0435\u0442\u0443,<\/em><\/strong> \u043e\u0431\u044a\u0435\u043a\u0442 \u0441\u0446\u0435\u043d\u044b <em>\u043f\u0435\u0440\u0435\u0434 \u0442\u0435\u043c<\/em>, \u043a\u0430\u043a \u043f\u0435\u0440\u0435\u0441\u0435\u0447\u044c \u0441\u0432\u0435\u0442. \u042d\u0442\u043e \u043f\u0440\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0442\u0430 \u0436\u0435 \u0437\u0430\u0434\u0430\u0447\u0430, \u0447\u0442\u043e \u043c\u044b \u0440\u0435\u0448\u0430\u043b\u0438 \u0440\u0430\u043d\u044c\u0448\u0435: \u043d\u0430\u043c \u043f\u0440\u043e\u0441\u0442\u043e \u043d\u0443\u0436\u043d\u043e \u0438\u0437\u043c\u0435\u043d\u0438\u0442\u044c \u043d\u0430\u0447\u0430\u043b\u043e \u0438 \u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u043b\u0443\u0447\u0430. \u0412\u043e-\u043f\u0435\u0440\u0432\u044b\u0445, \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u0442\u044c \u0441\u0432\u0435\u0442. \u041c\u043e\u0436\u043d\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u044d\u0442\u043e \u0441\u0440\u0430\u0437\u0443 \u0432\u043c\u0435\u0441\u0442\u0435 \u0441 \u043e\u0431\u044a\u044f\u0432\u043b\u0435\u043d\u0438\u0435\u043c \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432:<\/p>\n<pre><code class=\"python\">light = { 'position': np.array([5, 5, 5]) }<\/code><\/pre>\n<p>\u0427\u0442\u043e\u0431\u044b \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c, \u0437\u0430\u0442\u0435\u043d\u044f\u0435\u0442 \u043b\u0438 \u043e\u0431\u044a\u0435\u043a\u0442 \u0442\u043e\u0447\u043a\u0443 \u043f\u0435\u0440\u0435\u0441\u0435\u0447\u0435\u043d\u0438\u044f, \u043c\u044b \u0434\u043e\u043b\u0436\u043d\u044b \u043f\u0440\u043e\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u043b\u0443\u0447, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043d\u0430\u0447\u0438\u043d\u0430\u0435\u0442\u0441\u044f \u0432 <strong><em>\u0442\u043e\u0447\u043a\u0435 \u043f\u0435\u0440\u0435\u0441\u0435\u0447\u0435\u043d\u0438\u044f<\/em><\/strong> \u0438 \u0438\u0434\u0435\u0442 \u043a <strong><em>\u0441\u0432\u0435\u0442\u0443<\/em><\/strong>, \u0438 \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c, \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u043b\u0438 \u0431\u043b\u0438\u0436\u0430\u0439\u0448\u0438\u0439 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0435\u043d\u043d\u044b\u0439 \u043e\u0431\u044a\u0435\u043a\u0442 \u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0431\u043b\u0438\u0436\u0435, \u0447\u0435\u043c \u0441\u0432\u0435\u0442, \u043a \u0442\u043e\u0447\u043a\u0435 \u043f\u0435\u0440\u0435\u0441\u0435\u0447\u0435\u043d\u0438\u044f (\u0434\u0440\u0443\u0433\u0438\u043c\u0438 \u0441\u043b\u043e\u0432\u0430\u043c\u0438, \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u043b\u0438 \u043e\u043d \u043c\u0435\u0436\u0434\u0443 \u043d\u0438\u043c\u0438).<\/p>\n<pre><code class=\"python\"># ... intersection = origin + min_distance * direction intersection_to_light = normalize(light['position'] \u2014 intersection) _, min_distance = nearest_intersected_object(objects, intersection, intersection_to_light) intersection_to_light_distance = np.linalg.norm(light['position'] \u2014 intersection) is_shadowed = min_distance &lt; intersection_to_light_distance<\/code><\/pre>\n<p>\u0427\u0442\u043e \u0436, \u044d\u0442\u043e \u0442\u0430\u043a \u043d\u0435 \u0441\u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442. \u041d\u0443\u0436\u043d\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u0443\u044e \u043a\u043e\u0440\u0440\u0435\u043a\u0442\u0438\u0440\u043e\u0432\u043a\u0443. \u0415\u0441\u043b\u0438 \u043c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u0442\u043e\u0447\u043a\u0443 \u043f\u0435\u0440\u0435\u0441\u0435\u0447\u0435\u043d\u0438\u044f \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a\u0430 \u043d\u043e\u0432\u043e\u0433\u043e \u043b\u0443\u0447\u0430, \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0432 \u043a\u043e\u043d\u0435\u0447\u043d\u043e\u043c \u0438\u0442\u043e\u0433\u0435 \u043e\u0431\u043d\u0430\u0440\u0443\u0436\u0438\u0442\u044c \u0441\u0444\u0435\u0440\u0443, \u043d\u0430 \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u043c\u044b \u0441\u0435\u0439\u0447\u0430\u0441 \u043d\u0430\u0445\u043e\u0434\u0438\u043c\u0441\u044f, \u043a\u0430\u043a \u043e\u0431\u044a\u0435\u043a\u0442 \u043c\u0435\u0436\u0434\u0443 \u0442\u043e\u0447\u043a\u043e\u0439 \u043f\u0435\u0440\u0435\u0441\u0435\u0447\u0435\u043d\u0438\u044f \u0438 \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a\u043e\u043c \u0441\u0432\u0435\u0442\u0430. \u0411\u044b\u0441\u0442\u0440\u043e\u0435 \u0438 \u0448\u0438\u0440\u043e\u043a\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u043e\u0435 \u0440\u0435\u0448\u0435\u043d\u0438\u0435 \u044d\u0442\u043e\u0439 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u044b \u2014 \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u043e\u0439 \u0448\u0430\u0433, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0443\u0432\u043e\u0434\u0438\u0442 \u043d\u0430\u0441 \u043e\u0442 \u043f\u043e\u0432\u0435\u0440\u0445\u043d\u043e\u0441\u0442\u0438 \u0441\u0444\u0435\u0440\u044b. \u041e\u0431\u044b\u0447\u043d\u043e \u0434\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0432\u044b\u0447\u0438\u0441\u043b\u044f\u0435\u0442\u0441\u044f \u0432\u0435\u043a\u0442\u043e\u0440 \u043d\u043e\u0440\u043c\u0430\u043b\u0438 \u043a \u043f\u043e\u0432\u0435\u0440\u0445\u043d\u043e\u0441\u0442\u0438 \u0438 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0441\u044f \u043e\u0442\u0441\u0442\u0443\u043f \u0432 \u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0438 \u044d\u0442\u043e\u0439 \u043d\u043e\u0440\u043c\u0430\u043b\u0438.<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/6b2\/1b6\/156\/6b21b6156ef26ab267e70a7398628d62.png\" alt=\"\u0420\u0438\u0441\u0443\u043d\u043e\u043a 6\" title=\"\u0420\u0438\u0441\u0443\u043d\u043e\u043a 6\" width=\"780\" height=\"780\"><figcaption>\u0420\u0438\u0441\u0443\u043d\u043e\u043a 6<\/figcaption><\/figure>\n<p><em>\u042d\u0442\u043e\u0442 \u0442\u0440\u044e\u043a \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u043d\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u0434\u043b\u044f \u0441\u0444\u0435\u0440, \u043d\u043e \u0438 \u0434\u043b\u044f \u043b\u044e\u0431\u044b\u0445 \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432.<\/em><\/p>\n<p>\u0421\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e, \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u044b\u0439 \u043a\u043e\u0434 \u0431\u0443\u0434\u0435\u0442 \u0442\u0430\u043a\u0438\u043c:<\/p>\n<details class=\"spoiler\">\n<summary>\u041f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u043a\u043e\u0434<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"python\"># ... intersection = origin + min_distance * direction normal_to_surface = normalize(intersection \u2014 nearest_object['center']) shifted_point = intersection + 1e-5 * normal_to_surface intersection_to_light = normalize(light['position'] \u2014 shifted_point) _, min_distance = nearest_intersected_object(objects, shifted_point, intersection_to_light) intersection_to_light_distance = np.linalg.norm(light['position'] \u2014 intersection) is_shadowed = min_distance &lt; intersection_to_light_distance if is_shadowed:    continue<\/code><\/pre>\n<\/div>\n<\/details>\n<h3>\u041c\u043e\u0434\u0435\u043b\u044c \u043e\u0442\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u0411\u043b\u0438\u043d\u043d\u0430-\u0424\u043e\u043d\u0433\u0430<\/h3>\n<p>\u0418\u0442\u0430\u043a, \u043c\u044b \u0437\u043d\u0430\u0435\u043c, \u0447\u0442\u043e \u043b\u0443\u0447 \u0441\u0432\u0435\u0442\u0430 \u043f\u043e\u043f\u0430\u043b \u043d\u0430 \u043e\u0431\u044a\u0435\u043a\u0442, \u0430 \u043e\u0442\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u043b\u0443\u0447\u0430 \u2014 \u043f\u0440\u044f\u043c\u043e \u0432 <strong><em>\u043a\u0430\u043c\u0435\u0440\u0443<\/em><\/strong>. \u0412\u043e\u043f\u0440\u043e\u0441: \u0447\u0442\u043e \u0443\u0432\u0438\u0434\u0438\u0442 \u043a\u0430\u043c\u0435\u0440\u0430? \u041d\u0430 \u043d\u0435\u0433\u043e \u0438 \u043f\u044b\u0442\u0430\u0435\u0442\u0441\u044f \u043e\u0442\u0432\u0435\u0442\u0438\u0442\u044c \u043c\u043e\u0434\u0435\u043b\u044c \u0411\u043b\u0438\u043d\u043d\u0430-\u0424\u043e\u043d\u0433\u0430.<\/p>\n<p>\u041c\u043e\u0434\u0435\u043b\u044c <a href=\"https:\/\/en.wikipedia.org\/wiki\/Blinn%E2%80%93Phong_reflection_model\"><strong><u>\u0411\u043b\u0438\u043d\u043d\u0430-\u0424\u043e\u043d\u0433\u0430<\/u><\/strong><\/a> \u2014 \u044d\u0442\u043e \u043f\u0440\u0438\u0431\u043b\u0438\u0436\u0435\u043d\u0438\u0435 \u043a \u043c\u043e\u0434\u0435\u043b\u0438 <a href=\"https:\/\/en.wikipedia.org\/wiki\/Phong_reflection_model\"><strong><u>\u0424\u043e\u043d\u0433\u0430<\/u><\/strong><\/a>, \u0442\u0440\u0435\u0431\u0443\u044e\u0449\u0435\u0435 \u043c\u0435\u043d\u044c\u0448\u0438\u0445 \u0432\u044b\u0447\u0438\u0441\u043b\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0445 \u0437\u0430\u0442\u0440\u0430\u0442.<\/p>\n<p>\u0421\u043e\u0433\u043b\u0430\u0441\u043d\u043e \u044d\u0442\u043e\u0439 \u043c\u043e\u0434\u0435\u043b\u0438, \u043b\u044e\u0431\u043e\u0439 \u043c\u0430\u0442\u0435\u0440\u0438\u0430\u043b \u0438\u043c\u0435\u0435\u0442 \u0447\u0435\u0442\u044b\u0440\u0435 \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0430:<\/p>\n<ul>\n<li>\n<p><strong>\u0424\u043e\u043d\u043e\u0432\u044b\u0439 \u0446\u0432\u0435\u0442 (Ambient color)<\/strong>: \u0446\u0432\u0435\u0442, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0438\u043c\u0435\u0435\u0442 \u043e\u0431\u044a\u0435\u043a\u0442 \u0432 \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0438\u0435 \u0441\u0432\u0435\u0442\u0430;<\/p>\n<\/li>\n<li>\n<p><strong>\u0420\u0430\u0441\u0441\u0435\u044f\u043d\u043d\u044b\u0439 \u0446\u0432\u0435\u0442 (Diffuse color)<\/strong>: \u0446\u0432\u0435\u0442, \u043d\u0430\u0438\u0431\u043e\u043b\u0435\u0435 \u0431\u043b\u0438\u0437\u043a\u0438\u0439 \u043a \u0442\u043e\u043c\u0443, \u0447\u0442\u043e \u043c\u044b \u0441\u0435\u0431\u0435 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u043c;<\/p>\n<\/li>\n<li>\n<p><strong>\u0417\u0435\u0440\u043a\u0430\u043b\u044c\u043d\u044b\u0439 \u0446\u0432\u0435\u0442 (Specular color)<\/strong>: \u0446\u0432\u0435\u0442 \u0431\u043b\u0435\u0441\u0442\u044f\u0449\u0435\u0439 \u0447\u0430\u0441\u0442\u0438 \u043e\u0431\u044a\u0435\u043a\u0442\u0430, \u043a\u043e\u0433\u0434\u0430 \u0441\u0432\u0435\u0442 \u043f\u043e\u043f\u0430\u0434\u0430\u0435\u0442 \u043d\u0430 \u043d\u0435\u0435. \u0412 \u0431\u043e\u043b\u044c\u0448\u0438\u043d\u0441\u0442\u0432\u0435 \u0441\u043b\u0443\u0447\u0430\u0435\u0432 \u044d\u0442\u043e \u0431\u0435\u043b\u044b\u0439 \u0446\u0432\u0435\u0442;<\/p>\n<\/li>\n<li>\n<p><strong>\u0411\u043b\u0435\u0441\u043a (Shininess)<\/strong>: \u043a\u043e\u044d\u0444\u0444\u0438\u0446\u0438\u0435\u043d\u0442, \u043f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u044e\u0449\u0438\u0439, \u043d\u0430\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0431\u043b\u0435\u0441\u0442\u044f\u0449\u0438\u043c \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043e\u0431\u044a\u0435\u043a\u0442.<\/p>\n<\/li>\n<\/ul>\n<p><strong><em>\u041f\u0440\u0438\u043c\u0435\u0447\u0430\u043d\u0438\u0435<\/em><\/strong>: \u0412\u0441\u0435 \u0446\u0432\u0435\u0442\u0430 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u044b \u0432 RGB \u0432 \u0434\u0438\u0430\u043f\u0430\u0437\u043e\u043d\u0435 0 \u2013 1.<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/4ba\/b86\/528\/4bab8652854166012d83007f4618a69d.png\" alt=\"\u0420\u0438\u0441\u0443\u043d\u043e\u043a 7\" title=\"\u0420\u0438\u0441\u0443\u043d\u043e\u043a 7\" width=\"963\" height=\"268\"><figcaption>\u0420\u0438\u0441\u0443\u043d\u043e\u043a 7<\/figcaption><\/figure>\n<p>\u0414\u043e\u0431\u0430\u0432\u0438\u043c \u044d\u0442\u0438 \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0430 \u043a \u0441\u0444\u0435\u0440\u0430\u043c:<\/p>\n<pre><code class=\"python\">objects = [    { 'center': np.array([-0.2, 0, -1]), 'radius': 0.7, 'ambient': np.array([0.1, 0, 0]), 'diffuse': np.array([0.7, 0, 0]), 'specular': np.array([1, 1, 1]), 'shininess': 100 },    { 'center': np.array([0.1, -0.3, 0]), 'radius': 0.1, 'ambient': np.array([0.1, 0, 0.1]), 'diffuse': np.array([0.7, 0, 0.7]), 'specular': np.array([1, 1, 1]), 'shininess': 100 },    { 'center': np.array([-0.3, 0, 0]), 'radius': 0.15, 'ambient': np.array([0, 0.1, 0]), 'diffuse': np.array([0, 0.6, 0]), 'specular': np.array([1, 1, 1]), 'shininess': 100 } ]<\/code><\/pre>\n<p>\u0412 \u043d\u0430\u0448\u0435\u043c \u043f\u0440\u0438\u043c\u0435\u0440\u0435 \u0441\u0444\u0435\u0440\u044b \u0438\u043c\u0435\u044e\u0442 \u0446\u0432\u0435\u0442\u0430 \u043a\u0440\u0430\u0441\u043d\u044b\u0439, \u043f\u0443\u0440\u043f\u0443\u0440\u043d\u044b\u0439 \u0438 \u0437\u0435\u043b\u0435\u043d\u044b\u0439, \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0435\u043d\u043d\u043e.<\/p>\n<p>\u041c\u043e\u0434\u0435\u043b\u044c \u0411\u043b\u0438\u043d\u043d-\u0424\u043e\u043d\u0433\u0430 \u0443\u0442\u0432\u0435\u0440\u0436\u0434\u0430\u0435\u0442, \u0447\u0442\u043e \u0441\u0432\u0435\u0442 \u0442\u0430\u043a\u0436\u0435 \u0438\u043c\u0435\u0435\u0442 \u0442\u0440\u0438 \u0446\u0432\u0435\u0442\u043e\u0432\u044b\u0445 \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0430: \u0444\u043e\u043d\u043e\u0432\u044b\u0439 \u0446\u0432\u0435\u0442, \u0440\u0430\u0441\u0441\u0435\u044f\u043d\u043d\u044b\u0439 \u0438 \u0437\u0435\u0440\u043a\u0430\u043b\u044c\u043d\u044b\u0439. \u0418\u0445 \u0442\u043e\u0436\u0435 \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u043a \u043c\u043e\u0434\u0435\u043b\u0438:<\/p>\n<pre><code class=\"python\">light = { 'position': np.array([5, 5, 5]), 'ambient': np.array([1, 1, 1]), 'diffuse': np.array([1, 1, 1]), 'specular': np.array([1, 1, 1]) }<\/code><\/pre>\n<p>\u0423\u0447\u0438\u0442\u044b\u0432\u0430\u044f \u044d\u0442\u0438 \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0430, \u043c\u043e\u0434\u0435\u043b\u044c \u0411\u043b\u0438\u043d\u043d\u0430-\u0424\u043e\u043d\u0433\u0430 \u0440\u0430\u0441\u0441\u0447\u0438\u0442\u044b\u0432\u0430\u0435\u0442 \u043e\u0441\u0432\u0435\u0449\u0435\u043d\u043d\u043e\u0441\u0442\u044c \u0442\u043e\u0447\u043a\u0438 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c:<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/ab8\/a02\/604\/ab8a0260467e198f065b16710a935d46.png\" width=\"1400\" height=\"138\"><figcaption><\/figcaption><\/figure>\n<p>\u0433\u0434\u0435<\/p>\n<ul>\n<li>\n<p>ka, kd, ks \u2014 \u0444\u043e\u043d\u043e\u0432\u043e\u0435, \u0440\u0430\u0441\u0441\u0435\u044f\u043d\u043d\u043e\u0435, \u0437\u0435\u0440\u043a\u0430\u043b\u044c\u043d\u043e\u0435 \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0430 <strong><em>\u043e\u0431\u044a\u0435\u043a\u0442\u0430<\/em><\/strong>;<\/p>\n<\/li>\n<li>\n<p>ia, id, is \u2014 \u0444\u043e\u043d\u043e\u0432\u043e\u0435, \u0440\u0430\u0441\u0441\u0435\u044f\u043d\u043d\u043e\u0435, \u0437\u0435\u0440\u043a\u0430\u043b\u044c\u043d\u043e\u0435 \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0430 <strong><em>\u0441\u0432\u0435\u0442\u0430<\/em><\/strong>;<\/p>\n<\/li>\n<li>\n<p>L \u2014 <strong>\u0435\u0434\u0438\u043d\u0438\u0447\u043d\u044b\u0439 \u0432\u0435\u043a\u0442\u043e\u0440<\/strong> \u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u043e\u0442 <strong><em>\u0442\u043e\u0447\u043a\u0438 \u043f\u0435\u0440\u0435\u0441\u0435\u0447\u0435\u043d\u0438\u044f<\/em><\/strong> \u043a <strong><em>\u0441\u0432\u0435\u0442\u0443<\/em><\/strong>;<\/p>\n<\/li>\n<li>\n<p>N \u2014 <strong>\u0435\u0434\u0438\u043d\u0438\u0447\u043d\u044b\u0439 \u0432\u0435\u043a\u0442\u043e\u0440<\/strong> <strong>\u043d\u043e\u0440\u043c\u0430\u043b\u0438<\/strong> \u043a \u043f\u043e\u0432\u0435\u0440\u0445\u043d\u043e\u0441\u0442\u0438 \u043e\u0431\u044a\u0435\u043a\u0442\u0430 \u0432 <em>\u0442\u043e\u0447\u043a\u0435 \u043f\u0435\u0440\u0435\u0441\u0435\u0447\u0435\u043d\u0438\u044f<\/em>;<\/p>\n<\/li>\n<li>\n<p>V \u2014 <strong>\u0435\u0434\u0438\u043d\u0438\u0447\u043d\u044b\u0439 \u0432\u0435\u043a\u0442\u043e\u0440<\/strong> \u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u043e\u0442 <strong><em>\u0442\u043e\u0447\u043a\u0438 \u043f\u0435\u0440\u0435\u0441\u0435\u0447\u0435\u043d\u0438\u044f<\/em><\/strong> \u043a <strong><em>\u043a\u0430\u043c\u0435\u0440\u0435<\/em><\/strong>;<\/p>\n<\/li>\n<li>\n<p>\u03b1 \u2014 <strong>\u0431\u043b\u0435\u0441\u043a<\/strong> \u043e\u0431\u044a\u0435\u043a\u0442\u0430.<\/p>\n<\/li>\n<\/ul>\n<details class=\"spoiler\">\n<summary>\u041f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u043a\u043e\u0434<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"python\"># ... if is_shadowed:    break  # RGB illumination = np.zeros((3))  # ambiant illumination += nearest_object['ambient'] * light['ambient']  # diffuse illumination += nearest_object['diffuse'] * light['diffuse'] * np.dot(intersection_to_light, normal_to_surface)  # specular intersection_to_camera = normalize(camera \u2014 intersection) H = normalize(intersection_to_light + intersection_to_camera) illumination += nearest_object['specular'] * light['specular'] * np.dot(normal_to_surface, H) ** (nearest_object['shininess'] \/ 4) image[i, j] = np.clip(illumination, 0, 1)<\/code><\/pre>\n<\/div>\n<\/details>\n<p>\u041e\u0431\u0440\u0430\u0442\u0438\u0442\u0435 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435, \u0447\u0442\u043e \u0432 \u043a\u043e\u043d\u0446\u0435 \u043c\u044b \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u043c \u0446\u0432\u0435\u0442 \u043c\u0435\u0436\u0434\u0443 0 \u0438 1, \u0447\u0442\u043e\u0431\u044b \u0443\u0431\u0435\u0434\u0438\u0442\u044c\u0441\u044f, \u0447\u0442\u043e \u043e\u043d \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u0432 \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e\u043c \u0434\u0438\u0430\u043f\u0430\u0437\u043e\u043d\u0435.<\/p>\n<h3>\u0417\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u043c \u043a\u043e\u0434<\/h3>\n<p>\u0423\u0432\u0435\u043b\u0438\u0447\u0438\u043c <strong><em>\u0448\u0438\u0440\u0438\u043d\u0443<\/em><\/strong> \u0438 <strong><em>\u0432\u044b\u0441\u043e\u0442\u0443<\/em><\/strong> \u0434\u043b\u044f \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u0431\u043e\u043b\u0435\u0435 \u0432\u044b\u0441\u043e\u043a\u043e\u0433\u043e \u0440\u0430\u0437\u0440\u0435\u0448\u0435\u043d\u0438\u044f (\u0446\u0435\u043d\u043e\u0439 \u0443\u0432\u0435\u043b\u0438\u0447\u0435\u043d\u0438\u044f \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u0439).<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/982\/fd9\/bfd\/982fd9bfda7de473670f1b2ba7157de2.png\" alt=\"\u0420\u0438\u0441\u0443\u043d\u043e\u043a 8\" title=\"\u0420\u0438\u0441\u0443\u043d\u043e\u043a 8\" width=\"1400\" height=\"787\"><figcaption>\u0420\u0438\u0441\u0443\u043d\u043e\u043a 8<\/figcaption><\/figure>\n<p>\u041c\u043e\u0436\u043d\u043e \u0437\u0430\u043c\u0435\u0442\u0438\u0442\u044c \u0434\u0432\u0435 \u0432\u0435\u0449\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043e\u0442\u043b\u0438\u0447\u0430\u044e\u0442 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u043e\u0442 \u043f\u0435\u0440\u0432\u043e\u0433\u043e \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f, \u043f\u043e\u043a\u0430\u0437\u0430\u043d\u043d\u043e\u0433\u043e \u0432 \u043d\u0430\u0447\u0430\u043b\u0435:<\/p>\n<ul>\n<li>\n<p>\u0421\u0435\u0440\u044b\u0439 \u043f\u043e\u043b \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u0435\u0442;<\/p>\n<\/li>\n<li>\n<p>\u041e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0438\u0435 \u043e\u0442\u0440\u0430\u0436\u0435\u043d\u0438\u0439.<\/p>\n<\/li>\n<\/ul>\n<h3>\u0424\u0435\u0439\u043a\u043e\u0432\u0430\u044f \u043f\u043b\u043e\u0441\u043a\u043e\u0441\u0442\u044c<\/h3>\n<p>\u0412 \u0438\u0434\u0435\u0430\u043b\u0435 \u043c\u044b \u0434\u043e\u043b\u0436\u043d\u044b \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u0434\u0440\u0443\u0433\u043e\u0439 \u0442\u0438\u043f \u043e\u0431\u044a\u0435\u043a\u0442\u0430 \u2014 \u043f\u043b\u043e\u0441\u043a\u043e\u0441\u0442\u044c, \u043d\u043e \u043f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u043c\u044b \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u043b\u0435\u043d\u0438\u0432\u044b, \u0442\u043e \u043c\u043e\u0436\u0435\u043c \u043f\u0440\u043e\u0441\u0442\u043e \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0434\u0440\u0443\u0433\u0443\u044e \u0441\u0444\u0435\u0440\u0443. \u0412\u0435\u0434\u044c \u0435\u0441\u043b\u0438 \u0432\u044b \u0441\u0442\u043e\u0438\u0442\u0435 \u043d\u0430 \u0441\u0444\u0435\u0440\u0435, \u0438\u043c\u0435\u044e\u0449\u0435\u0439 \u0431\u0435\u0441\u043a\u043e\u043d\u0435\u0447\u043d\u043e \u0431\u043e\u043b\u044c\u0448\u043e\u0439 \u0440\u0430\u0434\u0438\u0443\u0441 (\u043f\u043e \u0441\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u044e \u0441 \u0432\u0430\u0448\u0438\u043c \u0440\u0430\u0437\u043c\u0435\u0440\u043e\u043c), \u0442\u043e\u0433\u0434\u0430 \u0432\u0430\u043c \u0431\u0443\u0434\u0435\u0442 \u043a\u0430\u0437\u0430\u0442\u044c\u0441\u044f, \u0447\u0442\u043e \u0432\u044b \u0441\u0442\u043e\u0438\u0442\u0435 \u043d\u0430 \u043f\u043b\u043e\u0441\u043a\u043e\u0439 \u043f\u043e\u0432\u0435\u0440\u0445\u043d\u043e\u0441\u0442\u0438.<\/p>\n<p>\u0414\u043e\u0431\u0430\u0432\u0438\u043c \u044d\u0442\u0443 \u0441\u0444\u0435\u0440\u0443 \u0432 \u0441\u043f\u0438\u0441\u043e\u043a \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432 \u0438 \u0441\u043d\u043e\u0432\u0430 \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u043c \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433:<\/p>\n<pre><code class=\"python\">{ 'center': np.array([0, -9000, 0]), 'radius': 9000 \u2014 0.7, 'ambient': np.array([0.1, 0.1, 0.1]), 'diffuse': np.array([0.6, 0.6, 0.6]), 'specular': np.array([1, 1, 1]), 'shininess': 100 }<\/code><\/pre>\n<h3>\u041e\u0442\u0440\u0430\u0436\u0435\u043d\u0438\u0435<\/h3>\n<p>\u0421\u0435\u0439\u0447\u0430\u0441 \u043c\u044b \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043c \u043b\u0443\u0447\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0432\u044b\u0445\u043e\u0434\u044f\u0442 \u0438\u0437 \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a\u0430 \u0441\u0432\u0435\u0442\u0430, \u0443\u0434\u0430\u0440\u044f\u044e\u0442\u0441\u044f \u043e \u043f\u043e\u0432\u0435\u0440\u0445\u043d\u043e\u0441\u0442\u044c \u043e\u0431\u044a\u0435\u043a\u0442\u0430 \u0438 \u043e\u0442\u0440\u0430\u0436\u0430\u044e\u0442\u0441\u044f \u0432 \u043a\u0430\u043c\u0435\u0440\u0443. \u041d\u043e \u0447\u0442\u043e, \u0435\u0441\u043b\u0438 \u043b\u0443\u0447 \u043f\u043e\u043f\u0430\u0434\u0435\u0442 \u0432 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432, \u043f\u0440\u0435\u0436\u0434\u0435 \u0447\u0435\u043c \u043f\u043e\u043f\u0430\u0441\u0442\u044c \u0432 \u043a\u0430\u043c\u0435\u0440\u0443? \u041f\u043e\u044f\u0432\u0438\u0442\u0441\u044f \u043e\u0442\u0440\u0430\u0436\u0435\u043d\u0438\u0435. <\/p>\n<p>\u041a\u0430\u0436\u0434\u044b\u0439 \u043e\u0431\u044a\u0435\u043a\u0442 \u0438\u043c\u0435\u0435\u0442 <strong>\u043a\u043e\u044d\u0444\u0444\u0438\u0446\u0438\u0435\u043d\u0442 \u043e\u0442\u0440\u0430\u0436\u0435\u043d\u0438\u044f<\/strong> \u0432 \u0434\u0438\u0430\u043f\u0430\u0437\u043e\u043d\u0435 \u043e\u0442 0 \u0434\u043e 1. \u0417\u0434\u0435\u0441\u044c 0 \u043e\u0437\u043d\u0430\u0447\u0430\u0435\u0442, \u0447\u0442\u043e \u043e\u0431\u044a\u0435\u043a\u0442 \u043c\u0430\u0442\u043e\u0432\u044b\u0439, 1 \u2014 \u0447\u0442\u043e \u043e\u0431\u044a\u0435\u043a\u0442 \u0437\u0435\u0440\u043a\u0430\u043b\u044c\u043d\u044b\u0439. \u0414\u043e\u0431\u0430\u0432\u0438\u043c \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u043e \u043e\u0442\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u043a\u043e \u0432\u0441\u0435\u043c \u0441\u0444\u0435\u0440\u0430\u043c:<\/p>\n<pre><code class=\"python\">{ 'center': np.array([-0.2, 0, -1]), ..., 'reflection': 0.5 } { 'center': np.array([0.1, -0.3, 0]), ..., 'reflection': 0.5 } { 'center': np.array([-0.3, 0, 0]), ..., 'reflection': 0.5 } { 'center': np.array([0, -9000, 0]), ..., 'reflection': 0.5 }<\/code><\/pre>\n<h3>\u0410\u043b\u0433\u043e\u0440\u0438\u0442\u043c<\/h3>\n<p>\u0427\u0442\u043e\u0431\u044b \u0432\u043a\u043b\u044e\u0447\u0438\u0442\u044c \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u0435 \u043e\u0442\u0440\u0430\u0436\u0435\u043d\u0438\u0439, \u043d\u0443\u0436\u043d\u043e \u043e\u0442\u0441\u043b\u0435\u0434\u0438\u0442\u044c <strong>\u043e\u0442\u0440\u0430\u0436\u0435\u043d\u043d\u044b\u0439 \u043b\u0443\u0447<\/strong> \u043f\u043e\u0441\u043b\u0435 \u0442\u043e\u0433\u043e, \u043a\u0430\u043a \u043f\u0440\u043e\u0438\u0437\u043e\u0448\u043b\u043e \u043f\u0435\u0440\u0435\u0441\u0435\u0447\u0435\u043d\u0438\u0435, \u0438 \u0443\u0447\u0435\u0441\u0442\u044c \u0446\u0432\u0435\u0442\u043e\u0432\u043e\u0439 \u0432\u043a\u043b\u0430\u0434 \u043a\u0430\u0436\u0434\u043e\u0439 \u0442\u043e\u0447\u043a\u0438 \u044d\u0442\u043e\u0433\u043e \u043f\u0435\u0440\u0435\u0441\u0435\u0447\u0435\u043d\u0438\u044f. \u041f\u043e\u0432\u0442\u043e\u0440\u044f\u0435\u043c \u044d\u0442\u043e\u0442 \u043f\u0440\u043e\u0446\u0435\u0441\u0441 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0440\u0430\u0437.<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/edb\/c70\/a0f\/edbc70a0fec7e53def15b8add5de696a.png\" alt=\"\u0420\u0438\u0441\u0443\u043d\u043e\u043a 9\" title=\"\u0420\u0438\u0441\u0443\u043d\u043e\u043a 9\" width=\"1078\" height=\"958\"><figcaption>\u0420\u0438\u0441\u0443\u043d\u043e\u043a 9<\/figcaption><\/figure>\n<h3>\u0420\u0430\u0441\u0447\u0435\u0442 \u0446\u0432\u0435\u0442\u0430<\/h3>\n<p>\u0427\u0442\u043e\u0431\u044b \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0446\u0432\u0435\u0442 \u043f\u0438\u043a\u0441\u0435\u043b\u044f, \u043d\u0443\u0436\u043d\u043e \u043f\u0440\u043e\u0441\u0443\u043c\u043c\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0432\u043a\u043b\u0430\u0434 \u043a\u0430\u0436\u0434\u043e\u0439 \u0442\u043e\u0447\u043a\u0438 \u043f\u0435\u0440\u0435\u0441\u0435\u0447\u0435\u043d\u0438\u044f \u043b\u0443\u0447\u0430:<\/p>\n<figure class=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/a7f\/e7a\/dda\/a7fe7adda3fccb6938d2e1c8682589ee.png\" width=\"507\" height=\"29\"><figcaption><\/figcaption><\/figure>\n<p>\u0433\u0434\u0435<\/p>\n<ul>\n<li>\n<p>c \u2014 \u043a\u043e\u043d\u0435\u0447\u043d\u044b\u0439 \u0446\u0432\u0435\u0442 \u043f\u0438\u043a\u0441\u0435\u043b\u044f;<\/p>\n<\/li>\n<li>\n<p>i \u2014 \u043e\u0441\u0432\u0435\u0449\u0435\u043d\u043d\u043e\u0441\u0442\u044c, \u0440\u0430\u0441\u0441\u0447\u0438\u0442\u0430\u043d\u043d\u0430\u044f \u043f\u043e \u043c\u043e\u0434\u0435\u043b\u0438 \u0411\u043b\u0438\u043d\u043d\u0430-\u0424\u043e\u043d\u0433\u0430 \u0434\u043b\u044f \u0442\u043e\u0447\u043a\u0438 \u043f\u0435\u0440\u0435\u0441\u0435\u0447\u0435\u043d\u0438\u044f;<\/p>\n<\/li>\n<li>\n<p>r \u2014 \u043e\u0442\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u043e\u0442 \u043f\u0435\u0440\u0435\u0441\u0435\u043a\u0430\u0435\u043c\u043e\u0433\u043e \u043e\u0431\u044a\u0435\u043a\u0442\u0430.<\/p>\n<\/li>\n<\/ul>\n<p>\u041a\u043e\u0433\u0434\u0430 \u043f\u0440\u0435\u043a\u0440\u0430\u0442\u0438\u0442\u044c \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u0435 \u044d\u0442\u043e\u0439 \u0441\u0443\u043c\u043c\u044b (\u0438 \u043e\u0442\u0441\u043b\u0435\u0436\u0438\u0432\u0430\u043d\u0438\u0435 \u043e\u0442\u0440\u0430\u0436\u0435\u043d\u043d\u044b\u0445 \u043b\u0443\u0447\u0435\u0439, \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0435\u043d\u043d\u043e), \u0440\u0435\u0448\u0430\u0435\u0442\u0435 \u0432\u044b \u0441\u0430\u043c\u0438.<\/p>\n<h3>\u041e\u0442\u0440\u0430\u0436\u0435\u043d\u043d\u044b\u0439 \u043b\u0443\u0447<\/h3>\n<p>\u041f\u0440\u0435\u0436\u0434\u0435 \u0447\u0435\u043c \u043c\u044b \u0441\u043c\u043e\u0436\u0435\u043c \u0432\u0441\u0435 \u044d\u0442\u043e \u0437\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u0432 \u0432\u0438\u0434\u0435 \u043a\u043e\u0434\u0430, \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u0442\u044c \u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u043e\u0442\u0440\u0430\u0436\u0435\u043d\u043d\u043e\u0433\u043e \u043b\u0443\u0447\u0430. \u041c\u043e\u0436\u043d\u043e \u0432\u044b\u0447\u0438\u0441\u043b\u0438\u0442\u044c \u0435\u0433\u043e \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c:<\/p>\n<figure class=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/0ed\/220\/24e\/0ed22024e0fbc03c7066e08ea593b186.png\" alt=\"\" title=\"\" width=\"273\" height=\"31\"><figcaption><\/figcaption><\/figure>\n<p>\u0433\u0434\u0435<\/p>\n<ul>\n<li>\n<p>R \u2014 \u043d\u043e\u0440\u043c\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u043e\u0442\u0440\u0430\u0436\u0435\u043d\u043d\u044b\u0439 \u043b\u0443\u0447;<\/p>\n<\/li>\n<li>\n<p>L \u2014 <strong>\u0435\u0434\u0438\u043d\u0438\u0447\u043d\u044b\u0439 \u0432\u0435\u043a\u0442\u043e\u0440<\/strong> \u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u043e\u0442\u0440\u0430\u0436\u0430\u0435\u043c\u043e\u0433\u043e \u043b\u0443\u0447\u0430;<\/p>\n<\/li>\n<li>\n<p>N \u2014 <strong>\u0435\u0434\u0438\u043d\u0438\u0447\u043d\u044b\u0439 \u0432\u0435\u043a\u0442\u043e\u0440<\/strong> \u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f <em>\u043d\u043e\u0440\u043c\u0430\u043b\u0438<\/em> \u043a \u043f\u043e\u0432\u0435\u0440\u0445\u043d\u043e\u0441\u0442\u0438 \u0445\u043e\u0434\u0430 \u043b\u0443\u0447\u0430.<\/p>\n<\/li>\n<\/ul>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/d3a\/668\/e7f\/d3a668e7f38ba4696de928cb805b308e.png\" alt=\"\u0420\u0438\u0441\u0443\u043d\u043e\u043a 10\" title=\"\u0420\u0438\u0441\u0443\u043d\u043e\u043a 10\" width=\"781\" height=\"540\"><figcaption>\u0420\u0438\u0441\u0443\u043d\u043e\u043a 10<\/figcaption><\/figure>\n<p>\u0414\u043e\u0431\u0430\u0432\u0438\u043c \u044d\u0442\u043e\u0442 \u043c\u0435\u0442\u043e\u0434 \u0432 \u043d\u0430\u0447\u0430\u043b\u043e \u043a\u043e\u0434\u0430 \u0432\u043c\u0435\u0441\u0442\u0435 \u0441 \u0444\u0443\u043d\u043a\u0446\u0438\u0435\u0439 normalize():<\/p>\n<pre><code class=\"python\">def reflected(vector, axis):    return vector \u2014 2 * np.dot(vector, axis) * axis<\/code><\/pre>\n<h2>\u041a\u043e\u0434<\/h2>\n<details class=\"spoiler\">\n<summary>\u041f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u043a\u043e\u0434<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"python\"># \u0433\u043b\u043e\u0431\u0430\u043b\u044c\u043d\u044b\u0435 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 max_depth = 3  # \u043d\u0443\u0436\u043d\u044b\u0435 \u0434\u0430\u043d\u043d\u044b\u0435 \u0434\u043b\u044f \u0446\u0438\u043a\u043b\u0430  color = np.zeros((3)) reflection = 1  for k in range(max_depth):    nearest_object, min_distance = # ...     # ...    illumination += # ...     # \u043e\u0442\u0440\u0430\u0436\u0435\u043d\u0438\u0435    color += reflection * illumination    reflection *= nearest_object['reflection']     # \u043d\u0430\u0447\u0430\u043b\u044c\u043d\u0430\u044f \u0442\u043e\u0447\u043a\u0430 \u0438 \u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u043d\u043e\u0432\u043e\u0433\u043e \u043b\u0443\u0447\u0430    origin = shifted_point    direction = reflected(direction, normal_to_surface) image[i, j] = np.clip(color, 0, 1)<\/code><\/pre>\n<\/div>\n<\/details>\n<p><strong><em>\u0412\u0430\u0436\u043d\u043e:<\/em><\/strong><em> \u0442\u0435\u043f\u0435\u0440\u044c, \u043a\u043e\u0433\u0434\u0430 \u043c\u044b \u043f\u043e\u043c\u0435\u0441\u0442\u0438\u043b\u0438 \u043f\u0435\u0440\u0435\u0441\u0435\u0447\u0435\u043d\u0438\u044f \u0432 \u0434\u0440\u0443\u0433\u043e\u0439 \u0446\u0438\u043a\u043b \u0434\u043b\u044f \u043e\u0442\u0440\u0430\u0436\u0435\u043d\u0438\u0439, \u043d\u0443\u0436\u043d\u043e \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043e\u043f\u0435\u0440\u0430\u0442\u043e\u0440\u044b break \u0432\u043e \u0438\u0437\u0431\u0435\u0436\u0430\u043d\u0438\u0435 \u0431\u0435\u0441\u043f\u043e\u043b\u0435\u0437\u043d\u044b\u0445 \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u0439.<\/em><\/p>\n<p>\u0412\u043e\u0442 \u0438 \u0432\u0441\u0435. \u0417\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u043c \u043a\u043e\u0434 \u0438 \u043d\u0430\u0431\u043b\u044e\u0434\u0430\u0435\u043c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442:<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/28d\/6ed\/82f\/28d6ed82ff1e81b310bf0c53fd19916b.png\" alt=\"\u0420\u0438\u0441\u0443\u043d\u043e\u043a 11\" title=\"\u0420\u0438\u0441\u0443\u043d\u043e\u043a 11\" width=\"1400\" height=\"787\"><figcaption>\u0420\u0438\u0441\u0443\u043d\u043e\u043a 11<\/figcaption><\/figure>\n<h3>\u041e\u043a\u043e\u043d\u0447\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u0439 \u043a\u043e\u0434<\/h3>\n<p>\u0418\u0442\u043e\u0433\u043e\u0432\u044b\u0439 \u043a\u043e\u0434 \u0441\u043e\u0441\u0442\u043e\u0438\u0442 \u0438\u0437 \u0432\u0441\u0435\u0433\u043e \u043f\u043e\u0440\u044f\u0434\u043a\u0430 \u0441\u043e\u0442\u043d\u0438 \u0441\u0442\u0440\u043e\u043a:<\/p>\n<details class=\"spoiler\">\n<summary>\u041f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u043a\u043e\u0434<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"python\">import numpy as np import matplotlib.pyplot as plt  def normalize(vector):     return vector \/ np.linalg.norm(vector)  def reflected(vector, axis):     return vector - 2 * np.dot(vector, axis) * axis   def sphere_intersect(center, radius, ray_origin, ray_direction):     b = 2 * np.dot(ray_direction, ray_origin - center)     c = np.linalg.norm(ray_origin - center) ** 2 - radius ** 2     delta = b ** 2 - 4 * c     if delta &gt; 0:         t1 = (-b + np.sqrt(delta)) \/ 2         t2 = (-b - np.sqrt(delta)) \/ 2         if t1 &gt; 0 and t2 &gt; 0:             return min(t1, t2)     return None  def nearest_intersected_object(objects, ray_origin, ray_direction):     distances = [sphere_intersect(obj['center'], obj['radius'], ray_origin, ray_direction) for obj in objects]     nearest_object = None     min_distance = np.inf     for index, distance in enumerate(distances):         if distance and distance &lt; min_distance:             min_distance = distance             nearest_object = objects[index]     return nearest_object, min_distance  width = 300 height = 200 max_depth = 3  camera = np.array([0, 0, 1]) ratio = float(width) \/ height screen = (-1, 1 \/ ratio, 1, -1 \/ ratio) # left, top, right, bottom  light = { 'position': np.array([5, 5, 5]), 'ambient': np.array([1, 1, 1]), 'diffuse': np.array([1, 1, 1]), 'specular': np.array([1, 1, 1]) }  objects = [     { 'center': np.array([-0.2, 0, -1]), 'radius': 0.7, 'ambient': np.array([0.1, 0, 0]), 'diffuse': np.array([0.7, 0, 0]), 'specular': np.array([1, 1, 1]), 'shininess': 100, 'reflection': 0.5 },     { 'center': np.array([0.1, -0.3, 0]), 'radius': 0.1, 'ambient': np.array([0.1, 0, 0.1]), 'diffuse': np.array([0.7, 0, 0.7]), 'specular': np.array([1, 1, 1]), 'shininess': 100, 'reflection': 0.5 },     { 'center': np.array([-0.3, 0, 0]), 'radius': 0.15, 'ambient': np.array([0, 0.1, 0]), 'diffuse': np.array([0, 0.6, 0]), 'specular': np.array([1, 1, 1]), 'shininess': 100, 'reflection': 0.5 },     { 'center': np.array([0, -9000, 0]), 'radius': 9000 - 0.7, 'ambient': np.array([0.1, 0.1, 0.1]), 'diffuse': np.array([0.6, 0.6, 0.6]), 'specular': np.array([1, 1, 1]), 'shininess': 100, 'reflection': 0.5 } ]  image = np.zeros((height, width, 3)) for i, y in enumerate(np.linspace(screen[1], screen[3], height)):     for j, x in enumerate(np.linspace(screen[0], screen[2], width)):          # \u044d\u043a\u0440\u0430\u043d \u0432 \u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e\u0439 \u0442\u043e\u0447\u043a\u0435          pixel = np.array([x, y, 0])         origin = camera         direction = normalize(pixel - origin)          color = np.zeros((3))         reflection = 1          for k in range(max_depth):              # \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u043f\u0435\u0440\u0435\u0441\u0435\u0447\u0435\u043d\u0438\u0439              nearest_object, min_distance = nearest_intersected_object(objects, origin, direction)             if nearest_object is None:                  break              intersection = origin + min_distance * direction             normal_to_surface = normalize(intersection - nearest_object['center'])             shifted_point = intersection + 1e-5 * normal_to_surface             intersection_to_light = normalize(light['position'] - shifted_point)              _, min_distance = nearest_intersected_object(objects, shifted_point, intersection_to_light)              intersection_to_light_distance = np.linalg.norm(light['position'] - intersection)             is_shadowed = min_distance &lt; intersection_to_light_distance              if is_shadowed:                 break              illumination = np.zeros((3))              # ambiant              illumination += nearest_object['ambient'] * light['ambient']              # diffuse              illumination += nearest_object['diffuse'] * light['diffuse'] * np.dot(intersection_to_light, normal_to_surface)              # specular              intersection_to_camera = normalize(camera - intersection)             H = normalize(intersection_to_light + intersection_to_camera)             illumination += nearest_object['specular'] * light['specular'] * np.dot(normal_to_surface, H) ** (nearest_object['shininess'] \/ 4)              # reflection              color += reflection * illumination             reflection *= nearest_object['reflection']             origin = shifted_point             direction = reflected(direction, normal_to_surface)         image[i, j] = np.clip(color, 0, 1)     print(\"%d\/%d\" % (i + 1, height)) plt.imsave('image.png', image)<\/code><\/pre>\n<\/div>\n<\/details>\n<h3>\u0427\u0442\u043e \u0434\u0430\u043b\u044c\u0448\u0435 ?<\/h3>\n<p>\u042d\u0442\u043e \u043e\u0447\u0435\u043d\u044c \u0443\u043f\u0440\u043e\u0449\u0435\u043d\u043d\u0430\u044f \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0430, \u043f\u0440\u0435\u0434\u043d\u0430\u0437\u043d\u0430\u0447\u0435\u043d\u043d\u0430\u044f \u0434\u043b\u044f \u043e\u0437\u043d\u0430\u043a\u043e\u043c\u043b\u0435\u043d\u0438\u044f \u0441 \u043e\u0441\u043d\u043e\u0432\u0430\u043c\u0438 \u0442\u0440\u0430\u0441\u0441\u0438\u0440\u043e\u0432\u043a\u0438 \u043b\u0443\u0447\u0435\u0439. \u0415\u0441\u0442\u044c \u043c\u043d\u043e\u0433\u043e \u0441\u043f\u043e\u0441\u043e\u0431\u043e\u0432 \u0443\u043b\u0443\u0447\u0448\u0438\u0442\u044c \u0435\u0435 \u0438 \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u0434\u0440\u0443\u0433\u0438\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440:<\/p>\n<ul>\n<li>\n<p>\u041c\u043e\u0436\u043d\u043e \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u043a\u043b\u0430\u0441\u0441\u044b \u0438 \u0432\u044b\u044f\u0441\u043d\u0438\u0442\u044c, \u0447\u0442\u043e \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0441\u043f\u0435\u0446\u0438\u0444\u0438\u0447\u0435\u0441\u043a\u0438\u043c \u0434\u043b\u044f \u0441\u0444\u0435\u0440, \u0430 \u0447\u0442\u043e \u043d\u0435\u0442, \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u0442\u044c \u0431\u0430\u0437\u043e\u0432\u044b\u0439 \u043a\u043b\u0430\u0441\u0441 \u0438 \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u0434\u0440\u0443\u0433\u0438\u0435 \u043e\u0431\u044a\u0435\u043a\u0442\u044b, \u0442\u0430\u043a\u0438\u0435 \u043a\u0430\u043a \u043f\u043b\u043e\u0441\u043a\u043e\u0441\u0442\u0438 \u0438\u043b\u0438 \u0442\u0440\u0435\u0443\u0433\u043e\u043b\u044c\u043d\u0438\u043a\u0438;<\/p>\n<\/li>\n<li>\n<p>\u0422\u043e \u0436\u0435 \u0441\u0430\u043c\u043e\u0435 \u0438 \u0441\u043e \u0441\u0432\u0435\u0442\u043e\u043c. \u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0441\u044e\u0434\u0430 POO \u0438 \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0442\u0430\u043a, \u0447\u0442\u043e\u0431\u044b \u043c\u043e\u0436\u043d\u043e \u0431\u044b\u043b\u043e \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a\u043e\u0432 \u0441\u0432\u0435\u0442\u0430 \u0432 \u0441\u0446\u0435\u043d\u0443;<\/p>\n<\/li>\n<li>\n<p>\u041e\u0442\u0434\u0435\u043b\u0438\u0442\u044c \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0430 \u043c\u0430\u0442\u0435\u0440\u0438\u0430\u043b\u0430 \u043e\u0442 \u0433\u0435\u043e\u043c\u0435\u0442\u0440\u0438\u0447\u0435\u0441\u043a\u0438\u0445 \u0441\u0432\u043e\u0439\u0441\u0442\u0432, \u0447\u0442\u043e\u0431\u044b \u0438\u043c\u0435\u0442\u044c \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u043f\u0440\u0438\u043c\u0435\u043d\u044f\u0442\u044c \u043e\u0434\u0438\u043d \u043c\u0430\u0442\u0435\u0440\u0438\u0430\u043b (\u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0441\u0438\u043d\u0438\u0439 \u043c\u0430\u0442\u043e\u0432\u044b\u0439) \u043a \u043b\u044e\u0431\u043e\u043c\u0443 \u0442\u0438\u043f\u0443 \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432;<\/p>\n<\/li>\n<li>\n<p>\u041d\u0430\u0439\u0442\u0438 \u0441\u043f\u043e\u0441\u043e\u0431 \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e \u0440\u0430\u0441\u043f\u043e\u043b\u043e\u0436\u0438\u0442\u044c \u044d\u043a\u0440\u0430\u043d \u043f\u0440\u0438 \u043b\u044e\u0431\u043e\u043c \u043f\u043e\u043b\u043e\u0436\u0435\u043d\u0438\u0438 \u0438 \u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0438 \u043a\u0430\u043c\u0435\u0440\u044b;<\/p>\n<\/li>\n<li>\n<p>\u0421\u043c\u043e\u0434\u0435\u043b\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0441\u0432\u0435\u0442 \u043f\u043e-\u0434\u0440\u0443\u0433\u043e\u043c\u0443. \u0412 \u043d\u0430\u0441\u0442\u043e\u044f\u0449\u0435\u0435 \u0432\u0440\u0435\u043c\u044f \u044d\u0442\u043e \u043e\u0434\u043d\u0430 \u0442\u043e\u0447\u043a\u0430, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0442\u0435\u043d\u0438 \u043e\u0442 \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432 \u00ab\u0436\u0435\u0441\u0442\u043a\u0438\u0435\u00bb \u0438\u043b\u0438 \u0447\u0435\u0442\u043a\u043e \u043e\u0447\u0435\u0440\u0447\u0435\u043d\u043d\u044b\u0435. \u0427\u0442\u043e\u0431\u044b \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u00ab\u043c\u044f\u0433\u043a\u0438\u0435\u00bb \u0442\u0435\u043d\u0438 , \u043d\u0443\u0436\u043d\u043e \u0441\u043c\u043e\u0434\u0435\u043b\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a \u0441\u0432\u0435\u0442\u0430 \u043a\u0430\u043a 2D- \u0438\u043b\u0438 3D-\u043e\u0431\u044a\u0435\u043a\u0442: \u0434\u0438\u0441\u043a \u0438\u043b\u0438 \u0441\u0444\u0435\u0440\u0443.<\/p>\n<\/li>\n<\/ul>\n<h3>\u0411\u043e\u043d\u0443\u0441<\/h3>\n<p>\u041d\u0438\u0436\u0435 \u043f\u0440\u0438\u0432\u0435\u0434\u0435\u043d\u0430 \u0430\u043d\u0438\u043c\u0430\u0446\u0438\u044f \u0442\u0440\u0430\u0441\u0441\u0438\u0440\u043e\u0432\u043a\u0438 \u043b\u0443\u0447\u0435\u0439. \u041f\u043e \u0441\u0443\u0442\u0438 \u044d\u0442\u043e \u043f\u0440\u043e\u0441\u0442\u043e \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0440\u0430\u0437 \u043e\u0442\u0440\u0435\u043d\u0434\u0435\u0440\u0435\u043d\u043d\u0430\u044f \u0441\u0446\u0435\u043d\u0430 \u0441 \u043a\u0430\u043c\u0435\u0440\u043e\u0439 \u0432 \u0440\u0430\u0437\u043d\u044b\u0445 \u043f\u043e\u043b\u043e\u0436\u0435\u043d\u0438\u044f\u0445:<\/p>\n<p><iframe id=\"604890128a93442df6782295\" src=\"https:\/\/embedd.srv.habr.com\/iframe\/604890128a93442df6782295\" class=\"embed_video embed__content\" allowfullscreen=\"true\"><\/iframe><\/p>\n<p>\u041a\u043e\u0434 \u043d\u0430\u043f\u0438\u0441\u0430\u043d \u043d\u0430 Kotlin (\u043c\u043e\u0436\u043d\u043e \u043e\u0446\u0435\u043d\u0438\u0442\u044c, \u043d\u0430\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043c\u0435\u0434\u043b\u0435\u043d\u043d\u044b\u0439 \u043f\u043e \u0441\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u044e \u0441 \u043d\u0438\u043c Python) \u0438 \u0434\u043e\u0441\u0442\u0443\u043f\u0435\u043d \u043d\u0430 <a href=\"https:\/\/github.com\/OmarAflak\/RayTracer-Kotlin\">GitHub.<\/a><\/p>\n<\/div>\n<p> \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\/company\/pixonic\/blog\/546328\/\"> https:\/\/habr.com\/ru\/company\/pixonic\/blog\/546328\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"\n<div class=\"post__text post__text_v2\" id=\"post-content-body\">\n<figure class=\"full-width\"><figcaption>\u0420\u0438\u0441\u0443\u043d\u043e\u043a 1<\/figcaption><\/figure>\n<p>\u0412 \u044d\u0442\u043e\u043c \u043f\u043e\u0441\u0442\u0435 \u043c\u044b \u0437\u0430\u0433\u043b\u044f\u043d\u0435\u043c \u043f\u043e\u0434 \u043a\u0430\u043f\u043e\u0442 \u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c\u043e\u0432 \u043a\u043e\u043c\u043f\u044c\u044e\u0442\u0435\u0440\u043d\u043e\u0439 \u0433\u0440\u0430\u0444\u0438\u043a\u0438, \u043f\u043e\u0448\u0430\u0433\u043e\u0432\u043e \u0440\u0430\u0437\u0431\u0435\u0440\u0435\u043c \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u0435 \u043f\u0440\u0438\u043d\u0446\u0438\u043f\u044b \u0442\u0440\u0430\u0441\u0441\u0438\u0440\u043e\u0432\u043a\u0438 \u043b\u0443\u0447\u0435\u0439 \u0438 \u043d\u0430\u043f\u0438\u0448\u0435\u043c \u0435\u0435 \u043f\u0440\u043e\u0441\u0442\u0443\u044e \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e \u043d\u0430 Python. \u041d\u0438\u043a\u0430\u043a\u0438\u0445 \u0441\u0442\u043e\u0440\u043e\u043d\u043d\u0438\u0445 \u0433\u0440\u0430\u0444\u0438\u0447\u0435\u0441\u043a\u0438\u0445 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a \u2014 \u0442\u043e\u043b\u044c\u043a\u043e <em>NumPy <\/em>\u0438 \u0433\u043e\u043b\u044b\u0439 \u043a\u043e\u0434 \u0432 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440\u0435.<\/p>\n<p><em>\u041f\u0440\u0438\u043c\u0435\u0447\u0430\u043d\u0438\u0435:<\/em> \u042d\u0442\u0430 \u0441\u0442\u0430\u0442\u044c\u044f \u043d\u0438 \u0432 \u043a\u043e\u0435\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u043d\u0435 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043f\u043e\u043b\u043d\u044b\u043c \u0440\u0443\u043a\u043e\u0432\u043e\u0434\u0441\u0442\u0432\u043e\u043c\/\u043e\u0431\u044a\u044f\u0441\u043d\u0435\u043d\u0438\u0435\u043c \u0442\u0440\u0430\u0441\u0441\u0438\u0440\u043e\u0432\u043a\u0438 \u043b\u0443\u0447\u0435\u0439, \u043f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u044d\u0442\u0430 \u0442\u0435\u043c\u0430 \u0441\u043b\u0438\u0448\u043a\u043e\u043c \u043e\u0431\u0448\u0438\u0440\u043d\u0430, \u0430 \u0441\u043a\u043e\u0440\u0435\u0435 \u043f\u0440\u043e\u0441\u0442\u043e \u0432\u0432\u0435\u0434\u0435\u043d\u0438\u0435\u043c \u0434\u043b\u044f \u043b\u044e\u0431\u043e\u043f\u044b\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0445.<\/p>\n<h3>\u041f\u0440\u0435\u0434\u043f\u043e\u0441\u044b\u043b\u043a\u0438<\/h3>\n<p>\u041d\u0430\u043c \u043f\u043e\u043d\u0430\u0434\u043e\u0431\u0438\u0442\u0441\u044f \u0442\u043e\u043b\u044c\u043a\u043e \u0441\u0430\u043c\u0430\u044f \u0431\u0430\u0437\u043e\u0432\u0430\u044f \u0432\u0435\u043a\u0442\u043e\u0440\u043d\u0430\u044f \u0433\u0435\u043e\u043c\u0435\u0442\u0440\u0438\u044f:<\/p>\n<ul>\n<li>\n<p>\u041f\u0443\u0441\u0442\u044c \u0443 \u043d\u0430\u0441 \u0435\u0441\u0442\u044c \u0434\u0432\u0435 \u0442\u043e\u0447\u043a\u0438 A \u0438 B \u2014 \u043d\u0435\u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e \u043e\u0442 \u0440\u0430\u0437\u043c\u0435\u0440\u043d\u043e\u0441\u0442\u0438: 1, 2, 3,\u2026, n, \u2014 \u0442\u043e\u0433\u0434\u0430 \u0432\u0435\u043a\u0442\u043e\u0440, \u0438\u0434\u0443\u0449\u0438\u0439 \u043e\u0442 A \u043a B, \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u043d\u0430\u0439\u0434\u0435\u043d \u043f\u0443\u0442\u0435\u043c \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u044f B \u2014 A (\u043f\u043e\u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043d\u043e);<\/p>\n<\/li>\n<li>\n<p>\u0414\u043b\u0438\u043d\u0443 \u0432\u0435\u043a\u0442\u043e\u0440\u0430 \u2014 \u043d\u0435\u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e \u043e\u0442 \u0435\u0433\u043e \u0440\u0430\u0437\u043c\u0435\u0440\u043d\u043e\u0441\u0442\u0438 \u2014 \u043c\u043e\u0436\u043d\u043e \u043d\u0430\u0439\u0442\u0438, \u0432\u044b\u0447\u0438\u0441\u043b\u0438\u0432 \u043a\u0432\u0430\u0434\u0440\u0430\u0442\u043d\u044b\u0439 \u043a\u043e\u0440\u0435\u043d\u044c \u0438\u0437 \u0441\u0443\u043c\u043c\u044b \u0432\u043e\u0437\u0432\u0435\u0434\u0435\u043d\u043d\u044b\u0445 \u0432 \u043a\u0432\u0430\u0434\u0440\u0430\u0442 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432. \u0414\u043b\u0438\u043d\u0430 \u0432\u0435\u043a\u0442\u043e\u0440\u0430 v \u043e\u0431\u043e\u0437\u043d\u0430\u0447\u0430\u0435\u0442\u0441\u044f ||v||;<\/p>\n<\/li>\n<li>\n<p><em>\u0415\u0434\u0438\u043d\u0438\u0447\u043d\u044b\u0439 \u0432\u0435\u043a\u0442\u043e\u0440<\/em> \u2014 \u044d\u0442\u043e \u0432\u0435\u043a\u0442\u043e\u0440 \u0434\u043b\u0438\u043d\u044b 1: ||v|| = 1;<\/p>\n<\/li>\n<li>\n<p>\u0414\u043b\u044f \u0434\u0430\u043d\u043d\u043e\u0433\u043e \u0432\u0435\u043a\u0442\u043e\u0440\u0430 \u0434\u0440\u0443\u0433\u043e\u0439 \u0432\u0435\u043a\u0442\u043e\u0440, \u0438\u0434\u0443\u0449\u0438\u0439 \u0432 \u0442\u043e\u043c \u0436\u0435 \u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0438, \u043d\u043e \u0438\u043c\u0435\u044e\u0449\u0438\u0439 \u0434\u043b\u0438\u043d\u0443 1, \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u043d\u0430\u0439\u0434\u0435\u043d \u043f\u0443\u0442\u0435\u043c \u0434\u0435\u043b\u0435\u043d\u0438\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430 \u043f\u0435\u0440\u0432\u043e\u0433\u043e \u0432\u0435\u043a\u0442\u043e\u0440\u0430 \u043d\u0430 \u0435\u0433\u043e \u0434\u043b\u0438\u043d\u0443 \u2014 \u044d\u0442\u043e \u043d\u0430\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u043d\u043e\u0440\u043c\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0435\u0439: u = v\/||v||;<\/p>\n<\/li>\n<li>\n<p>\u0422\u043e\u0447\u0435\u0447\u043d\u043e\u0435 \u043f\u0440\u043e\u0438\u0437\u0432\u0435\u0434\u0435\u043d\u0438\u0435 \u0434\u043b\u044f \u0432\u0435\u043a\u0442\u043e\u0440\u043e\u0432 \u0432\u044b\u0447\u0438\u0441\u043b\u044f\u0435\u0442\u0441\u044f \u043a\u0430\u043a: &lt;v, v&gt; = ||v||\u00b2.<\/p>\n<\/li>\n<\/ul>\n<h3>\u0410\u043b\u0433\u043e\u0440\u0438\u0442\u043c \u0442\u0440\u0430\u0441\u0441\u0438\u0440\u043e\u0432\u043a\u0438 \u043b\u0443\u0447\u0435\u0439<\/h3>\n<p><em>\u0422\u0440\u0430\u0441\u0441\u0438\u0440\u043e\u0432\u043a\u0430 \u043b\u0443\u0447\u0435\u0439<\/em> \u2014 \u044d\u0442\u043e \u043c\u0435\u0442\u043e\u0434 <strong>\u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433\u0430<\/strong>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0438\u043c\u0438\u0442\u0438\u0440\u0443\u0435\u0442 <strong>\u043f\u0443\u0442\u044c \u0441\u0432\u0435\u0442\u0430<\/strong> \u0438 <strong>\u043f\u0435\u0440\u0435\u0441\u0435\u0447\u0435\u043d\u0438\u044f \u0441 \u043e\u0431\u044a\u0435\u043a\u0442\u0430\u043c\u0438<\/strong> \u0438 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u0441 \u0432\u044b\u0441\u043e\u043a\u043e\u0439 \u0441\u0442\u0435\u043f\u0435\u043d\u044c\u044e \u0440\u0435\u0430\u043b\u0438\u0437\u043c\u0430. \u0411\u043e\u043b\u0435\u0435 \u043e\u043f\u0442\u0438\u043c\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u044b \u044d\u0442\u043e\u0433\u043e \u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c\u0430 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442\u0441\u044f \u0432 \u0432\u0438\u0434\u0435\u043e\u0438\u0433\u0440\u0430\u0445.<\/p>\n<p>\u0427\u0442\u043e\u0431\u044b \u043e\u0431\u044a\u044f\u0441\u043d\u0438\u0442\u044c \u0440\u0430\u0431\u043e\u0442\u0443 \u044d\u0442\u043e\u0433\u043e \u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c\u0430, \u0441\u043d\u0430\u0447\u0430\u043b\u0430 \u043d\u0443\u0436\u043d\u043e \u043d\u0430\u0441\u0442\u0440\u043e\u0438\u0442\u044c \u0441\u0446\u0435\u043d\u0443:<\/p>\n<ul>\n<li>\n<p><strong>\u0422\u0440\u0435\u0445\u043c\u0435\u0440\u043d\u043e\u0435 \u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u043e<\/strong> (\u043c\u044b \u0441\u043e\u0431\u0438\u0440\u0430\u0435\u043c\u0441\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0442\u0440\u0438 \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u044b \u0434\u043b\u044f \u043f\u043e\u0437\u0438\u0446\u0438\u043e\u043d\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432 \u0432 \u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u0435);<\/p>\n<\/li>\n<li>\n<p><strong>\u041e\u0431\u044a\u0435\u043a\u0442\u044b<\/strong> \u0432 \u044d\u0442\u043e\u043c \u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u0435 (\u043f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u043c\u044b \u0441\u043e\u0431\u0438\u0440\u0430\u0435\u043c\u0441\u044f \u0432\u043e\u0441\u043f\u0440\u043e\u0438\u0437\u0432\u0435\u0441\u0442\u0438 \u0440\u0438\u0441. 1, \u0442\u043e \u0432\u043e\u0437\u044c\u043c\u0435\u043c \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432 \u0441\u0444\u0435\u0440\u044b);<\/p>\n<\/li>\n<li>\n<p><strong>\u0418\u0441\u0442\u043e\u0447\u043d\u0438\u043a \u0441\u0432\u0435\u0442\u0430<\/strong> (\u0432 \u043d\u0430\u0448\u0435\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u044d\u0442\u043e \u043e\u0434\u043d\u0430 \u0442\u043e\u0447\u043a\u0430, \u0438\u0437\u043b\u0443\u0447\u0430\u044e\u0449\u0430\u044f \u0441\u0432\u0435\u0442 \u0432\u043e \u0432\u0441\u0435\u0445 \u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f\u0445);<\/p>\n<\/li>\n<li>\n<p><strong>\u041a\u0430\u043c\u0435\u0440\u0430<\/strong> \u0434\u043b\u044f \u043d\u0430\u0431\u043b\u044e\u0434\u0435\u043d\u0438\u044f \u0437\u0430 \u0441\u0446\u0435\u043d\u043e\u0439;<\/p>\n<\/li>\n<li>\n<p><strong>\u042d\u043a\u0440\u0430\u043d<\/strong>, \u0447\u0435\u0440\u0435\u0437 \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043a\u0430\u043c\u0435\u0440\u0430 \u0441\u043c\u043e\u0442\u0440\u0438\u0442 \u043d\u0430 \u043e\u0431\u044a\u0435\u043a\u0442\u044b (\u0447\u0435\u0442\u044b\u0440\u0435 \u0442\u043e\u0447\u043a\u0438 \u0434\u043b\u044f \u0447\u0435\u0442\u044b\u0440\u0435\u0445 \u0443\u0433\u043b\u043e\u0432 \u043f\u0440\u044f\u043c\u043e\u0443\u0433\u043e\u043b\u044c\u043d\u043e\u0433\u043e \u044d\u043a\u0440\u0430\u043d\u0430).<\/p>\n<\/li>\n<\/ul>\n<figure class=\"full-width\"><figcaption>\u0420\u0438\u0441\u0443\u043d\u043e\u043a 2<\/figcaption><\/figure>\n<p><strong><em>\u042d\u043a\u0440\u0430\u043d<\/em><\/strong> \u2014 \u044d\u0442\u043e \u043d\u0435\u043a\u0430\u044f \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u0430\u044f \u0432\u0430\u043c\u0438 \u0433\u0435\u043e\u043c\u0435\u0442\u0440\u0438\u0447\u0435\u0441\u043a\u0430\u044f \u0444\u0438\u0433\u0443\u0440\u0430 (\u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u043f\u0440\u044f\u043c\u043e\u0443\u0433\u043e\u043b\u044c\u043d\u0438\u043a 3&#215;2). \u041d\u043e \u0441\u0430\u043c\u0438 \u043f\u043e \u0441\u0435\u0431\u0435 \u0446\u0438\u0444\u0440\u044b 3 \u0438 2 \u043d\u0438 \u043e \u0447\u0435\u043c \u043d\u0430\u043c \u043d\u0435 \u0433\u043e\u0432\u043e\u0440\u044f\u0442 \u0438 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u043d\u0430\u0447\u0438\u043d\u0430\u044e\u0442 \u043f\u0440\u0438\u043e\u0431\u0440\u0435\u0442\u0430\u0442\u044c \u043a\u0430\u043a\u043e\u0435-\u0442\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u0440\u0438 \u0441\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u0438 \u0438\u0445 \u0441 \u0440\u0430\u0437\u043c\u0435\u0440\u0430\u043c\u0438 \u0434\u0440\u0443\u0433\u0438\u0445 \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432. \u0417\u0434\u0435\u0441\u044c \u0432\u0430\u0436\u043d\u043e \u0442\u043e, \u043a\u0430\u043a \u0432\u044b \u0440\u0430\u0437\u0434\u0435\u043b\u0438\u0442\u0435 \u0432\u0430\u0448 \u043f\u0440\u044f\u043c\u043e\u0443\u0433\u043e\u043b\u044c\u043d\u0438\u043a \u043d\u0430 \u0431\u043e\u043b\u0435\u0435 \u043c\u0435\u043b\u043a\u0438\u0435 \u043a\u0432\u0430\u0434\u0440\u0430\u0442\u044b (\u043f\u0438\u043a\u0441\u0435\u043b\u0438), \u043a\u0430\u043a \u043d\u0430 \u0440\u0438\u0441\u0443\u043d\u043a\u0435 \u0432\u044b\u0448\u0435. \u042d\u0442\u043e \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u0442 \u0440\u0430\u0437\u043c\u0435\u0440 \u043a\u043e\u043d\u0435\u0447\u043d\u043e\u0433\u043e \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f. \u0414\u0440\u0443\u0433\u0438\u043c\u0438 \u0441\u043b\u043e\u0432\u0430\u043c\u0438, \u043c\u043e\u0436\u043d\u043e \u0432\u0437\u044f\u0442\u044c \u043f\u0440\u044f\u043c\u043e\u0443\u0433\u043e\u043b\u044c\u043d\u0438\u043a 3&#215;2 \u0438 \u0440\u0430\u0437\u0434\u0435\u043b\u0438\u0442\u044c \u0435\u0433\u043e \u043d\u0430 300&#215;200 \u043f\u0438\u043a\u0441\u0435\u043b\u0435\u0439.<\/p>\n<p>\u041d\u0430\u043f\u0438\u0448\u0435\u043c \u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c \u0442\u0440\u0430\u0441\u0441\u0438\u0440\u043e\u0432\u043a\u0438 \u043b\u0443\u0447\u0435\u0439 \u0441 \u0443\u0447\u0435\u0442\u043e\u043c \u0437\u0430\u0434\u0430\u043d\u043d\u043e\u0439 <strong>\u0441\u0446\u0435\u043d\u044b<\/strong>:<\/p>\n<blockquote>\n<p><em>\u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u043f\u0438\u043a\u0441\u0435\u043b\u044f <\/em><strong><em>p<\/em><\/strong><em>(x, y, z) \u044d\u043a\u0440\u0430\u043d\u0430:<\/em><\/p>\n<p><em>&nbsp;&nbsp;&nbsp;\u0430\u0441\u0441\u043e\u0446\u0438\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0447\u0435\u0440\u043d\u044b\u0439 \u0446\u0432\u0435\u0442 \u0441 <\/em><strong><em>p<\/em><\/strong><\/p>\n<p><em>&nbsp;&nbsp;&nbsp;\u0435\u0441\u043b\u0438 \u043b\u0443\u0447 (\u043b\u0438\u043d\u0438\u044f), \u043d\u0430\u0447\u0438\u043d\u0430\u044e\u0449\u0438\u0439\u0441\u044f \u043e\u0442 <\/em><strong><em>\u043a\u0430\u043c\u0435\u0440\u044b<\/em><\/strong><em> \u0438 \u0438\u0434\u0443\u0449\u0438\u0439 \u043a \u0442\u043e\u0447\u043a\u0435 <\/em><strong><em>p<\/em><\/strong><em>, \u043f\u0435\u0440\u0435\u0441\u0435\u043a\u0430\u0435\u0442 \u043b\u044e\u0431\u043e\u0439 \u043e\u0431\u044a\u0435\u043a\u0442 \u0441\u0446\u0435\u043d\u044b, \u0442\u043e:<\/em><\/p>\n<p><em>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\u0432\u044b\u0447\u0438\u0441\u043b\u0438\u0442\u044c <\/em><strong><em>\u0442\u043e\u0447\u043a\u0443 \u043f\u0435\u0440\u0435\u0441\u0435\u0447\u0435\u043d\u0438\u044f<\/em><\/strong><em> \u0441 \u0431\u043b\u0438\u0436\u0430\u0439\u0448\u0438\u043c \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u043c<\/em><\/p>\n<p><em>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\u0435\u0441\u043b\u0438 \u043c\u0435\u0436\u0434\u0443 <\/em><strong><em>\u0442\u043e\u0447\u043a\u043e\u0439 \u043f\u0435\u0440\u0435\u0441\u0435\u0447\u0435\u043d\u0438\u044f<\/em><\/strong><em> \u0438 \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a\u043e\u043c <\/em><strong><em>\u0441\u0432\u0435\u0442\u0430<\/em><\/strong><em> \u043d\u0435\u0442 \u043e\u0431\u044a\u0435\u043a\u0442\u0430, \u0442\u043e\u0433\u0434\u0430:<\/em><\/p>\n<p><em>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\u0440\u0430\u0441\u0441\u0447\u0438\u0442\u0430\u0442\u044c \u0446\u0432\u0435\u0442 <\/em><strong><em>\u0442\u043e\u0447\u043a\u0438 \u043f\u0435\u0440\u0435\u0441\u0435\u0447\u0435\u043d\u0438\u044f<\/em><\/strong><\/p>\n<p><em>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\u0441\u043e\u043f\u043e\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u0446\u0432\u0435\u0442 <\/em><strong><em>\u0442\u043e\u0447\u043a\u0438 \u043f\u0435\u0440\u0435\u0441\u0435\u0447\u0435\u043d\u0438\u044f<\/em><\/strong><em> \u0441 <\/em><strong><em>p<\/em><\/strong><\/p>\n<\/blockquote>\n<figure class=\"full-width\"><figcaption>\u0420\u0438\u0441\u0443\u043d\u043e\u043a 3<\/figcaption><\/figure>\n<p><em>\u041e\u0431\u0440\u0430\u0442\u0438\u0442\u0435 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435, \u0447\u0442\u043e \u044d\u0442\u043e\u0442 \u043f\u0440\u043e\u0446\u0435\u0441\u0441 \u043d\u0430 \u0434\u0435\u043b\u0435 \u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u043e\u0431\u0440\u0430\u0442\u043d\u044b\u043c \u0440\u0435\u0430\u043b\u044c\u043d\u043e\u043c\u0443 \u043e\u0441\u0432\u0435\u0449\u0435\u043d\u0438\u044e. \u0412\u0435\u0434\u044c \u0440\u0435\u0430\u043b\u044c\u043d\u044b\u0439 \u0441\u0432\u0435\u0442 \u0432\u044b\u0445\u043e\u0434\u0438\u0442 \u0438\u0437 \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a\u0430 \u0432\u043e \u0432\u0441\u0435\u0445 \u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f\u0445, \u043e\u0442\u0440\u0430\u0436\u0430\u0435\u0442\u0441\u044f \u043e\u0442 \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432 \u0438 \u043f\u043e\u043f\u0430\u0434\u0430\u0435\u0442 \u0432 \u043a\u0430\u043c\u0435\u0440\u0443. \u041e\u0434\u043d\u0430\u043a\u043e, \u043f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u043d\u0435 \u0432\u0441\u0435 \u043b\u0443\u0447\u0438, \u0432\u044b\u0445\u043e\u0434\u044f\u0449\u0438\u0435 \u0438\u0437 \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a\u0430 \u0441\u0432\u0435\u0442\u0430, \u043f\u043e\u043f\u0430\u0434\u0443\u0442 \u0432 \u043a\u0430\u043c\u0435\u0440\u0443, \u0442\u0440\u0430\u0441\u0441\u0438\u0440\u043e\u0432\u043a\u0430 \u043b\u0443\u0447\u0435\u0439 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442 \u043e\u0431\u0440\u0430\u0442\u043d\u044b\u0439 \u043f\u0440\u043e\u0446\u0435\u0441\u0441 \u0434\u043b\u044f \u044d\u043a\u043e\u043d\u043e\u043c\u0438\u0438 \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u0439 (\u043e\u0442\u0441\u043b\u0435\u0436\u0438\u0432\u0430\u0435\u0442 \u043b\u0443\u0447\u0438 \u043e\u0442 \u043a\u0430\u043c\u0435\u0440\u044b \u043e\u0431\u0440\u0430\u0442\u043d\u043e \u043a \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a\u0443 \u0441\u0432\u0435\u0442\u0430).<\/em><\/p>\n<h3>\u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430 \u0441\u0446\u0435\u043d\u044b<\/h3>\n<p>\u041f\u0435\u0440\u0435\u0434 \u0442\u0435\u043c, \u043a\u0430\u043a \u043d\u0430\u0447\u0430\u0442\u044c \u043f\u0438\u0441\u0430\u0442\u044c \u043a\u043e\u0434, \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u043d\u0430\u0441\u0442\u0440\u043e\u0438\u0442\u044c \u0441\u0446\u0435\u043d\u0443. \u0412 \u043f\u0435\u0440\u0432\u0443\u044e \u043e\u0447\u0435\u0440\u0435\u0434\u044c \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u043c\u0441\u044f, \u0433\u0434\u0435 \u0440\u0430\u0441\u043f\u043e\u043b\u043e\u0436\u0435\u043d\u044b <strong><em>\u043a\u0430\u043c\u0435\u0440\u0430<\/em><\/strong> \u0438 <strong><em>\u044d\u043a\u0440\u0430\u043d<\/em><\/strong>. \u0414\u043b\u044f \u044d\u0442\u043e\u0439 \u0446\u0435\u043b\u0438 \u043f\u0440\u0438\u043c\u0435\u043c \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0443\u043f\u0440\u043e\u0449\u0435\u043d\u0438\u044f, \u0441\u043e\u0432\u043c\u0435\u0441\u0442\u0438\u0432 \u043e\u0431\u044a\u0435\u043a\u0442\u044b \u0441 \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u043d\u044b\u043c\u0438 \u043e\u0441\u044f\u043c\u0438.<\/p>\n<figure class=\"full-width\"><figcaption>\u0420\u0438\u0441\u0443\u043d\u043e\u043a 4<\/figcaption><\/figure>\n<p>\u0414\u043e\u043f\u0443\u0441\u0442\u0438\u043c, <strong><em>\u043a\u0430\u043c\u0435\u0440\u0430<\/em><\/strong> \u0440\u0430\u0441\u043f\u043e\u043b\u043e\u0436\u0435\u043d\u0430 \u0432 \u0442\u043e\u0447\u043a\u0435 (<strong>x = 0<\/strong>, <strong>y = 0<\/strong>, <strong>z = 1<\/strong>), \u0430 <strong><em>\u044d\u043a\u0440\u0430\u043d<\/em><\/strong> \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0447\u0430\u0441\u0442\u044c\u044e \u043f\u043b\u043e\u0441\u043a\u043e\u0441\u0442\u0438, \u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u043d\u043e\u0439 \u043e\u0441\u044f\u043c\u0438 <strong><em>x<\/em><\/strong> \u0438 <strong><em>y<\/em><\/strong>. \u0422\u0435\u043f\u0435\u0440\u044c \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u0441\u043a\u0435\u043b\u0435\u0442 \u043d\u0430\u0448\u0435\u0433\u043e \u043a\u043e\u0434\u0430.<\/p>\n<details class=\"spoiler\">\n<summary>\u041f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u043a\u043e\u0434<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"python\">import numpy as np import matplotlib.pyplot as plt width = 300 height = 200 camera = np.array([0, 0, 1]) ratio = float(width) \/ height screen = (-1, 1 \/ ratio, 1, -1 \/ ratio) # \u0441\u043b\u0435\u0432\u0430, \u0441\u0432\u0435\u0440\u0445\u0443, \u0441\u043f\u0440\u0430\u0432\u0430, \u0441\u043d\u0438\u0437\u0443 image = np.zeros((height, width, 3)) for i, y in enumerate(np.linspace(screen[1], screen[3], height)): &nbsp; &nbsp; for j, x in enumerate(np.linspace(screen[0], screen[2], width)): &nbsp; &nbsp; &nbsp; &nbsp; # image[i, j] = ... &nbsp; &nbsp; &nbsp; &nbsp; print(\"progress: %d\/%d\" % (i + 1, height)) plt.imsave('image.png', image)<\/code><\/pre>\n<\/div>\n<\/details>\n<ul>\n<li>\n<p><strong><em>\u041a\u0430\u043c\u0435\u0440\u0430<\/em><\/strong> \u2014 \u044d\u0442\u043e \u043f\u0440\u043e\u0441\u0442\u043e \u0442\u043e\u0447\u043a\u0430, \u0438\u043c\u0435\u044e\u0449\u0430\u044f \u0442\u0440\u0438 \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u044b;<\/p>\n<\/li>\n<li>\n<p>\u0421 \u0434\u0440\u0443\u0433\u043e\u0439 \u0441\u0442\u043e\u0440\u043e\u043d\u044b, <strong><em>\u044d\u043a\u0440\u0430\u043d<\/em><\/strong> \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u0442\u0441\u044f \u0447\u0435\u0442\u044b\u0440\u044c\u043c\u044f \u0447\u0438\u0441\u043b\u0430\u043c\u0438 (\u0438\u043b\u0438 \u0434\u0432\u0443\u043c\u044f \u0442\u043e\u0447\u043a\u0430\u043c\u0438): <em>\u0441\u043b\u0435\u0432\u0430, \u0441\u0432\u0435\u0440\u0445\u0443, \u0441\u043f\u0440\u0430\u0432\u0430, \u0441\u043d\u0438\u0437\u0443<\/em>. \u041e\u043d \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u0432 \u0434\u0438\u0430\u043f\u0430\u0437\u043e\u043d\u0435 \u043e\u0442 -1 \u0434\u043e 1 \u0432 \u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0438 <strong><em>x<\/em><\/strong> \u0438 \u043e\u0442 -1\/ratio \u0434\u043e 1\/ratio \u0432 \u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0438 <strong><em>y<\/em><\/strong>, \u0433\u0434\u0435 ratio \u2014 \u0448\u0438\u0440\u0438\u043d\u0430 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f, \u0434\u0435\u043b\u0435\u043d\u043d\u0430\u044f \u043d\u0430 \u0435\u0433\u043e \u0432\u044b\u0441\u043e\u0442\u0443. \u042d\u0442\u043e \u0432\u044b\u0442\u0435\u043a\u0430\u0435\u0442 \u0438\u0437 \u0442\u043e\u0433\u043e, \u0447\u0442\u043e \u043c\u044b \u0445\u043e\u0442\u0438\u043c, \u0447\u0442\u043e\u0431\u044b <strong><em>\u044d\u043a\u0440\u0430\u043d<\/em><\/strong> \u0438\u043c\u0435\u043b \u0442\u0430\u043a\u043e\u0435 \u0436\u0435 \u0441\u043e\u043e\u0442\u043d\u043e\u0448\u0435\u043d\u0438\u0435 \u0441\u0442\u043e\u0440\u043e\u043d, \u0447\u0442\u043e \u0438 \u0444\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u0435 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435. \u041f\u0440\u0438 \u0442\u0430\u043a\u043e\u0439 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0435 <strong><em>\u044d\u043a\u0440\u0430\u043d\u0430<\/em><\/strong> \u0431\u0443\u0434\u0435\u0442 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043e \u0441\u043e\u043e\u0442\u043d\u043e\u0448\u0435\u043d\u0438\u0435 \u0441\u0442\u043e\u0440\u043e\u043d (\u0448\u0438\u0440\u0438\u043d\u0430 \u043a \u0432\u044b\u0441\u043e\u0442\u0435): 2 \/(2\/ratio) = ratio, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u0438 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0441\u043e\u043e\u0442\u043d\u043e\u0448\u0435\u043d\u0438\u0435\u043c \u0441\u0442\u043e\u0440\u043e\u043d \u0436\u0435\u043b\u0430\u0435\u043c\u043e\u0433\u043e \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f 300&#215;200;<\/p>\n<\/li>\n<li>\n<p>\u0426\u0438\u043a\u043b \u0441\u043e\u0441\u0442\u043e\u0438\u0442 \u0438\u0437 \u0440\u0430\u0437\u0434\u0435\u043b\u0435\u043d\u0438\u044f \u044d\u043a\u0440\u0430\u043d\u0430 \u043d\u0430 \u0442\u043e\u0447\u043a\u0438 \u0432 \u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f\u0445 <strong><em>x<\/em><\/strong> \u0438 <strong><em>y<\/em><\/strong>, \u0437\u0430\u0442\u0435\u043c \u0432\u044b\u0447\u0438\u0441\u043b\u044f\u0435\u0442\u0441\u044f \u0446\u0432\u0435\u0442 \u0442\u0435\u043a\u0443\u0449\u0435\u0433\u043e \u043f\u0438\u043a\u0441\u0435\u043b\u044f;<\/p>\n<\/li>\n<li>\n<p>\u041f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u044b\u0439 \u043a\u043e\u0434 \u0441\u043e\u0437\u0434\u0430\u0441\u0442 \u2014 \u043a\u0430\u043a \u0438 \u043e\u0436\u0438\u0434\u0430\u043b\u043e\u0441\u044c \u043d\u0430 \u0434\u0430\u043d\u043d\u043e\u043c \u044d\u0442\u0430\u043f\u0435 \u2014 \u0447\u0435\u0440\u043d\u043e\u0435 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435.&nbsp;<\/p>\n<\/li>\n<\/ul>\n<h3>\u041f\u0435\u0440\u0435\u0441\u0435\u0447\u0435\u043d\u0438\u0435 \u043b\u0443\u0447\u0435\u0439<\/h3>\n<p>\u0421\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u0448\u0430\u0433 \u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c\u0430: <em>\u0435\u0441\u043b\u0438 \u043b\u0443\u0447 (\u043b\u0438\u043d\u0438\u044f), \u043d\u0430\u0447\u0438\u043d\u0430\u044e\u0449\u0438\u0439\u0441\u044f \u043e\u0442 <\/em><strong><em>\u043a\u0430\u043c\u0435\u0440\u044b<\/em><\/strong><em> \u0438 \u043f\u0440\u043e\u0445\u043e\u0434\u044f\u0449\u0438\u0439 \u043a \u0442\u043e\u0447\u043a\u0435 <\/em><strong><em>p<\/em><\/strong><em>, \u043f\u0435\u0440\u0435\u0441\u0435\u043a\u0430\u0435\u0442 \u043e\u0431\u044a\u0435\u043a\u0442 \u0441\u0446\u0435\u043d\u044b, \u0442\u043e\u0433\u0434\u0430&#8230;<\/em><\/p>\n<p>\u0420\u0430\u0437\u043e\u0431\u044c\u0435\u043c \u0435\u0433\u043e \u043d\u0430 \u0434\u0432\u0435 \u0447\u0430\u0441\u0442\u0438. \u0418 \u043d\u0430\u0447\u043d\u0435\u043c \u0441 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u044f \u0442\u043e\u0433\u043e, \u043a\u0430\u043a\u043e\u0439 \u043b\u0443\u0447 (\u043b\u0438\u043d\u0438\u044f) \u043d\u0430\u0447\u0438\u043d\u0430\u0435\u0442\u0441\u044f \u043e\u0442 <strong><em>\u043a\u0430\u043c\u0435\u0440\u044b<\/em><\/strong> \u0438 \u0438\u0434\u0435\u0442 \u043a \u0442\u043e\u0447\u043a\u0435 <strong><em>p<\/em><\/strong>?<\/p>\n<h3>\u041e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u0435 \u043b\u0443\u0447\u0430<\/h3>\n<p>\u041a\u043e\u0433\u0434\u0430 \u043c\u044b \u0433\u043e\u0432\u043e\u0440\u0438\u043c \u00ab<em>\u043b\u0443\u0447<\/em>\u00bb, \u043d\u0430 \u0441\u0430\u043c\u043e\u043c \u0434\u0435\u043b\u0435 \u043c\u044b \u0438\u043c\u0435\u0435\u043c \u0432 \u0432\u0438\u0434\u0443 \u0441\u043a\u043e\u0440\u0435\u0435 \u00ab<em>\u043b\u0438\u043d\u0438\u044e<\/em>\u00bb. \u0412\u0441\u044f\u043a\u0438\u0439 \u0440\u0430\u0437 \u043f\u0440\u0438 \u0440\u0430\u0431\u043e\u0442\u0435 \u0441 \u0433\u0435\u043e\u043c\u0435\u0442\u0440\u0438\u0435\u0439 \u043b\u0443\u0447\u0448\u0435 \u043e\u0442\u0434\u0430\u0442\u044c \u043f\u0440\u0435\u0434\u043f\u043e\u0447\u0442\u0435\u043d\u0438\u0435 \u0432\u0435\u043a\u0442\u043e\u0440\u0430\u043c, \u0447\u0435\u043c \u0440\u0435\u0430\u043b\u044c\u043d\u044b\u043c \u043b\u0438\u043d\u0435\u0439\u043d\u044b\u043c \u0443\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u044f\u043c: \u0441 \u043d\u0438\u043c\u0438 \u043b\u0435\u0433\u0447\u0435 \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c, \u0438 \u043e\u043d\u0438 \u0433\u043e\u0440\u0430\u0437\u0434\u043e \u043c\u0435\u043d\u0435\u0435 \u043f\u043e\u0434\u0432\u0435\u0440\u0436\u0435\u043d\u044b \u043e\u0448\u0438\u0431\u043a\u0430\u043c, \u0442\u0430\u043a\u0438\u043c \u043a\u0430\u043a \u0434\u0435\u043b\u0435\u043d\u0438\u0435 \u043d\u0430 \u043d\u043e\u043b\u044c.<\/p>\n<p>\u0418\u0442\u0430\u043a, \u043f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u043b\u0443\u0447 \u043d\u0430\u0447\u0438\u043d\u0430\u0435\u0442\u0441\u044f \u043e\u0442 <strong><em>\u043a\u0430\u043c\u0435\u0440\u044b<\/em><\/strong> \u0438 \u0438\u0434\u0435\u0442 \u0432 \u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0438 \u0442\u0435\u043a\u0443\u0449\u0435\u0433\u043e \u0446\u0435\u043b\u0435\u0432\u043e\u0433\u043e <strong><em>\u043f\u0438\u043a\u0441\u0435\u043b\u044f<\/em><\/strong>, \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u0442\u044c \u0435\u0434\u0438\u043d\u0438\u0447\u043d\u044b\u0439 \u0432\u0435\u043a\u0442\u043e\u0440, \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u044e\u0449\u0438\u0439 \u0432 \u0442\u043e\u043c \u0436\u0435 \u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0438. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u043c\u044b \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u043c \u043d\u0430\u0448 \u043b\u0443\u0447 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u0443\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u0435\u043c:<\/p>\n<figure class=\"full-width\"><figcaption><\/figcaption><\/figure>\n<p>\u041f\u043e\u043c\u043d\u0438\u0442\u0435, \u0447\u0442\u043e <strong><em>\u043a\u0430\u043c\u0435\u0440\u0430<\/em><\/strong> \u0438 <strong><em>\u043f\u0438\u043a\u0441\u0435\u043b\u044c<\/em><\/strong> \u2014 \u044d\u0442\u043e 3D-\u0442\u043e\u0447\u043a\u0438. \u041f\u0440\u0438 t = 0 \u0432\u044b \u043e\u043a\u0430\u0436\u0435\u0442\u0435\u0441\u044c \u0432 \u043f\u043e\u043b\u043e\u0436\u0435\u043d\u0438\u0438 <strong><em>\u043a\u0430\u043c\u0435\u0440\u044b<\/em><\/strong>, \u043d\u043e \u0441 \u0443\u0432\u0435\u043b\u0438\u0447\u0435\u043d\u0438\u0435\u043c t \u0431\u0443\u0434\u0435\u0442\u0435 \u0443\u0434\u0430\u043b\u044f\u0442\u044c\u0441\u044f \u043e\u0442 \u043d\u0435\u0435 \u0432 \u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0438 <strong><em>\u043f\u0438\u043a\u0441\u0435\u043b\u044f<\/em><\/strong>. \u042d\u0442\u043e \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0438\u0447\u0435\u0441\u043a\u043e\u0435 \u0443\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u0435, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u0434\u0430\u0441\u0442 <strong><em>\u0442\u043e\u0447\u043a\u0443<\/em><\/strong> \u0432\u0434\u043e\u043b\u044c \u043b\u0438\u043d\u0438\u0438 \u0434\u043b\u044f \u043b\u044e\u0431\u043e\u0433\u043e t.<\/p>\n<p>\u041a\u043e\u043d\u0435\u0447\u043d\u043e, \u0442\u043e\u0447\u043d\u043e \u0442\u0430\u043a \u0436\u0435 \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u043f\u0435\u0440\u0435\u043f\u0438\u0441\u0430\u0442\u044c \u0443\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u0435 \u0438 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u0442\u044c \u043b\u0443\u0447, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043d\u0430\u0447\u0438\u043d\u0430\u0435\u0442\u0441\u044f \u0432 \u0438\u0441\u0445\u043e\u0434\u043d\u043e\u0439 \u0442\u043e\u0447\u043a\u0435 (O) \u0438 \u0438\u0434\u0435\u0442 \u043a \u043c\u0435\u0441\u0442\u0443 \u043d\u0430\u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f (D) \u043a\u0430\u043a:<\/p>\n<figure class=\"\"><figcaption><\/figcaption><\/figure>\n<p>\u0414\u043b\u044f \u0443\u0434\u043e\u0431\u0441\u0442\u0432\u0430 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u043c <strong><em>d<\/em><\/strong> \u043a\u0430\u043a \u0432\u0435\u043a\u0442\u043e\u0440 <strong><em>\u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f<\/em><\/strong>.<\/p>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043a \u043d\u0430\u0448\u0435\u043c\u0443 \u043a\u043e\u0434\u0443 \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u0435 \u043b\u0443\u0447\u0430:<\/p>\n<details class=\"spoiler\">\n<summary>\u041f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u043a\u043e\u0434<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"python\">import numpy as np import matplotlib.pyplot as plt def normalize(vector):     return vector \/ np.linalg.norm(vector) width = 300 height = 200 camera = np.array([0, 0, 1]) ratio = float(width) \/ height screen = (-1, 1 \/ ratio, 1, -1 \/ ratio) # \u0441\u043b\u0435\u0432\u0430, \u0441\u0432\u0435\u0440\u0445\u0443, \u0441\u043f\u0440\u0430\u0432\u0430, \u0441\u043d\u0438\u0437\u0443 image = np.zeros((height, width, 3)) for i, y in enumerate(np.linspace(screen[1], screen[3], height)):     for j, x in enumerate(np.linspace(screen[0], screen[2], width)):         pixel = np.array([x, y, 0])         origin = camera         direction = normalize(pixel - origin)         # image[i, j] = ...     print(\"progress: %d\/%d\" % (i + 1, height)) plt.imsave('image.png', image)<\/code><\/pre>\n<\/div>\n<\/details>\n<ul>\n<li>\n<p>\u041c\u044b \u0434\u043e\u0431\u0430\u0432\u0438\u043b\u0438 \u0432 \u043a\u043e\u0434 \u0444\u0443\u043d\u043a\u0446\u0438\u044e normalize(vector), \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442&#8230; \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u043e, \u043d\u043e\u0440\u043c\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u0432\u0435\u043a\u0442\u043e\u0440;<\/p>\n<\/li>\n<li>\n<p>\u0422\u0430\u043a\u0436\u0435 \u043c\u044b \u0434\u043e\u0431\u0430\u0432\u0438\u043b\u0438 \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u0435 \u0438\u0441\u0445\u043e\u0434\u043d\u043e\u0439 \u0442\u043e\u0447\u043a\u0438 \u0438 \u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0432\u043c\u0435\u0441\u0442\u0435 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u044e\u0442 \u043b\u0443\u0447. \u041e\u0431\u0440\u0430\u0442\u0438\u0442\u0435 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435, \u0447\u0442\u043e <strong><em>\u043f\u0438\u043a\u0441\u0435\u043b\u044c<\/em><\/strong> \u0438\u043c\u0435\u0435\u0442 \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u0443 z = 0, \u043f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u043e\u043d \u043b\u0435\u0436\u0438\u0442 \u043d\u0430 \u044d\u043a\u0440\u0430\u043d\u0435, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u0432 \u043f\u043b\u043e\u0441\u043a\u043e\u0441\u0442\u0438, \u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u043d\u043e\u0439 \u043e\u0441\u044f\u043c\u0438 <strong><em>x<\/em><\/strong> \u0438 <strong><em>y<\/em><\/strong>;<\/p>\n<\/li>\n<\/ul>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043f\u0435\u0440\u0435\u0439\u0434\u0435\u043c \u043a\u043e \u0432\u0442\u043e\u0440\u043e\u0439 \u0447\u0430\u0441\u0442\u0438, \u0433\u0434\u0435 \u043b\u0443\u0447 \u043f\u0435\u0440\u0435\u0441\u0435\u043a\u0430\u0435\u0442 \u043e\u0431\u044a\u0435\u043a\u0442 \u0441\u0446\u0435\u043d\u044b.  \u0414\u043b\u044f \u043f\u0440\u043e\u0441\u0442\u043e\u0442\u044b \u0431\u0443\u0434\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u0441\u0444\u0435\u0440\u044b.<\/p>\n<h3>\u041e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u0435 \u0441\u0444\u0435\u0440\u044b<\/h3>\n<p>\u0421\u0444\u0435\u0440\u0430 \u2014 \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u043f\u0440\u043e\u0441\u0442\u043e\u0439 \u043c\u0430\u0442\u0435\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u043e\u0431\u044a\u0435\u043a\u0442. \u041e\u043d\u0430 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u0442\u0441\u044f \u043a\u0430\u043a <em>\u043d\u0430\u0431\u043e\u0440 \u0442\u043e\u0447\u0435\u043a, \u043d\u0430\u0445\u043e\u0434\u044f\u0449\u0438\u0445\u0441\u044f \u043d\u0430 \u043e\u0434\u0438\u043d\u0430\u043a\u043e\u0432\u043e\u043c \u0440\u0430\u0441\u0441\u0442\u043e\u044f\u043d\u0438\u0438 r (\u0440\u0430\u0434\u0438\u0443\u0441) \u043e\u0442 \u0437\u0430\u0434\u0430\u043d\u043d\u043e\u0439 \u0442\u043e\u0447\u043a\u0438 (\u0446\u0435\u043d\u0442\u0440\u0430)<\/em>.<\/p>\n<p>\u0421\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e, \u0441 \u0443\u0447\u0435\u0442\u043e\u043c \u0446\u0435\u043d\u0442\u0440\u0430 <strong><em>C<\/em><\/strong> \u0441\u0444\u0435\u0440\u044b \u0438 \u0435\u0435 \u0440\u0430\u0434\u0438\u0443\u0441\u0430 <strong><em>r<\/em><\/strong> \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u043b\u044c\u043d\u0430\u044f \u0442\u043e\u0447\u043a\u0430 <strong><em>X<\/em><\/strong> \u043b\u0435\u0436\u0438\u0442 \u043d\u0430 \u0441\u0444\u0435\u0440\u0435 \u0442\u043e\u0433\u0434\u0430, \u043a\u043e\u0433\u0434\u0430:<\/p>\n<figure class=\"\"><figcaption><\/figcaption><\/figure>\n<p>\u0414\u043b\u044f \u0443\u0434\u043e\u0431\u0441\u0442\u0432\u0430 \u0432\u043e\u0437\u0432\u0435\u0434\u0435\u043c \u043e\u0431\u0435 \u0441\u0442\u043e\u0440\u043e\u043d\u044b \u0432 \u043a\u0432\u0430\u0434\u0440\u0430\u0442, \u0447\u0442\u043e\u0431\u044b \u0438\u0437\u0431\u0430\u0432\u0438\u0442\u044c\u0441\u044f \u043e\u0442 \u043a\u0432\u0430\u0434\u0440\u0430\u0442\u043d\u043e\u0433\u043e \u043a\u043e\u0440\u043d\u044f, \u043e\u0431\u0443\u0441\u043b\u043e\u0432\u043b\u0435\u043d\u043d\u043e\u0433\u043e \u0432\u0435\u043b\u0438\u0447\u0438\u043d\u043e\u0439 X \u2014 C:<\/p>\n<figure class=\"\"><figcaption><\/figcaption><\/figure>\n<p>\u041f\u043e\u0441\u043b\u0435 \u044d\u0442\u043e\u0433\u043e \u043c\u044b \u0441\u043c\u043e\u0436\u0435\u043c \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u0442\u044c \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0441\u0444\u0435\u0440\u044b \u0441\u0440\u0430\u0437\u0443 \u043f\u043e\u0441\u043b\u0435 \u043e\u0431\u044a\u044f\u0432\u043b\u0435\u043d\u0438\u044f \u044d\u043a\u0440\u0430\u043d\u0430:<\/p>\n<pre><code class=\"python\">objects = [    { 'center': np.array([-0.2, 0, -1]), 'radius': 0.7 },    { 'center': np.array([0.1, -0.3, 0]), 'radius': 0.1 },    { 'center': np.array([-0.3, 0, 0]), 'radius': 0.15 } ]<\/code><\/pre>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u0432\u044b\u0447\u0438\u0441\u043b\u0438\u043c \u043f\u0435\u0440\u0435\u0441\u0435\u0447\u0435\u043d\u0438\u0435 \u043b\u0443\u0447\u0430 \u0438 \u0441\u0444\u0435\u0440\u044b.<\/p>\n<h3>\u041f\u0435\u0440\u0435\u0441\u0435\u0447\u0435\u043d\u0438\u0435 \u0441\u043e \u0441\u0444\u0435\u0440\u043e\u0439<\/h3>\n<p>\u041c\u044b \u0437\u043d\u0430\u0435\u043c \u0443\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u0435 \u043b\u0443\u0447\u0435\u0439 \u0438 \u0437\u043d\u0430\u0435\u043c, \u043a\u0430\u043a\u043e\u043c\u0443 \u0443\u0441\u043b\u043e\u0432\u0438\u044e \u0434\u043e\u043b\u0436\u043d\u0430 \u0443\u0434\u043e\u0432\u043b\u0435\u0442\u0432\u043e\u0440\u044f\u0442\u044c \u0442\u043e\u0447\u043a\u0430, \u0447\u0442\u043e\u0431\u044b \u043e\u043d\u0430 \u043b\u0435\u0436\u0430\u043b\u0430 \u043d\u0430 \u0441\u0444\u0435\u0440\u0435. \u0412\u0441\u0435, \u0447\u0442\u043e \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c, \u044d\u0442\u043e \u043f\u043e\u0434\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u043e\u0434\u043d\u043e \u0443\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u0435 \u0432 \u0434\u0440\u0443\u0433\u043e\u0435 \u0438 \u0440\u0435\u0448\u0438\u0442\u044c \u0435\u0433\u043e \u043e\u0442\u043d\u043e\u0441\u0438\u0442\u0435\u043b\u044c\u043d\u043e t. \u0422\u043e \u0435\u0441\u0442\u044c, \u043d\u0430\u0439\u0442\u0438 \u043e\u0442\u0432\u0435\u0442 \u043d\u0430 \u0432\u043e\u043f\u0440\u043e\u0441: <em>\u0434\u043b\u044f \u043a\u0430\u043a\u043e\u0433\u043e t \u0442\u043e\u0447\u043a\u0430 \u043b\u0443\u0447\u0430 ray(t) \u043e\u043a\u0430\u0436\u0435\u0442\u0441\u044f \u043d\u0430 \u0441\u0444\u0435\u0440\u0435<\/em>?<\/p>\n<figure class=\"full-width\"><figcaption><\/figcaption><\/figure>\n<p>\u042d\u0442\u043e \u043e\u0431\u044b\u0447\u043d\u043e\u0435 \u043a\u0432\u0430\u0434\u0440\u0430\u0442\u043d\u043e\u0435 \u0443\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u0435, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u043f\u0440\u043e\u0441\u0442\u043e \u0440\u0435\u0448\u0430\u0435\u0442\u0441\u044f \u043e\u0442\u043d\u043e\u0441\u0438\u0442\u0435\u043b\u044c\u043d\u043e t. \u041c\u044b \u0431\u0443\u0434\u0435\u043c \u0432\u044b\u0437\u044b\u0432\u0430\u0442\u044c \u043a\u043e\u044d\u0444\u0444\u0438\u0446\u0438\u0435\u043d\u0442\u044b, \u0441\u0432\u044f\u0437\u0430\u043d\u043d\u044b\u0435 \u0441 t\u00b2, t\u00b9, t\u2070, <strong><em>a<\/em><\/strong>, <strong><em>b<\/em><\/strong> \u0438 <strong><em>c<\/em><\/strong>, \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0435\u043d\u043d\u043e. \u0412\u044b\u0447\u0438\u0441\u043b\u0438\u043c \u0434\u0438\u0441\u043a\u0440\u0438\u043c\u0438\u043d\u0430\u043d\u0442 \u044d\u0442\u043e\u0433\u043e \u0443\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u044f:<\/p>\n<figure class=\"\"><figcaption><\/figcaption><\/figure>\n<p>\u041f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435 <strong><em>d<\/em><\/strong> \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0435\u0434\u0438\u043d\u0438\u0447\u043d\u044b\u043c \u0432\u0435\u043a\u0442\u043e\u0440\u043e\u043c, \u043f\u043e\u043b\u0443\u0447\u0438\u043c <strong><em>a<\/em><\/strong> = 1. \u041f\u043e\u0441\u043b\u0435 \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u044f \u0434\u0438\u0441\u043a\u0440\u0438\u043c\u0438\u043d\u0430\u043d\u0442\u0430 \u0443 \u043d\u0430\u0441 \u0435\u0441\u0442\u044c \u0442\u0440\u0438 \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u0430:<\/p>\n<figure class=\"full-width\"><figcaption>\u0420\u0438\u0441\u0443\u043d\u043e\u043a 5<\/figcaption><\/figure>\n<p>\u0414\u043b\u044f \u043e\u0431\u043d\u0430\u0440\u0443\u0436\u0435\u043d\u0438\u044f \u043f\u0435\u0440\u0435\u0441\u0435\u0447\u0435\u043d\u0438\u0439 \u0431\u0443\u0434\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e <strong>\u0442\u0440\u0435\u0442\u0438\u0439<\/strong> \u0441\u043b\u0443\u0447\u0430\u0439. \u0417\u0430\u043f\u0438\u0448\u0435\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u044e, \u043e\u0442\u0432\u0435\u0447\u0430\u044e\u0449\u0443\u044e \u0437\u0430 \u043e\u0431\u043d\u0430\u0440\u0443\u0436\u0435\u043d\u0438\u0435 \u043f\u0435\u0440\u0435\u0441\u0435\u0447\u0435\u043d\u0438\u044f \u043b\u0443\u0447\u0430 \u0438 \u0441\u0444\u0435\u0440\u044b. \u041e\u043d\u0430 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u0440\u0430\u0441\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u043e\u0442 <strong><em>\u043d\u0430\u0447\u0430\u043b\u0430 \u043b\u0443\u0447\u0430<\/em><\/strong> \u0434\u043e <strong><em>\u0431\u043b\u0438\u0436\u0430\u0439\u0448\u0435\u0439 \u0442\u043e\u0447\u043a\u0438 \u043f\u0435\u0440\u0435\u0441\u0435\u0447\u0435\u043d\u0438\u044f<\/em><\/strong>, \u0435\u0441\u043b\u0438 \u043b\u0443\u0447 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u043f\u0435\u0440\u0435\u0441\u0435\u043a\u0430\u0435\u0442 \u0441\u0444\u0435\u0440\u0443, \u0438\u043d\u0430\u0447\u0435 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 None:<\/p>\n<details class=\"spoiler\">\n<summary>\u041f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u043a\u043e\u0434<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"python\">def sphere_intersect(center, radius, ray_origin, ray_direction):    b = 2 * np.dot(ray_direction, ray_origin \u2014 center)    c = np.linalg.norm(ray_origin \u2014 center) ** 2 \u2014 radius ** 2    delta = b ** 2 \u2014 4 * c    if delta &gt; 0:        t1 = (-b + np.sqrt(delta)) \/ 2        t2 = (-b \u2014 np.sqrt(delta)) \/ 2        if t1 &gt; 0 and t2 &gt; 0:            return min(t1, t2)    return None<\/code><\/pre>\n<\/div>\n<\/details>\n<p>\u041e\u0431\u0440\u0430\u0442\u0438\u0442\u0435 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435, \u0447\u0442\u043e \u043c\u044b \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c \u0442\u043e\u043b\u044c\u043a\u043e <strong>\u0431\u043b\u0438\u0436\u0430\u0439\u0448\u0435\u0435<\/strong> \u043f\u0435\u0440\u0435\u0441\u0435\u0447\u0435\u043d\u0438\u0435 \u0438\u0437 \u0434\u0432\u0443\u0445 \u0442\u043e\u0433\u0434\u0430, \u043a\u043e\u0433\u0434\u0430 \u043e\u0431\u0430 t1 \u0438 t2 \u043f\u043e\u043b\u043e\u0436\u0438\u0442\u0435\u043b\u044c\u043d\u044b. \u042d\u0442\u043e \u0441\u0432\u044f\u0437\u0430\u043d\u043e \u0441 \u0442\u0435\u043c, \u0447\u0442\u043e \u043e\u0442\u0432\u0435\u0442 \u0443\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u044f \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u043e\u0442\u0440\u0438\u0446\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u043c, \u0438 \u0432 \u0442\u0430\u043a\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u043b\u0443\u0447, \u043f\u0435\u0440\u0435\u0441\u0435\u043a\u0430\u044e\u0449\u0438\u0439 \u0441\u0444\u0435\u0440\u0443, \u0431\u0443\u0434\u0435\u0442 \u0438\u043c\u0435\u0442\u044c \u043d\u0435 <strong><em>d<\/em><\/strong> \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0432\u0435\u043a\u0442\u043e\u0440\u0430 \u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f, \u0430 &#8212;<strong><em>d<\/em><\/strong> (\u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0435\u0441\u043b\u0438 \u0441\u0444\u0435\u0440\u0430 \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u0437\u0430 \u043a\u0430\u043c\u0435\u0440\u043e\u0439 \u0438 \u044d\u043a\u0440\u0430\u043d\u043e\u043c).<\/p>\n<h3>\u0411\u043b\u0438\u0436\u0430\u0439\u0448\u0438\u0439 \u043f\u0435\u0440\u0435\u0441\u0435\u043a\u0430\u0435\u043c\u044b\u0439 \u043e\u0431\u044a\u0435\u043a\u0442<\/h3>\n<p>\u041f\u043e\u043a\u0430 \u043c\u044b \u0432\u0441\u0435 \u0435\u0449\u0435 \u043d\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u043b\u0438 \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u044e \u0438\u0437 \u043f\u0441\u0435\u0432\u0434\u043e\u043a\u043e\u0434\u0430: <em>\u0435\u0441\u043b\u0438 \u043b\u0443\u0447 (\u043b\u0438\u043d\u0438\u044f), \u043d\u0430\u0447\u0438\u043d\u0430\u044e\u0449\u0438\u0439\u0441\u044f \u043e\u0442 <\/em><strong><em>\u043a\u0430\u043c\u0435\u0440\u044b<\/em><\/strong><em> \u0438 \u0438\u0434\u0443\u0449\u0438\u0439 \u043a \u0442\u043e\u0447\u043a\u0435 <\/em><strong><em>p<\/em><\/strong><em>, \u043f\u0435\u0440\u0435\u0441\u0435\u043a\u0430\u0435\u0442 \u043b\u044e\u0431\u043e\u0439 \u043e\u0431\u044a\u0435\u043a\u0442 \u0441\u0446\u0435\u043d\u044b, \u0442\u043e [&#8230;]<\/em>. \u0422\u0435\u043f\u0435\u0440\u044c \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u0432\u044b\u0447\u0438\u0441\u043b\u0438\u0442\u044c <strong><em>\u0442\u043e\u0447\u043a\u0443 \u043f\u0435\u0440\u0435\u0441\u0435\u0447\u0435\u043d\u0438\u044f<\/em><\/strong> \u0441 \u0431\u043b\u0438\u0436\u0430\u0439\u0448\u0438\u043c \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u043c.<\/p>\n<p>\u041d\u0430\u043f\u0438\u0448\u0435\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u044e, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 sphere_intersect() \u0434\u043b\u044f \u043f\u043e\u0438\u0441\u043a\u0430 \u0431\u043b\u0438\u0436\u0430\u0439\u0448\u0435\u0433\u043e<\/p>\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-319334","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/319334","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=319334"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/319334\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=319334"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=319334"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=319334"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}