{"id":314338,"date":"2020-12-04T15:02:57","date_gmt":"2020-12-04T15:02:57","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=314338"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=314338","title":{"rendered":"\u041f\u0438\u0448\u0435\u043c \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0443 3D-\u043c\u043e\u0434\u0435\u043b\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0432 500 \u0441\u0442\u0440\u043e\u043a\u0430\u0445 \u043a\u043e\u0434\u0430"},"content":{"rendered":"\n<div class=\"post__text post__text-html post__text_v1\" id=\"post-content-body\">\n<div style=\"text-align:center;\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/post_images\/1b6\/d49\/be0\/1b6d49be070fb475dde98d84f4263c95.png\" alt=\"image\"><\/div>\n<p>  <\/p>\n<h2>\u0412\u0432\u0435\u0434\u0435\u043d\u0438\u0435<\/h2>\n<p>  \u041b\u044e\u0434\u0438 \u043e\u0442 \u043f\u0440\u0438\u0440\u043e\u0434\u044b \u043a\u0440\u0435\u0430\u0442\u0438\u0432\u043d\u044b. \u041c\u044b \u043f\u043e\u0441\u0442\u043e\u044f\u043d\u043d\u043e \u043f\u0440\u043e\u0435\u043a\u0442\u0438\u0440\u0443\u0435\u043c \u0438 \u0441\u043e\u0437\u0434\u0430\u0451\u043c \u043d\u043e\u0432\u044b\u0435, \u043f\u043e\u043b\u0435\u0437\u043d\u044b\u0435 \u0438 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u044b\u0435 \u0432\u0435\u0449\u0438. \u0421\u0435\u0433\u043e\u0434\u043d\u044f \u043c\u044b \u043f\u0438\u0448\u0435\u043c \u041f\u041e, \u043f\u043e\u043c\u043e\u0433\u0430\u044e\u0449\u0435\u0435 \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u0443 \u043f\u0440\u043e\u0435\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0438 \u0442\u0432\u043e\u0440\u0447\u0435\u0441\u0442\u0432\u0430. \u041f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b \u0421\u0410\u041f\u0420 (Computer-aided design, CAD) \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u044e\u0442 \u0442\u0432\u043e\u0440\u0446\u0430\u043c \u043f\u0440\u043e\u0435\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0437\u0434\u0430\u043d\u0438\u044f, \u043c\u043e\u0441\u0442\u044b, \u0433\u0440\u0430\u0444\u0438\u043a\u0443 \u0432\u0438\u0434\u0435\u043e\u0438\u0433\u0440, \u0447\u0443\u0434\u043e\u0432\u0438\u0449 \u0434\u043b\u044f \u0444\u0438\u043b\u044c\u043c\u043e\u0432, \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432 \u0434\u043b\u044f 3D-\u043f\u0435\u0447\u0430\u0442\u0438 \u0438 \u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u043e \u0434\u0440\u0443\u0433\u0438\u0445 \u0432\u0435\u0449\u0435\u0439 \u043f\u0435\u0440\u0435\u0434 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435\u043c \u0444\u0438\u0437\u0438\u0447\u0435\u0441\u043a\u043e\u0439 \u0432\u0435\u0440\u0441\u0438\u0438 \u043f\u0440\u043e\u0435\u043a\u0442\u0430.<\/p>\n<p>  \u041f\u043e \u0441\u0432\u043e\u0435\u0439 \u0441\u0443\u0442\u0438, \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u044b CAD \u044f\u0432\u043b\u044f\u044e\u0442\u0441\u044f \u0441\u043f\u043e\u0441\u043e\u0431\u043e\u043c \u0430\u0431\u0441\u0442\u0440\u0430\u0433\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0442\u0440\u0451\u0445\u043c\u0435\u0440\u043d\u043e\u0433\u043e \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u0432 \u043d\u0435\u0447\u0442\u043e, \u0447\u0442\u043e \u043c\u043e\u0436\u043d\u043e \u043f\u0440\u043e\u0441\u043c\u0430\u0442\u0440\u0438\u0432\u0430\u0442\u044c \u0438 \u0440\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043d\u0430 \u0434\u0432\u0443\u0445\u043c\u0435\u0440\u043d\u043e\u043c \u044d\u043a\u0440\u0430\u043d\u0435. \u0427\u0442\u043e\u0431\u044b \u0441\u043f\u0440\u0430\u0432\u043b\u044f\u0442\u044c\u0441\u044f \u0441\u043e \u0441\u0432\u043e\u0435\u0439 \u0437\u0430\u0434\u0430\u0447\u0435\u0439, \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u044b CAD \u0434\u043e\u043b\u0436\u043d\u044b \u043e\u0431\u0435\u0441\u043f\u0435\u0447\u0438\u0432\u0430\u0442\u044c \u0442\u0440\u0438 \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u0445 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u043e\u0441\u0442\u0438. \u0412\u043e-\u043f\u0435\u0440\u0432\u044b\u0445, \u043e\u043d\u0438 \u0434\u043e\u043b\u0436\u043d\u044b \u0438\u043c\u0435\u0442\u044c \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443 \u0434\u0430\u043d\u043d\u044b\u0445, \u043e\u043f\u0438\u0441\u044b\u0432\u0430\u044e\u0449\u0443\u044e \u043f\u0440\u043e\u0435\u043a\u0442\u0438\u0440\u0443\u0435\u043c\u044b\u0439 \u043e\u0431\u044a\u0435\u043a\u0442: \u044d\u0442\u043e \u0442\u043e, \u043a\u0430\u043a \u043a\u043e\u043c\u043f\u044c\u044e\u0442\u0435\u0440 \u043f\u043e\u043d\u0438\u043c\u0430\u0435\u0442 \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0435\u043c\u044b\u0439 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u043c \u0442\u0440\u0451\u0445\u043c\u0435\u0440\u043d\u044b\u0439 \u043c\u0438\u0440. \u0412\u043e-\u0432\u0442\u043e\u0440\u044b\u0445, \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442 CAD \u0434\u043e\u043b\u0436\u0435\u043d \u043e\u0431\u0435\u0441\u043f\u0435\u0447\u0438\u0432\u0430\u0442\u044c \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u043d\u0430 \u044d\u043a\u0440\u0430\u043d\u0435 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f. \u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043f\u0440\u043e\u0435\u043a\u0442\u0438\u0440\u0443\u0435\u0442 \u0444\u0438\u0437\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u043e\u0431\u044a\u0435\u043a\u0442 \u0441 \u0442\u0440\u0435\u043c\u044f \u0438\u0437\u043c\u0435\u0440\u0435\u043d\u0438\u044f\u043c\u0438, \u043d\u043e \u044d\u043a\u0440\u0430\u043d \u043a\u043e\u043c\u043f\u044c\u044e\u0442\u0435\u0440\u0430 \u0438\u043c\u0435\u0435\u0442 \u0432\u0441\u0435\u0433\u043e \u0434\u0432\u0430 \u0438\u0437\u043c\u0435\u0440\u0435\u043d\u0438\u044f. \u0418\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442 CAD \u0434\u043e\u043b\u0436\u0435\u043d \u043c\u043e\u0434\u0435\u043b\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0441\u043f\u043e\u0441\u043e\u0431 \u0432\u043e\u0441\u043f\u0440\u0438\u044f\u0442\u0438\u044f \u043d\u0430\u043c\u0438 \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432 \u0438 \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u044b\u0432\u0430\u0442\u044c \u0438\u0445 \u043d\u0430 \u044d\u043a\u0440\u0430\u043d\u0435 \u0442\u0430\u043a, \u0447\u0442\u043e\u0431\u044b \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u0441\u043c\u043e\u0433 \u043f\u043e\u043d\u044f\u0442\u044c \u0432\u0441\u0435 \u0442\u0440\u0438 \u0438\u0437\u043c\u0435\u0440\u0435\u043d\u0438\u044f \u043e\u0431\u044a\u0435\u043a\u0442\u0430. \u0412-\u0442\u0440\u0435\u0442\u044c\u0438\u0445, CAD \u0434\u043e\u043b\u0436\u0435\u043d \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0442\u044c \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f \u0441 \u043f\u0440\u043e\u0435\u043a\u0442\u0438\u0440\u0443\u0435\u043c\u044b\u043c \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u043c. \u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u0434\u043e\u043b\u0436\u0435\u043d \u0431\u044b\u0442\u044c \u0441\u043f\u043e\u0441\u043e\u0431\u0435\u043d \u0434\u043e\u043f\u043e\u043b\u043d\u044f\u0442\u044c \u0438\u043b\u0438 \u043c\u043e\u0434\u0438\u0444\u0438\u0446\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043f\u0440\u043e\u0435\u043a\u0442, \u0447\u0442\u043e\u0431\u044b \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u043d\u0443\u0436\u043d\u044b\u0439 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442. \u041a\u0440\u043e\u043c\u0435 \u0442\u043e\u0433\u043e, \u0432\u0441\u0435 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u044b \u0434\u043e\u043b\u0436\u043d\u044b \u0438\u043c\u0435\u0442\u044c \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u0438 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u043f\u0440\u043e\u0435\u043a\u0442\u043e\u0432 \u0441 \u0434\u0438\u0441\u043a\u0430, \u0447\u0442\u043e\u0431\u044b \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0438 \u043c\u043e\u0433\u043b\u0438 \u0441\u043e\u0442\u0440\u0443\u0434\u043d\u0438\u0447\u0430\u0442\u044c, \u043e\u0431\u043c\u0435\u043d\u0438\u0432\u0430\u0442\u044c\u0441\u044f \u0441\u0432\u043e\u0435\u0439 \u0440\u0430\u0431\u043e\u0442\u043e\u0439 \u0438 \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0442\u044c \u0435\u0451.<br \/>  <a name=\"habracut\"><\/a><br \/>  \u0421\u043f\u0435\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u044b CAD \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u044e\u0442 \u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u043e \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0445 \u0444\u0443\u043d\u043a\u0446\u0438\u0439, \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0445 \u0442\u0440\u0435\u0431\u043e\u0432\u0430\u043d\u0438\u044f\u043c \u0441\u0432\u043e\u0435\u0439 \u043e\u0431\u043b\u0430\u0441\u0442\u0438. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0432 \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u043d\u043e\u043c CAD \u0435\u0441\u0442\u044c \u0441\u0438\u043c\u0443\u043b\u044f\u0446\u0438\u0438 \u0444\u0438\u0437\u0438\u043a\u0438 \u0434\u043b\u044f \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u043a\u043b\u0438\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0445 \u043d\u0430\u0433\u0440\u0443\u0437\u043e\u043a \u043d\u0430 \u0437\u0434\u0430\u043d\u0438\u0435, \u0432 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0435 \u0434\u043b\u044f 3D-\u043f\u0435\u0447\u0430\u0442\u0438 \u0431\u0443\u0434\u0443\u0442 \u043f\u0440\u0438\u0441\u0443\u0442\u0441\u0442\u0432\u043e\u0432\u0430\u0442\u044c \u0444\u0443\u043d\u043a\u0446\u0438\u0438, \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u044e\u0449\u0438\u0435 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u043f\u0435\u0447\u0430\u0442\u0438 \u043e\u0431\u044a\u0435\u043a\u0442\u0430, \u0430 \u043f\u0430\u043a\u0435\u0442 \u0434\u043b\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u043a\u0438\u043d\u0435\u043c\u0430\u0442\u043e\u0433\u0440\u0430\u0444\u0438\u0447\u0435\u0441\u043a\u0438\u0445 \u0441\u043f\u0435\u0446\u044d\u0444\u0444\u0435\u043a\u0442\u043e\u0432 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0442\u043e\u0447\u043d\u043e\u0439 \u0441\u0438\u043c\u0443\u043b\u044f\u0446\u0438\u0438 \u043f\u0438\u0440\u043e\u043a\u0438\u043d\u0435\u0442\u0438\u043a\u0438.<\/p>\n<p>  \u041e\u0434\u043d\u0430\u043a\u043e \u0432\u043e \u0432\u0441\u0435\u0445 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u0430\u0445 CAD \u0434\u043e\u043b\u0436\u043d\u044b \u043f\u0440\u0438\u0441\u0443\u0442\u0441\u0442\u0432\u043e\u0432\u0430\u0442\u044c \u043f\u043e \u043a\u0440\u0430\u0439\u043d\u0435\u0439 \u043c\u0435\u0440\u0435 \u0442\u0440\u0438 \u043e\u043f\u0438\u0441\u0430\u043d\u043d\u044b\u0445 \u0432\u044b\u0448\u0435 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430: \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 \u0434\u0430\u043d\u043d\u044b\u0445, \u043e\u043f\u0438\u0441\u044b\u0432\u0430\u044e\u0449\u0430\u044f \u043f\u0440\u043e\u0435\u043a\u0442, \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u043d\u0430 \u044d\u043a\u0440\u0430\u043d\u0435 \u0438 \u0441\u043f\u043e\u0441\u043e\u0431 \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f \u0441 \u043f\u0440\u043e\u0435\u043a\u0442\u043e\u043c.<\/p>\n<p>  \u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u0442\u0435\u043f\u0435\u0440\u044c \u0443\u0437\u043d\u0430\u0435\u043c, \u043a\u0430\u043a \u043c\u043e\u0436\u043d\u043e \u043e\u043f\u0438\u0441\u0430\u0442\u044c 3D-\u043f\u0440\u043e\u0435\u043a\u0442, \u043e\u0442\u043e\u0431\u0440\u0430\u0437\u0438\u0442\u044c \u0435\u0433\u043e \u043d\u0430 \u044d\u043a\u0440\u0430\u043d\u0435 \u0438 \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u043e\u0432\u0430\u0442\u044c \u0441 \u043d\u0438\u043c \u0432\u0441\u0435\u0433\u043e \u0432 500 \u0441\u0442\u0440\u043e\u043a\u0430\u0445 \u043d\u0430 Python.<\/p>\n<h2>\u0420\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433 \u043a\u0430\u043a \u043e\u0440\u0438\u0435\u043d\u0442\u0438\u0440<\/h2>\n<p>  \u0414\u0432\u0438\u0436\u0443\u0449\u0435\u0439 \u0441\u0438\u043b\u043e\u0439 \u043c\u043d\u043e\u0433\u0438\u0445 \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u043d\u044b\u0445 \u0440\u0435\u0448\u0435\u043d\u0438\u0439 3D-\u0440\u0435\u0434\u0430\u043a\u0442\u043e\u0440\u0430 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043f\u0440\u043e\u0446\u0435\u0441\u0441 \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433\u0430. \u041d\u0430\u043c \u043d\u0443\u0436\u043d\u0430 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u0438 \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433\u0430 \u0432 \u043f\u0440\u043e\u0435\u043a\u0442\u0435 \u0441\u043b\u043e\u0436\u043d\u044b\u0445 \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432, \u043d\u043e \u0432 \u0442\u043e \u0436\u0435 \u0432\u0440\u0435\u043c\u044f \u043c\u044b \u0445\u043e\u0442\u0438\u043c \u043e\u0431\u0435\u0441\u043f\u0435\u0447\u0438\u0442\u044c \u043d\u0438\u0437\u043a\u0443\u044e \u0441\u043b\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u043a\u043e\u0434\u0430 \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433\u0430. \u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u0438\u0437\u0443\u0447\u0438\u043c \u043f\u0440\u043e\u0446\u0435\u0441\u0441 \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433\u0430 \u0438 \u0438\u0441\u0441\u043b\u0435\u0434\u0443\u0435\u043c \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443 \u0434\u0430\u043d\u043d\u044b\u0445 \u0434\u043b\u044f \u043f\u0440\u043e\u0435\u043a\u0442\u0430, \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u044e\u0449\u0443\u044e \u043d\u0430\u043c \u0445\u0440\u0430\u043d\u0438\u0442\u044c \u0438 \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u044b\u0432\u0430\u0442\u044c \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u043b\u044c\u043d\u044b\u0435 \u0441\u043b\u043e\u0436\u043d\u044b\u0435 \u043e\u0431\u044a\u0435\u043a\u0442\u044b \u043f\u0440\u0438 \u043f\u043e\u043c\u043e\u0449\u0438 \u043f\u0440\u043e\u0441\u0442\u043e\u0439 \u043b\u043e\u0433\u0438\u043a\u0438 \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433\u0430.<\/p>\n<h3>\u0423\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430\u043c\u0438 \u0438 \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u043c \u0446\u0438\u043a\u043b\u043e\u043c<\/h3>\n<p>  \u041f\u0440\u0435\u0436\u0434\u0435 \u0447\u0435\u043c \u043c\u044b \u043f\u0440\u0438\u0441\u0442\u0443\u043f\u0438\u043c \u043a \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433\u0443, \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u043f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u0438\u0442\u044c \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0430\u0441\u043f\u0435\u043a\u0442\u044b. \u0412\u043e-\u043f\u0435\u0440\u0432\u044b\u0445, \u043d\u0430\u043c \u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u043e\u043a\u043d\u043e \u0434\u043b\u044f \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u043f\u0440\u043e\u0435\u043a\u0442\u0430. \u0412\u043e-\u0432\u0442\u043e\u0440\u044b\u0445, \u043c\u044b \u0445\u043e\u0442\u0438\u043c \u043e\u0431\u043c\u0435\u043d\u0438\u0432\u0430\u0442\u044c\u0441\u044f \u0434\u0430\u043d\u043d\u044b\u043c\u0438 \u0441 \u0433\u0440\u0430\u0444\u0438\u0447\u0435\u0441\u043a\u0438\u043c\u0438 \u0434\u0440\u0430\u0439\u0432\u0435\u0440\u0430\u043c\u0438 \u0434\u043b\u044f \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433\u0430 \u043d\u0430 \u044d\u043a\u0440\u0430\u043d\u0435. \u041c\u044b \u0431\u044b \u043d\u0435 \u0445\u043e\u0442\u0435\u043b\u0438 \u043e\u0431\u043c\u0435\u043d\u0438\u0432\u0430\u0442\u044c\u0441\u044f \u0434\u0430\u043d\u043d\u044b\u043c\u0438 \u043d\u0430\u043f\u0440\u044f\u043c\u0443\u044e, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0434\u043b\u044f \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u043e\u043a\u043d\u043e\u043c \u0432\u043e\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u0441\u044f \u043a\u0440\u043e\u0441\u0441\u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u0435\u043d\u043d\u044b\u043c \u0441\u043b\u043e\u0435\u043c \u0430\u0431\u0441\u0442\u0440\u0430\u043a\u0446\u0438\u0438 \u043f\u043e\u0434 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435\u043c OpenGL \u0438 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u043e\u0439 \u043f\u043e\u0434 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435\u043c GLUT (OpenGL Utility Toolkit).<\/p>\n<h4>\u041f\u0440\u0438\u043c\u0435\u0447\u0430\u043d\u0438\u0435 \u043e OpenGL<\/h4>\n<p>  OpenGL \u2014 \u044d\u0442\u043e \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0433\u0440\u0430\u0444\u0438\u0447\u0435\u0441\u043a\u0438\u0445 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439 (API) \u0434\u043b\u044f \u043a\u0440\u043e\u0441\u0441\u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u0435\u043d\u043d\u043e\u0439 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438. \u042d\u0442\u043e \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u044b\u0439 API \u0434\u043b\u044f \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0433\u0440\u0430\u0444\u0438\u0447\u0435\u0441\u043a\u0438\u0445 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439 \u0434\u043b\u044f \u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u0430 \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c. OpenGL \u0438\u043c\u0435\u0435\u0442 \u0434\u0432\u0430 \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u0445 \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u0430: Legacy OpenGL \u0438 Modern OpenGL.<\/p>\n<p>  \u0420\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433 \u0432 OpenGL \u043e\u0441\u043d\u043e\u0432\u0430\u043d \u043d\u0430 \u043f\u043e\u043b\u0438\u0433\u043e\u043d\u0430\u0445, \u0437\u0430\u0434\u0430\u0432\u0430\u0435\u043c\u044b\u0445 \u0432\u0435\u0440\u0448\u0438\u043d\u0430\u043c\u0438 \u0438 \u043d\u043e\u0440\u043c\u0430\u043b\u044f\u043c\u0438. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0434\u043b\u044f \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433\u0430 \u043e\u0434\u043d\u043e\u0439 \u0441\u0442\u043e\u0440\u043e\u043d\u044b \u043a\u0443\u0431\u0430 \u043c\u044b \u0437\u0430\u0434\u0430\u0451\u043c 4 \u0432\u0435\u0440\u0448\u0438\u043d\u044b \u0438 \u043d\u043e\u0440\u043c\u0430\u043b\u044c \u043a \u0441\u0442\u043e\u0440\u043e\u043d\u0435.<\/p>\n<p>  Legacy OpenGL \u0438\u043c\u0435\u0435\u0442 \u043a\u043e\u043d\u0432\u0435\u0439\u0435\u0440 \u0441 \u0444\u0438\u043a\u0441\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u043c\u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u044f\u043c\u0438 (fixed function pipeline). \u0417\u0430\u0434\u0430\u0432\u0430\u044f \u0433\u043b\u043e\u0431\u0430\u043b\u044c\u043d\u044b\u0435 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435, \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0441\u0442 \u043c\u043e\u0436\u0435\u0442 \u0432\u043a\u043b\u044e\u0447\u0430\u0442\u044c \u0438 \u043e\u0442\u043a\u043b\u044e\u0447\u0430\u0442\u044c \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0442\u0430\u043a\u0438\u0445 \u0444\u0443\u043d\u043a\u0446\u0438\u0439, \u043a\u0430\u043a \u043e\u0441\u0432\u0435\u0449\u0435\u043d\u0438\u0435, \u0440\u0430\u0441\u043a\u0440\u0430\u0441\u043a\u0430, \u0443\u0441\u0435\u0447\u0435\u043d\u0438\u0435 \u0433\u0440\u0430\u043d\u0435\u0439 \u0438 \u0442.\u0434. \u041f\u043e\u0441\u043b\u0435 \u0447\u0435\u0433\u043e OpenGL \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u0442 \u0441\u0446\u0435\u043d\u0443 \u0441\u043e \u0432\u043a\u043b\u044e\u0447\u0435\u043d\u043d\u043e\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u043e\u0441\u0442\u044c\u044e. \u0422\u0430\u043a\u0430\u044f \u0441\u0438\u0441\u0442\u0435\u043c\u0430 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0443\u0441\u0442\u0430\u0440\u0435\u0432\u0448\u0435\u0439.<\/p>\n<p>  \u0412 Modern OpenGL \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0440\u0443\u0435\u043c\u044b\u0439 \u043a\u043e\u043d\u0432\u0435\u0439\u0435\u0440 \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433\u0430 (programmable rendering pipeline), \u043f\u0440\u0438 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0441\u0442 \u043f\u0438\u0448\u0435\u0442 \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u0438\u0435 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b, \u043d\u0430\u0437\u044b\u0432\u0430\u0435\u043c\u044b\u0435 \u00ab\u0448\u0435\u0439\u0434\u0435\u0440\u0430\u043c\u0438\u00bb; \u043e\u043d\u0438 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u044e\u0442\u0441\u044f \u043d\u0430 \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u043c \u0433\u0440\u0430\u0444\u0438\u0447\u0435\u0441\u043a\u043e\u043c \u043e\u0431\u043e\u0440\u0443\u0434\u043e\u0432\u0430\u043d\u0438\u0438 (GPU). \u041f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0440\u0443\u0435\u043c\u044b\u0439 \u043a\u043e\u043d\u0432\u0435\u0439\u0435\u0440 Modern OpenGL \u0437\u0430\u043c\u0435\u043d\u0438\u043b \u0443\u0441\u0442\u0430\u0440\u0435\u0432\u0448\u0438\u0439 Legacy OpenGL.<\/p>\n<p>  \u0412 \u0441\u0432\u043e\u0451\u043c \u043f\u0440\u043e\u0435\u043a\u0442\u0435 \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c Legacy OpenGL. \u0424\u0438\u043a\u0441\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u0430\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u043e\u0441\u0442\u044c, \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u043c\u0430\u044f Legacy OpenGL, \u043e\u0447\u0435\u043d\u044c \u043f\u043e\u043b\u0435\u0437\u043d\u0430 \u0434\u043b\u044f \u043e\u0431\u0435\u0441\u043f\u0435\u0447\u0435\u043d\u0438\u044f \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u043e\u0433\u043e \u0440\u0430\u0437\u043c\u0435\u0440\u0430 \u043a\u043e\u0434\u0430. \u041e\u043d\u0430 \u0443\u043c\u0435\u043d\u044c\u0448\u0430\u0435\u0442 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b\u0445 \u0437\u043d\u0430\u043d\u0438\u0439 \u043b\u0438\u043d\u0435\u0439\u043d\u043e\u0439 \u0430\u043b\u0433\u0435\u0431\u0440\u044b \u0438 \u0443\u043f\u0440\u043e\u0449\u0430\u0435\u0442 \u043d\u0430\u0448 \u043a\u043e\u0434.<\/p>\n<h4>\u0427\u0442\u043e \u0442\u0430\u043a\u043e\u0435 GLUT<\/h4>\n<p>  \u0411\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 GLUT \u0438\u0437 \u043a\u043e\u043c\u043f\u043b\u0435\u043a\u0442\u0430 OpenGL \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043d\u0430\u043c \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u043e\u043a\u043d\u0430 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u043e\u043d\u043d\u043e\u0439 \u0441\u0438\u0441\u0442\u0435\u043c\u044b \u0438 \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u043e\u0431\u0440\u0430\u0442\u043d\u043e\u0433\u043e \u0432\u044b\u0437\u043e\u0432\u0430 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f. \u042d\u0442\u043e\u0439 \u0431\u0430\u0437\u043e\u0432\u043e\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u043e\u0441\u0442\u0438 \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0434\u043b\u044f \u043d\u0430\u0448\u0438\u0445 \u0446\u0435\u043b\u0435\u0439. \u0415\u0441\u043b\u0438 \u0431\u044b \u043d\u0430\u043c \u0431\u044b\u043b\u0430 \u043d\u0443\u0436\u043d\u0430 \u0431\u043e\u043b\u0435\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u0430\u044f \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 \u0434\u043b\u044f \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u043e\u043a\u043d\u0430\u043c\u0438 \u0438 \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f \u0441 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u043c, \u0442\u043e \u043c\u044b \u0431\u044b \u0437\u0430\u0434\u0443\u043c\u0430\u043b\u0438\u0441\u044c \u043e\u0431 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0438 \u043f\u043e\u043b\u043d\u043e\u0446\u0435\u043d\u043d\u043e\u0433\u043e \u0442\u0443\u043b\u043a\u0438\u0442\u0430 \u043d\u0430\u043f\u043e\u0434\u043e\u0431\u0438\u0435 GTK \u0438\u043b\u0438 Qt.<\/p>\n<h4>\u0421\u0440\u0435\u0434\u0441\u0442\u0432\u043e \u043f\u0440\u043e\u0441\u043c\u043e\u0442\u0440\u0430<\/h4>\n<p>  \u0414\u043b\u044f \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430\u043c\u0438 GLUT \u0438 OpenGL, \u0430 \u0442\u0430\u043a\u0436\u0435 \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u043e\u0439 \u0447\u0430\u0441\u0442\u044c\u044e \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b \u043c\u043e\u0434\u0435\u043b\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u043c\u044b \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u043a\u043b\u0430\u0441\u0441 \u043f\u043e\u0434 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435\u043c <code>Viewer<\/code>. \u041c\u044b \u0431\u0443\u0434\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0435\u0434\u0438\u043d\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0439 \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440 <code>Viewer<\/code>, \u0443\u043f\u0440\u0430\u0432\u043b\u044f\u044e\u0449\u0438\u0439 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435\u043c \u0438 \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433\u043e\u043c \u043e\u043a\u043e\u043d, \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0449\u0438\u0439 \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u0439 \u0446\u0438\u043a\u043b \u043d\u0430\u0448\u0435\u0439 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b. \u0412\u043d\u0443\u0442\u0440\u0438 \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u0430 \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 <code>Viewer<\/code> \u043c\u044b \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u043e\u043a\u043d\u043e GUI \u0438 \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u0443\u0435\u043c OpenGL.<\/p>\n<p>  \u0424\u0443\u043d\u043a\u0446\u0438\u044f <code>init_interface<\/code> \u0441\u043e\u0437\u0434\u0430\u0451\u0442 \u043e\u043a\u043d\u043e, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u0431\u0443\u0434\u0435\u0442 \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u0442\u044c\u0441\u044f \u0440\u0435\u0434\u0430\u043a\u0442\u043e\u0440, \u0438 \u0437\u0430\u0434\u0430\u0451\u0442 \u0444\u0443\u043d\u043a\u0446\u0438\u044e, \u043a\u043e\u0442\u043e\u0440\u043e\u0430\u044f \u0434\u043e\u043b\u0436\u043d\u0430 \u0432\u044b\u0437\u044b\u0432\u0430\u0442\u044c\u0441\u044f \u0434\u043b\u044f \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433\u0430 \u043f\u0440\u043e\u0435\u043a\u0442\u0430. \u0424\u0443\u043d\u043a\u0446\u0438\u044f <code>init_opengl<\/code> \u0437\u0430\u0434\u0430\u0451\u0442 \u043d\u0443\u0436\u043d\u043e\u0435 \u0434\u043b\u044f \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 OpenGL. \u041e\u043d\u0430 \u0437\u0430\u0434\u0430\u0451\u0442 \u043c\u0430\u0442\u0440\u0438\u0446\u044b, \u0432\u043a\u043b\u044e\u0447\u0430\u0435\u0442 \u043e\u0442\u0441\u0435\u0447\u0435\u043d\u0438\u0435 \u0437\u0430\u0434\u043d\u0438\u0445 \u0433\u0440\u0430\u043d\u0435\u0439, \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u0443\u0435\u0442 \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a \u0441\u0432\u0435\u0442\u0430 \u0434\u043b\u044f \u043e\u0441\u0432\u0435\u0449\u0435\u043d\u0438\u044f \u0441\u0446\u0435\u043d\u044b \u0438 \u0441\u043e\u043e\u0431\u0449\u0430\u0435\u0442 OpenGL, \u0447\u0442\u043e \u043e\u0431\u044a\u0435\u043a\u0442\u044b \u043d\u0443\u0436\u043d\u043e \u0440\u0430\u0441\u043a\u0440\u0430\u0448\u0438\u0432\u0430\u0442\u044c. \u0424\u0443\u043d\u043a\u0446\u0438\u044f <code>init_scene<\/code> \u0441\u043e\u0437\u0434\u0430\u0451\u0442 \u043e\u0431\u044a\u0435\u043a\u0442\u044b <code>Scene<\/code> \u0438 \u0440\u0430\u0441\u043f\u043e\u043b\u0430\u0433\u0430\u0435\u0442 \u043d\u0430\u0447\u0430\u043b\u044c\u043d\u044b\u0435 \u0443\u0437\u043b\u044b, \u0447\u0442\u043e\u0431\u044b \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043c\u043e\u0433 \u043d\u0430\u0447\u0430\u0442\u044c \u0440\u0430\u0431\u043e\u0442\u0443. \u0427\u0443\u0442\u044c \u043d\u0438\u0436\u0435 \u043c\u044b \u0443\u0437\u043d\u0430\u0435\u043c \u0431\u043e\u043b\u044c\u0448\u0435 \u043e \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0435 \u0434\u0430\u043d\u043d\u044b\u0445 <code>Scene<\/code>. \u041d\u0430\u043a\u043e\u043d\u0435\u0446, <code>init_interaction<\/code> \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u0443\u0435\u0442 \u043e\u0431\u0440\u0430\u0442\u043d\u044b\u0435 \u0432\u044b\u0437\u043e\u0432\u044b \u0444\u0443\u043d\u043a\u0446\u0438\u0439 \u0434\u043b\u044f \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f \u0441 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u043c, \u0447\u0442\u043e \u043c\u044b \u043e\u0431\u0441\u0443\u0434\u0438\u043c \u043f\u043e\u0437\u0436\u0435.<\/p>\n<p>  \u041f\u043e\u0441\u043b\u0435 \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 <code>Viewer<\/code> \u043c\u044b \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u043c <code>glutMainLoop<\/code>, \u0447\u0442\u043e\u0431\u044b \u043f\u0435\u0440\u0435\u043d\u0435\u0441\u0442\u0438 \u0438\u0441\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b \u0432 GLUT. \u042d\u0442\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u043d\u0438\u043a\u043e\u0433\u0434\u0430 \u043d\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442 \u0432\u043e\u0437\u0432\u0440\u0430\u0442. \u041e\u0431\u0440\u0430\u0442\u043d\u044b\u0435 \u0432\u044b\u0437\u043e\u0432\u044b \u0444\u0443\u043d\u043a\u0446\u0438\u0439, \u0437\u0430\u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u043d\u0430\u043c\u0438 \u0434\u043b\u044f \u0441\u043e\u0431\u044b\u0442\u0438\u0439 GLUT, \u0431\u0443\u0434\u0443\u0442 \u0432\u044b\u0437\u044b\u0432\u0430\u0442\u044c\u0441\u044f \u043f\u0440\u0438 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0438 \u044d\u0442\u0438\u0445 \u0441\u043e\u0431\u044b\u0442\u0438\u0439.<\/p>\n<pre><code class=\"python\">class Viewer(object):     def __init__(self):         &quot;&quot;&quot; Initialize the viewer. &quot;&quot;&quot;         self.init_interface()         self.init_opengl()         self.init_scene()         self.init_interaction()         init_primitives()      def init_interface(self):         &quot;&quot;&quot; initialize the window and register the render function &quot;&quot;&quot;         glutInit()         glutInitWindowSize(640, 480)         glutCreateWindow(&quot;3D Modeller&quot;)         glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB)         glutDisplayFunc(self.render)      def init_opengl(self):         &quot;&quot;&quot; initialize the opengl settings to render the scene &quot;&quot;&quot;         self.inverseModelView = numpy.identity(4)         self.modelView = numpy.identity(4)          glEnable(GL_CULL_FACE)         glCullFace(GL_BACK)         glEnable(GL_DEPTH_TEST)         glDepthFunc(GL_LESS)          glEnable(GL_LIGHT0)         glLightfv(GL_LIGHT0, GL_POSITION, GLfloat_4(0, 0, 1, 0))         glLightfv(GL_LIGHT0, GL_SPOT_DIRECTION, GLfloat_3(0, 0, -1))          glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE)         glEnable(GL_COLOR_MATERIAL)         glClearColor(0.4, 0.4, 0.4, 0.0)      def init_scene(self):         &quot;&quot;&quot; initialize the scene object and initial scene &quot;&quot;&quot;         self.scene = Scene()         self.create_sample_scene()      def create_sample_scene(self):         cube_node = Cube()         cube_node.translate(2, 0, 2)         cube_node.color_index = 2         self.scene.add_node(cube_node)          sphere_node = Sphere()         sphere_node.translate(-2, 0, 2)         sphere_node.color_index = 3         self.scene.add_node(sphere_node)          hierarchical_node = SnowFigure()         hierarchical_node.translate(-2, 0, -2)         self.scene.add_node(hierarchical_node)      def init_interaction(self):         &quot;&quot;&quot; init user interaction and callbacks &quot;&quot;&quot;         self.interaction = Interaction()         self.interaction.register_callback('pick', self.pick)         self.interaction.register_callback('move', self.move)         self.interaction.register_callback('place', self.place)         self.interaction.register_callback('rotate_color', self.rotate_color)         self.interaction.register_callback('scale', self.scale)      def main_loop(self):         glutMainLoop()  if __name__ == &quot;__main__&quot;:     viewer = Viewer()     viewer.main_loop()<\/code><\/pre>\n<p>  \u041f\u0440\u0435\u0436\u0434\u0435 \u0447\u0435\u043c \u0440\u0430\u0437\u0431\u0438\u0440\u0430\u0442\u044c \u0444\u0443\u043d\u043a\u0446\u0438\u044e <code>render<\/code>, \u043c\u044b \u0434\u043e\u043b\u0436\u043d\u044b \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u043f\u043e\u0433\u043e\u0432\u043e\u0440\u0438\u0442\u044c \u043e \u043b\u0438\u043d\u0435\u0439\u043d\u043e\u0439 \u0430\u043b\u0433\u0435\u0431\u0440\u0435.<\/p>\n<h3>\u041a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u043d\u043e\u0435 \u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u043e<\/h3>\n<p>  \u0412 \u043d\u0430\u0448\u0435\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u043d\u043e\u0435 \u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u043e \u0431\u0443\u0434\u0435\u0442 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u0442\u044c \u0441\u043e\u0431\u043e\u0439 \u0442\u043e\u0447\u043a\u0443 \u043d\u0430\u0447\u0430\u043b\u0430 \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442 \u0438 \u043d\u0430\u0431\u043e\u0440 \u0438\u0437 \u0442\u0440\u0451\u0445 \u0431\u0430\u0437\u0438\u0441\u043d\u044b\u0445 \u0432\u0435\u043a\u0442\u043e\u0440\u043e\u0432, \u043e\u0431\u044b\u0447\u043d\u043e \u043e\u0431\u043e\u0437\u043d\u0430\u0447\u0430\u0435\u043c\u044b\u0445 \u043a\u0430\u043a \u043e\u0441\u0438 <math><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/formulas\/817\/b92\/407\/817b92407f764f57af9226e50cc788fd.svg\" alt=\"$x$\" data-tex=\"inline\"><\/math>, <math><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/formulas\/9b3\/4c4\/da5\/9b34c4da5c757d4982bbd1b6f2e8998a.svg\" alt=\"$y$\" data-tex=\"inline\"><\/math> \u0438 <math><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/formulas\/4ec\/3e2\/363\/4ec3e23638b6073b649999485c251c94.svg\" alt=\"$z$\" data-tex=\"inline\"><\/math>.<\/p>\n<h3>\u0422\u043e\u0447\u043a\u0430<\/h3>\n<p>  \u041b\u044e\u0431\u0443\u044e \u0442\u043e\u0447\u043a\u0443 \u0432 \u0442\u0440\u0451\u0445 \u0438\u0437\u043c\u0435\u0440\u0435\u043d\u0438\u044f\u0445 \u043c\u043e\u0436\u043d\u043e \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u043a\u0430\u043a \u0441\u043c\u0435\u0449\u0435\u043d\u0438\u0435 \u0432 \u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f\u0445 <math><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/formulas\/817\/b92\/407\/817b92407f764f57af9226e50cc788fd.svg\" alt=\"$x$\" data-tex=\"inline\"><\/math>, <math><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/formulas\/9b3\/4c4\/da5\/9b34c4da5c757d4982bbd1b6f2e8998a.svg\" alt=\"$y$\" data-tex=\"inline\"><\/math> \u0438 <math><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/formulas\/4ec\/3e2\/363\/4ec3e23638b6073b649999485c251c94.svg\" alt=\"$z$\" data-tex=\"inline\"><\/math> \u043e\u0442\u043d\u043e\u0441\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0442\u043e\u0447\u043a\u0438 \u043d\u0430\u0447\u0430\u043b\u0430 \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442. \u041e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u0442\u043e\u0447\u043a\u0438 \u0437\u0430\u0434\u0430\u0451\u0442\u0441\u044f \u043e\u0442\u043d\u043e\u0441\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u043d\u043e\u0433\u043e \u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u0430, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u0442\u043e\u0447\u043a\u0430. \u041e\u0434\u043d\u0430 \u0438 \u0442\u0430 \u0436\u0435 \u0442\u043e\u0447\u043a\u0430 \u0438\u043c\u0435\u0435\u0442 \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b\u0435 \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u044f \u0432 \u0440\u0430\u0437\u043d\u044b\u0445 \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u043d\u044b\u0445 \u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u0430\u0445. \u041b\u044e\u0431\u0430\u044f \u0442\u043e\u0447\u043a\u0430 \u0432 \u0442\u0440\u0451\u0445 \u0438\u0437\u043c\u0435\u0440\u0435\u043d\u0438\u044f\u0445 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0430 \u0432 \u043b\u044e\u0431\u043e\u043c \u0442\u0440\u0451\u0445\u043c\u0435\u0440\u043d\u043e\u043c \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u043d\u043e\u043c \u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u0435.<\/p>\n<h3>\u0412\u0435\u043a\u0442\u043e\u0440<\/h3>\n<p>  \u0412\u0435\u043a\u0442\u043e\u0440 \u2014 \u044d\u0442\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0438\u0437 <math><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/formulas\/817\/b92\/407\/817b92407f764f57af9226e50cc788fd.svg\" alt=\"$x$\" data-tex=\"inline\"><\/math>, <math><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/formulas\/9b3\/4c4\/da5\/9b34c4da5c757d4982bbd1b6f2e8998a.svg\" alt=\"$y$\" data-tex=\"inline\"><\/math> \u0438 <math><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/formulas\/4ec\/3e2\/363\/4ec3e23638b6073b649999485c251c94.svg\" alt=\"$z$\" data-tex=\"inline\"><\/math>, \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u044e\u0449\u0435\u0435 \u0440\u0430\u0437\u043d\u0438\u0446\u0443 \u043c\u0435\u0436\u0434\u0443 \u0434\u0432\u0443\u043c\u044f \u0442\u043e\u0447\u043a\u0430\u043c\u0438 \u043f\u043e \u043e\u0441\u044f\u043c <math><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/formulas\/817\/b92\/407\/817b92407f764f57af9226e50cc788fd.svg\" alt=\"$x$\" data-tex=\"inline\"><\/math>, <math><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/formulas\/9b3\/4c4\/da5\/9b34c4da5c757d4982bbd1b6f2e8998a.svg\" alt=\"$y$\" data-tex=\"inline\"><\/math> \u0438 <math><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/formulas\/4ec\/3e2\/363\/4ec3e23638b6073b649999485c251c94.svg\" alt=\"$z$\" data-tex=\"inline\"><\/math>.<\/p>\n<h3>\u041c\u0430\u0442\u0440\u0438\u0446\u0430 \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u0439<\/h3>\n<p>  \u0412 \u043a\u043e\u043c\u043f\u044c\u044e\u0442\u0435\u0440\u043d\u043e\u0439 \u0433\u0440\u0430\u0444\u0438\u043a\u0435 \u0443\u0434\u043e\u0431\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0440\u0430\u0437\u043d\u044b\u0445 \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u043d\u044b\u0445 \u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432 \u0434\u043b\u044f \u0440\u0430\u0437\u043d\u044b\u0445 \u0442\u0438\u043f\u043e\u0432 \u0442\u043e\u0447\u0435\u043a. \u041c\u0430\u0442\u0440\u0438\u0446\u044b \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u0439 \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u0443\u044e\u0442 \u0442\u043e\u0447\u043a\u0438 \u0438\u0437 \u043e\u0434\u043d\u043e\u0433\u043e \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u043d\u043e\u0433\u043e \u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u0430 \u0432 \u0434\u0440\u0443\u0433\u043e\u0435. \u0427\u0442\u043e\u0431\u044b \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u0442\u044c \u0432\u0435\u043a\u0442\u043e\u0440 <math><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/formulas\/1c1\/778\/187\/1c1778187263268cc347012d16da61e2.svg\" alt=\"$v$\" data-tex=\"inline\"><\/math> \u0438\u0437 \u043e\u0434\u043d\u043e\u0433\u043e \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u043d\u043e\u0433\u043e \u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u0430 \u0432 \u0434\u0440\u0443\u0433\u043e\u0435, \u043c\u044b \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u043c \u0443\u043c\u043d\u043e\u0436\u0435\u043d\u0438\u0435 \u043d\u0430 \u043c\u0430\u0442\u0440\u0438\u0446\u0443 \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u0439 <math><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/formulas\/94d\/13e\/e0a\/94d13ee0aadd7f17977e0d279af38d42.svg\" alt=\"$M$\" data-tex=\"inline\"><\/math>: <math><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/formulas\/d87\/bd0\/f09\/d87bd0f0922ac16cb92e7fec983b6201.svg\" alt=\"$v&#39; = M v$\" data-tex=\"inline\"><\/math>. \u041f\u0440\u0438\u043c\u0435\u0440\u0430\u043c\u0438 \u0440\u0430\u0441\u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0451\u043d\u043d\u044b\u0445 \u043c\u0430\u0442\u0440\u0438\u0446 \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u044f\u0432\u043b\u044f\u044e\u0442\u0441\u044f \u043f\u0435\u0440\u0435\u043c\u0435\u0449\u0435\u043d\u0438\u0435, \u043c\u0430\u0441\u0448\u0442\u0430\u0431\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0438 \u043f\u043e\u0432\u043e\u0440\u043e\u0442.<\/p>\n<h3>\u041a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u043d\u044b\u0435 \u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u0430 \u043c\u043e\u0434\u0435\u043b\u0438, \u043c\u0438\u0440\u0430, \u043e\u043a\u043d\u0430 \u043f\u0440\u043e\u0441\u043c\u043e\u0442\u0440\u0430 \u0438 \u043f\u0440\u043e\u0435\u0446\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f<\/h3>\n<p>  <\/p>\n<div style=\"text-align:center;\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/post_images\/77c\/e26\/789\/77ce26789e8dd2db53958eac8029faf8.png\"><\/div>\n<p>  <i>\u0420\u0438\u0441\u0443\u043d\u043e\u043a 1 \u2014 \u041a\u043e\u043d\u0432\u0435\u0439\u0435\u0440 \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u0439<\/i><\/p>\n<p>  \u0414\u043b\u044f \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u043a\u0438 \u043d\u0430 \u044d\u043a\u0440\u0430\u043d\u0435 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430 \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u044c \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u043c\u0435\u0436\u0434\u0443 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u043c\u0438 \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u043d\u044b\u043c\u0438 \u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u0430\u043c\u0438.<\/p>\n<p>  \u0412\u0441\u0435 \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u044f, \u043f\u043e\u043a\u0430\u0437\u0430\u043d\u043d\u044b\u0435 \u0432 \u043f\u0440\u0430\u0432\u043e\u0439 \u0447\u0430\u0441\u0442\u0438 \u0420\u0438\u0441\u0443\u043d\u043a\u0430 1, \u0432 \u0442\u043e\u043c \u0447\u0438\u0441\u043b\u0435 \u0432\u0441\u0435 \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u0438\u0437 \u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u0430 \u043a\u0430\u043c\u0435\u0440\u044b (Eye Space) \u0432 \u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u043e \u043e\u043a\u043d\u0430 \u043f\u0440\u043e\u0441\u043c\u043e\u0442\u0440\u0430 (Viewport Space) \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0442\u044c \u0437\u0430 \u043d\u0430\u0441 OpenGL.<\/p>\n<p>  \u041f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u0438\u0437 \u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u0430 \u043a\u0430\u043c\u0435\u0440\u044b \u0432 \u043e\u0434\u043d\u043e\u0440\u043e\u0434\u043d\u043e\u0435 \u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u043e \u0443\u0441\u0435\u0447\u0435\u043d\u0438\u044f (clip space) \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442\u0441\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u0435\u0439 <code>gluPerspective<\/code>, \u0430 \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u0432 \u043d\u043e\u0440\u043c\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d\u043d\u043e\u0435 \u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u043e \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0430 \u0438 \u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u043e \u043e\u043a\u043d\u0430 \u043e\u0431\u0437\u043e\u0440\u0430 \u2014 \u0444\u0443\u043d\u043a\u0446\u0438\u0435\u0439 <code>glViewport<\/code>. \u042d\u0442\u0438 \u043c\u0430\u0442\u0440\u0438\u0446\u044b \u043f\u0435\u0440\u0435\u043c\u043d\u043e\u0436\u0430\u044e\u0442\u0441\u044f \u0438 \u0445\u0440\u0430\u043d\u044f\u0442\u0441\u044f \u043a\u0430\u043a \u043c\u0430\u0442\u0440\u0438\u0446\u0430 GL_PROJECTION. \u0414\u043b\u044f \u043d\u0430\u0448\u0435\u0433\u043e \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u043d\u0435 \u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u0437\u043d\u0430\u0442\u044c \u0442\u0435\u0440\u043c\u0438\u043d\u043e\u043b\u043e\u0433\u0438\u044e \u0438\u043b\u0438 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u043e\u0441\u0442\u0438 \u0440\u0430\u0431\u043e\u0442\u044b \u044d\u0442\u0438\u0445 \u043c\u0430\u0442\u0440\u0438\u0446.<\/p>\n<p>  \u041e\u0434\u043d\u0430\u043a\u043e \u043d\u0430\u043c \u0441\u0430\u043c\u043e\u0441\u0442\u043e\u044f\u0442\u0435\u043b\u044c\u043d\u043e \u043f\u0440\u0438\u0434\u0451\u0442\u0441\u044f \u0437\u0430\u043d\u044f\u0442\u044c\u0441\u044f \u043b\u0435\u0432\u043e\u0439 \u0447\u0430\u0441\u0442\u044c\u044e \u0441\u0445\u0435\u043c\u044b. \u041c\u044b \u0437\u0430\u0434\u0430\u0451\u043c \u043c\u0430\u0442\u0440\u0438\u0446\u0443, \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u0443\u044e\u0449\u0443\u044e \u0442\u043e\u0447\u043a\u0438 \u043c\u043e\u0434\u0435\u043b\u0438 (\u0442\u0430\u043a\u0436\u0435 \u043d\u0430\u0437\u044b\u0432\u0430\u0435\u043c\u043e\u0439 \u043c\u0435\u0448\u0435\u043c) \u0438\u0437 \u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432 \u043c\u043e\u0434\u0435\u043b\u0435\u0439 \u0432 \u043c\u0438\u0440\u043e\u0432\u043e\u0435 \u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u043e, \u044d\u0442\u043e \u043d\u0430\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u043c\u0430\u0442\u0440\u0438\u0446\u0435\u0439 \u043c\u043e\u0434\u0435\u043b\u0438. \u0422\u0430\u043a\u0436\u0435 \u043c\u044b \u0437\u0430\u0434\u0430\u0451\u043c \u043c\u0430\u0442\u0440\u0438\u0446\u0443 \u043e\u0431\u0437\u043e\u0440\u0430, \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u044e\u0449\u0443\u044e \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u0438\u0437 \u043c\u0438\u0440\u043e\u0432\u043e\u0433\u043e \u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u0430 \u0432 \u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u043e \u043a\u0430\u043c\u0435\u0440\u044b. \u0412 \u044d\u0442\u043e\u043c \u043f\u0440\u043e\u0435\u043a\u0442\u0435 \u043c\u044b \u0441\u043a\u043e\u043c\u0431\u0438\u043d\u0438\u0440\u0443\u0435\u043c \u044d\u0442\u0438 \u0434\u0432\u0435 \u043c\u0430\u0442\u0440\u0438\u0446\u044b, \u0447\u0442\u043e\u0431\u044b \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u043c\u0430\u0442\u0440\u0438\u0446\u0443 ModelView.<\/p>\n<p>  \u0427\u0442\u043e\u0431\u044b \u0443\u0437\u043d\u0430\u0442\u044c \u0431\u043e\u043b\u044c\u0448\u0435 \u043e \u043f\u043e\u043b\u043d\u043e\u043c \u043a\u043e\u043d\u0432\u0435\u0439\u0435\u0440\u0435 \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433\u0430 \u0433\u0440\u0430\u0444\u0438\u043a\u0438 \u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u044b\u0445 \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u043d\u044b\u0445 \u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u0430\u0445, \u043f\u0440\u043e\u0447\u0438\u0442\u0430\u0439\u0442\u0435 \u0433\u043b\u0430\u0432\u0443 2 \u043a\u043d\u0438\u0433\u0438 <a href=\"http:\/\/www.realtimerendering.com\/\" rel=\"nofollow\"><em>Real Time Rendering<\/em><\/a> \u0438\u043b\u0438 \u0434\u0440\u0443\u0433\u0443\u044e \u043a\u043d\u0438\u0433\u0443 \u043e \u043a\u043e\u043c\u043f\u044c\u044e\u0442\u0435\u0440\u043d\u043e\u0439 \u0433\u0440\u0430\u0444\u0438\u043a\u0435 \u0434\u043b\u044f \u043d\u0430\u0447\u0438\u043d\u0430\u044e\u0449\u0438\u0445.<\/p>\n<h3>\u0420\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433 \u043f\u0440\u0438 \u043f\u043e\u043c\u043e\u0449\u0438 Viewer<\/h3>\n<p>  \u0424\u0443\u043d\u043a\u0446\u0438\u044f <code>render<\/code> \u043d\u0430\u0447\u0438\u043d\u0430\u0435\u0442\u0441\u044f \u0441 \u043f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u043a\u0438 \u043b\u044e\u0431\u043e\u0433\u043e \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f OpenGL, \u0447\u0442\u043e \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0442\u044c \u0432\u043e \u0432\u0440\u0435\u043c\u044f \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433\u0430. \u041e\u043d\u0430 \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u0443\u0435\u0442 \u043c\u0430\u0442\u0440\u0438\u0446\u0443 \u043f\u0440\u043e\u0435\u0446\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u043f\u0440\u0438 \u043f\u043e\u043c\u043e\u0449\u0438 <code>init_view<\/code> \u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 \u0434\u0430\u043d\u043d\u044b\u0435 \u0438\u0437 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f \u0441 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u043c \u0434\u043b\u044f \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u043c\u0430\u0442\u0440\u0438\u0446\u044b ModelView \u0441 \u043c\u0430\u0442\u0440\u0438\u0446\u0435\u0439 \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u0439, \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u044e\u0449\u0435\u0439 \u043f\u0435\u0440\u0435\u0445\u043e\u0434 \u0438\u0437 \u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u0430 \u0441\u0446\u0435\u043d\u044b \u0432 \u043c\u0438\u0440\u043e\u0432\u043e\u0435 \u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u043e. \u041f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435 \u043e \u043a\u043b\u0430\u0441\u0441\u0435 Interaction \u0431\u0443\u0434\u0435\u0442 \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u043e \u043d\u0438\u0436\u0435. \u041e\u043d\u0430 \u043e\u0447\u0438\u0449\u0430\u0435\u0442 \u044d\u043a\u0440\u0430\u043d \u043f\u0440\u0438 \u043f\u043e\u043c\u043e\u0449\u0438 <code>glClear<\/code>, \u043f\u0440\u0438\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442 \u0441\u0446\u0435\u043d\u0435 \u043e\u0442\u0440\u0435\u043d\u0434\u0435\u0440\u0438\u0442\u044c\u0441\u044f, \u0430 \u0437\u0430\u0442\u0435\u043c \u0440\u0438\u0441\u0443\u0435\u0442 \u0441\u0435\u0442\u043a\u0443 \u0435\u0434\u0438\u043d\u0438\u0447\u043d\u044b\u0445 \u043a\u0432\u0430\u0434\u0440\u0430\u0442\u043e\u0432.<\/p>\n<p>  \u041f\u0435\u0440\u0435\u0434 \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433\u043e\u043c \u0441\u0435\u0442\u043a\u0438 \u043c\u044b \u043e\u0442\u043a\u043b\u044e\u0447\u0430\u0435\u043c \u043e\u0441\u0432\u0435\u0449\u0435\u043d\u0438\u0435 OpenGL. \u041f\u0440\u0438 \u043e\u0442\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0438 \u043e\u0441\u0432\u0435\u0449\u0435\u043d\u0438\u044f OpenGL \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u0442 \u043e\u0431\u044a\u0435\u043a\u0442\u044b \u0441\u043f\u043b\u043e\u0448\u043d\u044b\u043c \u0446\u0432\u0435\u0442\u043e\u043c, \u0430 \u043d\u0435 \u0441\u0438\u043c\u0443\u043b\u0438\u0440\u0443\u0435\u0442 \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a\u0438 \u043e\u0441\u0432\u0435\u0449\u0435\u043d\u0438\u044f. \u0411\u043b\u0430\u0433\u043e\u0434\u0430\u0440\u044f \u044d\u0442\u043e\u043c\u0443 \u0441\u0435\u0442\u043a\u0430 \u0432\u0438\u0437\u0443\u0430\u043b\u044c\u043d\u043e \u043e\u0442\u043b\u0438\u0447\u0430\u0435\u0442\u0441\u044f \u043e\u0442 \u0441\u0446\u0435\u043d\u044b. \u0414\u0430\u043b\u0435\u0435 <code>glFlush<\/code> \u043f\u043e\u0434\u0430\u0451\u0442 \u0441\u0438\u0433\u043d\u0430\u043b \u0433\u0440\u0430\u0444\u0438\u0447\u0435\u0441\u043a\u043e\u043c\u0443 \u0434\u0440\u0430\u0439\u0432\u0435\u0440\u0443, \u0447\u0442\u043e \u043c\u044b \u0433\u043e\u0442\u043e\u0432\u044b \u043a \u043e\u0447\u0438\u0441\u0442\u043a\u0435 \u0431\u0443\u0444\u0435\u0440\u0430 \u0438 \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044e \u043d\u0430 \u044d\u043a\u0440\u0430\u043d.<\/p>\n<pre><code class=\"python\">    # class Viewer     def render(self):         &quot;&quot;&quot; The render pass for the scene &quot;&quot;&quot;         self.init_view()          glEnable(GL_LIGHTING)         glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)          # Load the modelview matrix from the current state of the trackball         glMatrixMode(GL_MODELVIEW)         glPushMatrix()         glLoadIdentity()         loc = self.interaction.translation         glTranslated(loc[0], loc[1], loc[2])         glMultMatrixf(self.interaction.trackball.matrix)          # store the inverse of the current modelview.         currentModelView = numpy.array(glGetFloatv(GL_MODELVIEW_MATRIX))         self.modelView = numpy.transpose(currentModelView)         self.inverseModelView = inv(numpy.transpose(currentModelView))          # render the scene. This will call the render function for each object         # in the scene         self.scene.render()          # draw the grid         glDisable(GL_LIGHTING)         glCallList(G_OBJ_PLANE)         glPopMatrix()          # flush the buffers so that the scene can be drawn         glFlush()      def init_view(self):         &quot;&quot;&quot; initialize the projection matrix &quot;&quot;&quot;         xSize, ySize = glutGet(GLUT_WINDOW_WIDTH), glutGet(GLUT_WINDOW_HEIGHT)         aspect_ratio = float(xSize) \/ float(ySize)          # load the projection matrix. Always the same         glMatrixMode(GL_PROJECTION)         glLoadIdentity()          glViewport(0, 0, xSize, ySize)         gluPerspective(70, aspect_ratio, 0.1, 1000.0)         glTranslated(0, 0, -15)<\/code><\/pre>\n<p>  <\/p>\n<h3>\u0427\u0442\u043e \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u0442\u044c: \u0441\u0446\u0435\u043d\u0430<\/h3>\n<p>  \u041f\u043e\u0441\u043b\u0435 \u0442\u043e\u0433\u043e, \u043a\u0430\u043a \u043c\u044b \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043b\u0438 \u043a\u043e\u043d\u0432\u0435\u0439\u0435\u0440 \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433\u0430 \u0434\u043b\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u043a\u0438 \u0432 \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u043d\u043e\u043c \u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u0435 \u043c\u0438\u0440\u0430, \u0447\u0442\u043e \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u0442\u044c? \u0412\u0441\u043f\u043e\u043c\u043d\u0438\u043c, \u0447\u0442\u043e \u043d\u0430\u0448\u0430 \u0446\u0435\u043b\u044c \u2014 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u043f\u0440\u043e\u0435\u043a\u0442\u0430, \u0441\u043e\u0441\u0442\u043e\u044f\u0449\u0435\u0433\u043e \u0438\u0437 3D-\u043c\u043e\u0434\u0435\u043b\u0435\u0439. \u041d\u0430\u043c \u043d\u0443\u0436\u043d\u0430 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 \u0434\u0430\u043d\u043d\u044b\u0445 \u0434\u043b\u044f \u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u044d\u0442\u043e\u0433\u043e \u043f\u0440\u043e\u0435\u043a\u0442\u0430. \u0430 \u0442\u0430\u043a\u0436\u0435 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 \u0434\u0430\u043d\u043d\u044b\u0445 \u0434\u043b\u044f \u0435\u0433\u043e \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433\u0430. \u041e\u0431\u0440\u0430\u0442\u0438\u0442\u0435 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435 \u043d\u0430 \u0432\u044b\u0437\u043e\u0432 <code>self.scene.render()<\/code> \u0432 \u0446\u0438\u043a\u043b\u0435 \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433\u0430 viewer. \u0427\u0442\u043e \u0442\u0430\u043a\u043e\u0435 scene?<\/p>\n<p>  \u041a\u043b\u0430\u0441\u0441 <code>Scene<\/code> \u2014 \u044d\u0442\u043e \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 \u0441\u043e \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u043e\u0439 \u0434\u0430\u043d\u043d\u044b\u0445, \u043a\u043e\u0442\u043e\u0440\u0443\u044e \u043c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u0434\u043b\u044f \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u044f \u043f\u0440\u043e\u0435\u043a\u0442\u0430. \u041e\u043d \u0430\u0431\u0441\u0442\u0440\u0430\u0433\u0438\u0440\u0443\u0435\u0442 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u043e\u0441\u0442\u0438 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b \u0434\u0430\u043d\u043d\u044b\u0445 \u0438 \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430, \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b\u0435 \u0434\u043b\u044f \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f \u0441 \u043f\u0440\u043e\u0435\u043a\u0442\u043e\u043c, \u0432 \u0442\u043e\u043c \u0447\u0438\u0441\u043b\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0434\u043b\u044f \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433\u0430, \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432 \u0438 \u043c\u0430\u043d\u0438\u043f\u0443\u043b\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430\u043c\u0438. \u0421\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442 \u043e\u0434\u0438\u043d \u043e\u0431\u044a\u0435\u043a\u0442 <code>Scene<\/code>, \u043a\u043e\u0442\u043e\u0440\u044b\u043c \u0432\u043b\u0430\u0434\u0435\u0435\u0442 viewer. \u042d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440 <code>Scene<\/code> \u0445\u0440\u0430\u043d\u0438\u0442 \u0441\u043f\u0438\u0441\u043e\u043a \u0432\u0441\u0435\u0445 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432 \u0441\u0446\u0435\u043d\u044b, \u043d\u0430\u0437\u044b\u0432\u0430\u0435\u043c\u044b\u0439 <code>node_list<\/code>. \u0422\u0430\u043a\u0436\u0435 \u043e\u043d \u043e\u0442\u0441\u043b\u0435\u0436\u0438\u0432\u0430\u0435\u0442 \u0432\u044b\u0431\u0440\u0430\u043d\u043d\u044b\u0439 \u044d\u043b\u0435\u043c\u0435\u043d\u0442. \u0424\u0443\u043d\u043a\u0446\u0438\u044f <code>render<\/code> \u0441\u0446\u0435\u043d\u044b \u043f\u0440\u043e\u0441\u0442\u043e \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442 <code>render<\/code> \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u043f\u0443\u043d\u043a\u0442\u0430 \u0441\u043f\u0438\u0441\u043a\u0430 <code>node_list<\/code>.<\/p>\n<pre><code class=\"python\">class Scene(object):      # the default depth from the camera to place an object at     PLACE_DEPTH = 15.0      def __init__(self):         # The scene keeps a list of nodes that are displayed         self.node_list = list()         # Keep track of the currently selected node.         # Actions may depend on whether or not something is selected         self.selected_node = None      def add_node(self, node):         &quot;&quot;&quot; Add a new node to the scene &quot;&quot;&quot;         self.node_list.append(node)      def render(self):         &quot;&quot;&quot; Render the scene. &quot;&quot;&quot;         for node in self.node_list:             node.render()<\/code><\/pre>\n<p>  <\/p>\n<h3>\u0423\u0437\u043b\u044b<\/h3>\n<p>  \u0412 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 <code>render<\/code> \u043a\u043b\u0430\u0441\u0441\u0430 Scene \u043c\u044b \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u043c <code>render<\/code> \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430 <code>node_list<\/code> \u043a\u043b\u0430\u0441\u0441\u0430 Scene. \u041d\u043e \u0447\u0442\u043e \u0437\u0430 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u044b \u043d\u0430\u0445\u043e\u0434\u044f\u0442\u0441\u044f \u0432 \u044d\u0442\u043e\u043c \u0441\u043f\u0438\u0441\u043a\u0435? \u041c\u044b \u043d\u0430\u0437\u044b\u0432\u0430\u0435\u043c \u0438\u0445 <em>\u0443\u0437\u043b\u0430\u043c\u0438<\/em>. \u0423\u0437\u0435\u043b \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u0432\u0441\u0435\u043c, \u0447\u0442\u043e \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u043c\u0435\u0441\u0442\u0438\u0442\u044c \u0432 \u0441\u0446\u0435\u043d\u0443. \u0412 \u043e\u0431\u044a\u0435\u043a\u0442\u043d\u043e-\u043e\u0440\u0438\u0435\u043d\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u043c \u041f\u041e \u043c\u044b \u043f\u0438\u0448\u0435\u043c <code>Node<\/code> \u043a\u0430\u043a \u0430\u0431\u0441\u0442\u0440\u0430\u043a\u0442\u043d\u044b\u0439 \u0431\u0430\u0437\u043e\u0432\u044b\u0439 \u043a\u043b\u0430\u0441\u0441. \u041b\u044e\u0431\u044b\u0435 \u043a\u043b\u0430\u0441\u0441\u044b, \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u044e\u0449\u0438\u0435 \u043e\u0431\u044a\u0435\u043a\u0442\u044b, \u0440\u0430\u0437\u043c\u0435\u0449\u0430\u0435\u043c\u044b\u0435 \u0432 <code>Scene<\/code>, \u0431\u0443\u0434\u0443\u0442 \u043d\u0430\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u044c \u043e\u0442 <code>Node<\/code>. \u042d\u0442\u043e\u0442 \u0431\u0430\u0437\u043e\u0432\u044b\u0439 \u043a\u043b\u0430\u0441\u0441 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043d\u0430\u043c \u0440\u0430\u0441\u0441\u0443\u0436\u0434\u0430\u0442\u044c \u043e \u0441\u0446\u0435\u043d\u0435 \u0430\u0431\u0441\u0442\u0440\u0430\u043a\u0442\u043d\u043e. \u041e\u0441\u0442\u0430\u043b\u044c\u043d\u0430\u044f \u0447\u0430\u0441\u0442\u044c \u043a\u043e\u0434\u043e\u0432\u043e\u0439 \u0431\u0430\u0437\u044b \u043d\u0435 \u043e\u0431\u044f\u0437\u0430\u043d\u0430 \u0437\u043d\u0430\u0442\u044c \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u043e\u0441\u0442\u0435\u0439 \u043e\u0431 \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0430\u0435\u043c\u043e\u043c \u0435\u044e \u043e\u0431\u044a\u0435\u043a\u0442\u0435; \u0435\u0439 \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0437\u043d\u0430\u0442\u044c, \u0447\u0442\u043e \u043e\u043d\u0438 \u043f\u0440\u0438\u043d\u0430\u0434\u043b\u0435\u0436\u0430\u0442 \u043a \u043a\u043b\u0430\u0441\u0441\u0443 <code>Node<\/code>.<\/p>\n<p>  \u041a\u0430\u0436\u0434\u044b\u0439 \u0442\u0438\u043f <code>Node<\/code> \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u0442 \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0435 \u043f\u043e\u0432\u0435\u0434\u0435\u043d\u0438\u0435 \u0434\u043b\u044f \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433\u0430 \u0441\u0430\u043c\u043e\u0433\u043e \u0441\u0435\u0431\u044f \u0438 \u0434\u043b\u044f \u043b\u044e\u0431\u044b\u0445 \u0434\u0440\u0443\u0433\u0438\u0445 \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0439. <code>Node<\/code> \u043e\u0442\u0441\u043b\u0435\u0436\u0438\u0432\u0430\u0435\u0442 \u0432\u0430\u0436\u043d\u044b\u0435 \u0434\u0430\u043d\u043d\u044b\u0435 \u043e \u0441\u0430\u043c\u043e\u043c \u0441\u0435\u0431\u0435: \u043c\u0430\u0442\u0440\u0438\u0446\u0443 \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u0439, \u043c\u0430\u0442\u0440\u0438\u0446\u0443 \u043c\u0430\u0441\u0448\u0442\u0430\u0431\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f, \u0446\u0432\u0435\u0442, \u0438 \u0442.\u043f. \u041f\u0440\u0438 \u0443\u043c\u043d\u043e\u0436\u0435\u043d\u0438\u0438 \u043c\u0430\u0442\u0440\u0438\u0446\u044b \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u0439 \u0443\u0437\u043b\u0430 \u043d\u0430 \u0435\u0433\u043e \u043c\u0430\u0442\u0440\u0438\u0446\u0443 \u043c\u0430\u0441\u0448\u0442\u0430\u0431\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f, \u043c\u044b \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u043c\u0430\u0442\u0440\u0438\u0446\u0443 \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u0439 \u0438\u0437 \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u043d\u043e\u0433\u043e \u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u0430 \u043c\u043e\u0434\u0435\u043b\u0438 \u0443\u0437\u043b\u0430 \u0432 \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u043d\u043e\u0435 \u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u043e \u043c\u0438\u0440\u0430. \u041a\u0440\u043e\u043c\u0435 \u0442\u043e\u0433\u043e, \u0443\u0437\u0435\u043b \u0442\u0430\u043a\u0436\u0435 \u0445\u0440\u0430\u043d\u0438\u0442 \u0432 \u0441\u0435\u0431\u0435 \u043f\u0430\u0440\u0430\u043b\u043b\u0435\u043b\u044c\u043d\u044b\u0439 \u043e\u0441\u044f\u043c \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0438\u0432\u0430\u044e\u0449\u0438\u0439 \u043f\u0430\u0440\u0430\u043b\u043b\u0435\u043b\u0435\u043f\u0438\u043f\u0435\u0434 (axis-aligned bounding box, AABB). \u041f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435 \u043e\u0431 AABB \u043c\u044b \u043f\u043e\u0433\u043e\u0432\u043e\u0440\u0438\u043c \u043d\u0438\u0436\u0435.<\/p>\n<p>  \u041f\u0440\u043e\u0441\u0442\u0435\u0439\u0448\u0435\u0439 \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e\u0439 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0435\u0439 <code>Node<\/code> \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f <em>\u043f\u0440\u0438\u043c\u0438\u0442\u0438\u0432<\/em>. \u041f\u0440\u0438\u043c\u0438\u0442\u0438\u0432 \u2014 \u044d\u0442\u043e \u0435\u0434\u0438\u043d\u0430\u044f \u0444\u0438\u0433\u0443\u0440\u0430, \u043a\u043e\u0442\u043e\u0440\u0443\u044e \u043c\u043e\u0436\u043d\u043e \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0432 \u0441\u0446\u0435\u043d\u0443. \u0412 \u043d\u0430\u0448\u0435\u0439 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0435 \u043f\u0440\u0438\u043c\u0438\u0442\u0438\u0432\u0430\u043c\u0438 \u0431\u0443\u0434\u0443\u0442 \u043a\u0443\u0431 (<code>Cube<\/code>) \u0438 \u0441\u0444\u0435\u0440\u0430 (<code>Sphere<\/code>).<\/p>\n<pre><code class=\"python\">class Node(object):     &quot;&quot;&quot; Base class for scene elements &quot;&quot;&quot;     def __init__(self):         self.color_index = random.randint(color.MIN_COLOR, color.MAX_COLOR)         self.aabb = AABB([0.0, 0.0, 0.0], [0.5, 0.5, 0.5])         self.translation_matrix = numpy.identity(4)         self.scaling_matrix = numpy.identity(4)         self.selected = False      def render(self):         &quot;&quot;&quot; renders the item to the screen &quot;&quot;&quot;         glPushMatrix()         glMultMatrixf(numpy.transpose(self.translation_matrix))         glMultMatrixf(self.scaling_matrix)         cur_color = color.COLORS[self.color_index]         glColor3f(cur_color[0], cur_color[1], cur_color[2])         if self.selected:  # emit light if the node is selected             glMaterialfv(GL_FRONT, GL_EMISSION, [0.3, 0.3, 0.3])          self.render_self()          if self.selected:             glMaterialfv(GL_FRONT, GL_EMISSION, [0.0, 0.0, 0.0])         glPopMatrix()      def render_self(self):         raise NotImplementedError(             &quot;The Abstract Node Class doesn't define 'render_self'&quot;)  class Primitive(Node):     def __init__(self):         super(Primitive, self).__init__()         self.call_list = None      def render_self(self):         glCallList(self.call_list)   class Sphere(Primitive):     &quot;&quot;&quot; Sphere primitive &quot;&quot;&quot;     def __init__(self):         super(Sphere, self).__init__()         self.call_list = G_OBJ_SPHERE   class Cube(Primitive):     &quot;&quot;&quot; Cube primitive &quot;&quot;&quot;     def __init__(self):         super(Cube, self).__init__()         self.call_list = G_OBJ_CUBE<\/code><\/pre>\n<p>  \u0420\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433 \u0443\u0437\u043b\u043e\u0432 \u043e\u0441\u043d\u043e\u0432\u0430\u043d \u043d\u0430 \u043c\u0430\u0442\u0440\u0438\u0446\u0430\u0445 \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u0439, \u0445\u0440\u0430\u043d\u044f\u0449\u0438\u0445\u0441\u044f \u0432 \u043a\u0430\u0436\u0434\u043e\u043c \u0438\u0437 \u0443\u0437\u043b\u043e\u0432. \u041c\u0430\u0442\u0440\u0438\u0446\u0430 \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u0439 \u0443\u0437\u043b\u0430 \u2014 \u044d\u0442\u043e \u0441\u043e\u0447\u0435\u0442\u0430\u043d\u0438\u0435 \u0435\u0433\u043e \u043c\u0430\u0442\u0440\u0438\u0446\u044b \u043c\u0430\u0441\u0448\u0442\u0430\u0431\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0438 \u043c\u0430\u0442\u0440\u0438\u0446\u044b \u043f\u0435\u0440\u0435\u043c\u0435\u0449\u0435\u043d\u0438\u044f. \u0412\u043d\u0435 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043e\u0442 \u0442\u0438\u043f\u0430 \u0443\u0437\u043b\u0430, \u043f\u0435\u0440\u0432\u044b\u043c \u044d\u0442\u0430\u043f\u043e\u043c \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433\u0430 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0437\u0430\u0434\u0430\u043d\u0438\u0435 \u043c\u0430\u0442\u0440\u0438\u0446\u0435 ModelView \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430 OpenGL \u043c\u0430\u0442\u0440\u0438\u0446\u044b \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u0439, \u0447\u0442\u043e\u0431\u044b \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u044c \u043f\u0435\u0440\u0435\u0445\u043e\u0434 \u043e\u0442 \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u043d\u043e\u0433\u043e \u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u0430 \u043c\u043e\u0434\u0435\u043b\u0438 \u043a \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u043d\u043e\u043c\u0443 \u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u0443 \u043e\u043a\u043d\u0430 \u043f\u0440\u043e\u0441\u043c\u043e\u0442\u0440\u0430. \u041f\u043e\u0441\u043b\u0435 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f \u043c\u0430\u0442\u0440\u0438\u0446 OpenGL \u043c\u044b \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u043c <code>render_self<\/code>, \u0447\u0442\u043e\u0431\u044b \u043f\u0440\u0438\u043a\u0430\u0437\u0430\u0442\u044c \u0443\u0437\u043b\u0443 \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u044c \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b\u0435 \u0432\u044b\u0437\u043e\u0432\u044b OpenGL \u0434\u043b\u044f \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u043a\u0438 \u0441\u0435\u0431\u044f. \u0417\u0430\u0442\u0435\u043c \u043c\u044b \u043e\u0442\u043c\u0435\u043d\u044f\u0435\u043c \u0432\u0441\u0435 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f, \u0432\u043d\u0435\u0441\u0451\u043d\u043d\u044b\u0435 \u0432 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 OpenGL \u044d\u0442\u043e\u0433\u043e \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e\u0433\u043e \u0443\u0437\u043b\u0430. \u041c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u0438 OpenGL <code>glPushMatrix<\/code> \u0438 <code>glPopMatrix<\/code> \u0434\u043b\u044f \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u0438 \u0432\u043e\u0441\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u043c\u0430\u0442\u0440\u0438\u0446\u044b ModelView \u0434\u043e \u0438 \u043f\u043e\u0441\u043b\u0435 \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433\u0430 \u0443\u0437\u043b\u0430. \u041e\u0431\u0440\u0430\u0442\u0438\u0442\u0435 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435, \u0447\u0442\u043e \u0443\u0437\u0435\u043b \u0445\u0440\u0430\u043d\u0438\u0442 \u0441\u0432\u043e\u0439 \u0446\u0432\u0435\u0442, \u0440\u0430\u0441\u043f\u043e\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0438 \u043c\u0430\u0441\u0448\u0442\u0430\u0431, \u043f\u0440\u0438\u043c\u0435\u043d\u044f\u044f \u0438\u0445 \u043a \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044e OpenGL \u043f\u0435\u0440\u0435\u0434 \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433\u043e\u043c.<\/p>\n<p>  \u0415\u0441\u043b\u0438 \u0443\u0437\u0435\u043b \u0432 \u0434\u0430\u043d\u043d\u044b\u0439 \u043c\u043e\u043c\u0435\u043d\u0442 \u0432\u044b\u0434\u0435\u043b\u0435\u043d, \u043c\u044b \u0437\u0430\u0441\u0442\u0430\u0432\u0438\u043c \u0435\u0433\u043e \u0438\u0437\u043b\u0443\u0447\u0430\u0442\u044c \u0441\u0432\u0435\u0442. \u0411\u043b\u0430\u0433\u043e\u0434\u0430\u0440\u044f \u044d\u0442\u043e\u043c\u0443 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u0431\u0443\u0434\u0435\u0442 \u0432\u0438\u0434\u0435\u0442\u044c, \u043a\u0430\u043a\u043e\u0439 \u0443\u0437\u0435\u043b \u0432\u044b\u0431\u0440\u0430\u043d.<\/p>\n<p>  \u0414\u043b\u044f \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433\u0430 \u043f\u0440\u0438\u043c\u0438\u0442\u0438\u0432\u043e\u0432 \u043c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u044e OpenGL \u0441\u043f\u0438\u0441\u043a\u043e\u0432 \u0432\u044b\u0437\u043e\u0432\u043e\u0432. \u0421\u043f\u0438\u0441\u043e\u043a \u0432\u044b\u0437\u043e\u0432\u043e\u0432 OpenGL \u2014 \u044d\u0442\u043e \u043d\u0430\u0431\u043e\u0440 \u0432\u044b\u0437\u043e\u0432\u043e\u0432 OpenGL, \u0437\u0430\u0434\u0430\u043d\u043d\u044b\u0445 \u0438 \u043e\u0431\u044a\u0435\u0434\u0438\u043d\u0451\u043d\u043d\u044b\u0445 \u043f\u043e\u0434 \u043e\u0434\u043d\u0438\u043c \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435\u043c. \u0412\u044b\u0437\u043e\u0432\u044b \u043c\u043e\u0433\u0443\u0442 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0442\u044c\u0441\u044f \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e <code>glCallList(LIST_NAME)<\/code>. \u041a\u0430\u0436\u0434\u044b\u0439 \u043f\u0440\u0438\u043c\u0438\u0442\u0438\u0432 (<code>Sphere<\/code> \u0438 <code>Cube<\/code>) \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u0442 \u0441\u043f\u0438\u0441\u043e\u043a \u0432\u044b\u0437\u043e\u0432\u043e\u0432, \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b\u0439 \u0434\u043b\u044f \u0435\u0433\u043e \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433\u0430 (\u043d\u0435 \u043f\u043e\u043a\u0430\u0437\u0430\u043d).<\/p>\n<p>  \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0441\u043f\u0438\u0441\u043e\u043a \u0432\u044b\u0437\u043e\u0432\u043e\u0432 \u043a\u0443\u0431\u0430 \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u044b\u0432\u0430\u0435\u0442 6 \u0433\u0440\u0430\u043d\u0435\u0439 \u043a\u0443\u0431\u0430 \u0441 \u0446\u0435\u043d\u0442\u0440\u043e\u043c \u0432 \u0442\u043e\u0447\u043a\u0435 \u043d\u0430\u0447\u0430\u043b\u0430 \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442 \u0438 \u0441 \u0440\u0451\u0431\u0440\u0430\u043c\u0438 \u0434\u043b\u0438\u043d\u043e\u0439 \u0440\u043e\u0432\u043d\u043e 1 \u0435\u0434\u0438\u043d\u0438\u0446\u0443.<\/p>\n<pre><code class=\"python\"># Pseudocode Cube definition # Left face ((-0.5, -0.5, -0.5), (-0.5, -0.5, 0.5), (-0.5, 0.5, 0.5), (-0.5, 0.5, -0.5)), # Back face ((-0.5, -0.5, -0.5), (-0.5, 0.5, -0.5), (0.5, 0.5, -0.5), (0.5, -0.5, -0.5)), # Right face ((0.5, -0.5, -0.5), (0.5, 0.5, -0.5), (0.5, 0.5, 0.5), (0.5, -0.5, 0.5)), # Front face ((-0.5, -0.5, 0.5), (0.5, -0.5, 0.5), (0.5, 0.5, 0.5), (-0.5, 0.5, 0.5)), # Bottom face ((-0.5, -0.5, 0.5), (-0.5, -0.5, -0.5), (0.5, -0.5, -0.5), (0.5, -0.5, 0.5)), # Top face ((-0.5, 0.5, -0.5), (-0.5, 0.5, 0.5), (0.5, 0.5, 0.5), (0.5, 0.5, -0.5))<\/code><\/pre>\n<p>  \u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u0438\u0441\u043a\u043b\u044e\u0447\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u043f\u0440\u0438\u043c\u0438\u0442\u0438\u0432\u043e\u0432 \u0441\u0438\u043b\u044c\u043d\u043e \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0438\u0432\u0430\u0435\u0442 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438 \u043c\u043e\u0434\u0435\u043b\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f. 3D-\u043c\u043e\u0434\u0435\u043b\u0438 \u043e\u0431\u044b\u0447\u043d\u043e \u0441\u043e\u0441\u0442\u043e\u044f\u0442 \u0438\u0437 \u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u0430 \u043f\u0440\u0438\u043c\u0438\u0442\u0438\u0432\u043e\u0432 (\u0438\u043b\u0438 \u0442\u0440\u0435\u0443\u0433\u043e\u043b\u044c\u043d\u044b\u0445 \u043c\u0435\u0448\u0435\u0439, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043c\u044b \u0437\u0434\u0435\u0441\u044c \u0440\u0430\u0441\u0441\u043c\u0430\u0442\u0440\u0438\u0432\u0430\u0442\u044c \u043d\u0435 \u0431\u0443\u0434\u0435\u043c). \u041a \u0441\u0447\u0430\u0441\u0442\u044c\u044e, \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 \u043a\u043b\u0430\u0441\u0441\u0430 <code>Node<\/code> \u0443\u043f\u0440\u043e\u0449\u0430\u0435\u0442 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u0443\u0437\u043b\u043e\u0432 <code>Scene<\/code>, \u0441\u043e\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u043d\u044b\u0445 \u0438\u0437 \u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0445 \u043f\u0440\u0438\u043c\u0438\u0442\u0438\u0432\u043e\u0432. \u041d\u0430 \u0441\u0430\u043c\u043e\u043c \u0434\u0435\u043b\u0435, \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u043e\u0431\u0435\u0441\u043f\u0435\u0447\u0438\u0442\u044c \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0443 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u043b\u044c\u043d\u043e\u0439 \u0433\u0440\u0443\u043f\u043f\u0438\u0440\u043e\u0432\u043a\u0438 \u0443\u0437\u043b\u043e\u0432 \u0431\u0435\u0437 \u043f\u043e\u0432\u044b\u0448\u0435\u043d\u0438\u044f \u0441\u043b\u043e\u0436\u043d\u043e\u0441\u0442\u0438 \u043a\u043e\u0434\u0430.<\/p>\n<p>  \u0412 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a\u0430 \u043c\u043e\u0442\u0438\u0432\u0430\u0446\u0438\u0438 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u0438\u043c \u043e\u0447\u0435\u043d\u044c \u043f\u0440\u043e\u0441\u0442\u0443\u044e \u0444\u0438\u0433\u0443\u0440\u0443: \u043e\u0431\u044b\u0447\u043d\u043e\u0433\u043e \u0441\u043d\u0435\u0433\u043e\u0432\u0438\u043a\u0430, \u0441\u043e\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u043d\u043e\u0433\u043e \u0438\u0437 \u0442\u0440\u0451\u0445 \u0441\u0444\u0435\u0440. \u0414\u0430\u0436\u0435 \u043d\u0435\u0441\u043c\u043e\u0442\u0440\u044f \u043d\u0430 \u0442\u043e, \u0447\u0442\u043e \u0444\u0438\u0433\u0443\u0440\u0430 \u0441\u043e\u0441\u0442\u043e\u0438\u0442 \u0438\u0437 \u0442\u0440\u0451\u0445 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0445 \u043f\u0440\u0438\u043c\u0438\u0442\u0438\u0432\u043e\u0432, \u043c\u044b \u0445\u043e\u0442\u0435\u043b\u0438 \u0431\u044b \u0438\u043c\u0435\u0442\u044c \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0441 \u043d\u0435\u0439 \u043a\u0430\u043a \u0441 \u0435\u0434\u0438\u043d\u044b\u043c \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u043c.<\/p>\n<p>  \u041c\u044b \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u043a\u043b\u0430\u0441\u0441 <code>HierarchicalNode<\/code>, \u0442\u043e \u0435\u0441\u0442\u044c <code>Node<\/code>, \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0449\u0438\u0439 \u0434\u0440\u0443\u0433\u0438\u0435 \u0443\u0437\u043b\u044b. \u041e\u043d \u0443\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442 \u0441\u043f\u0438\u0441\u043a\u043e\u043c \u00ab\u0434\u043e\u0447\u0435\u0440\u043d\u0438\u0445 \u0443\u0437\u043b\u043e\u0432\u00bb. \u0424\u0443\u043d\u043a\u0446\u0438\u044f <code>render_self<\/code> \u0434\u043b\u044f \u0438\u0435\u0440\u0430\u0440\u0445\u0438\u0447\u0435\u0441\u043a\u0438\u0445 \u0443\u0437\u043b\u043e\u0432 \u043f\u0440\u043e\u0441\u0442\u043e \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442 <code>render_self<\/code> \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0438\u0437 \u0434\u043e\u0447\u0435\u0440\u043d\u0438\u0445 \u0443\u0437\u043b\u043e\u0432. \u041f\u0440\u0438 \u043f\u043e\u043c\u043e\u0449\u0438 \u043a\u043b\u0430\u0441\u0441\u0430 <code>HierarchicalNode<\/code> \u043e\u0447\u0435\u043d\u044c \u043b\u0435\u0433\u043a\u043e \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0442\u044c \u0432 \u0441\u0446\u0435\u043d\u0443 \u0444\u0438\u0433\u0443\u0440\u044b. \u0422\u0435\u043f\u0435\u0440\u044c \u0434\u043b\u044f \u0437\u0430\u0434\u0430\u043d\u0438\u044f \u0441\u043d\u0435\u0433\u043e\u0432\u0438\u043a\u0430 \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0443\u043a\u0430\u0437\u0430\u0442\u044c \u0441\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u044e\u0449\u0438\u0435 \u0435\u0433\u043e \u0444\u0438\u0433\u0443\u0440\u044b, \u0430 \u0442\u0430\u043a\u0436\u0435 \u0438\u0445 \u043e\u0442\u043d\u043e\u0441\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u043f\u043e\u0437\u0438\u0446\u0438\u0438 \u0438 \u0440\u0430\u0437\u043c\u0435\u0440\u044b.<\/p>\n<div style=\"text-align:center;\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/post_images\/b8d\/cfc\/431\/b8dcfc4313a97594f3b93c37779060a5.jpg\"><\/div>\n<p>  <i>\u0420\u0438\u0441\u0443\u043d\u043e\u043a 2 \u2014 \u0418\u0435\u0440\u0430\u0440\u0445\u0438\u044f \u043f\u043e\u0434\u043a\u043b\u0430\u0441\u0441\u043e\u0432 <code>Node<\/code><\/i><\/p>\n<pre><code class=\"python\">class HierarchicalNode(Node):     def __init__(self):         super(HierarchicalNode, self).__init__()         self.child_nodes = []      def render_self(self):         for child in self.child_nodes:             child.render()<\/code><\/pre>\n<p>  <\/p>\n<pre><code class=\"python\">class SnowFigure(HierarchicalNode):     def __init__(self):         super(SnowFigure, self).__init__()         self.child_nodes = [Sphere(), Sphere(), Sphere()]         self.child_nodes[0].translate(0, -0.6, 0) # scale 1.0         self.child_nodes[1].translate(0, 0.1, 0)         self.child_nodes[1].scaling_matrix = numpy.dot(             self.scaling_matrix, scaling([0.8, 0.8, 0.8]))         self.child_nodes[2].translate(0, 0.75, 0)         self.child_nodes[2].scaling_matrix = numpy.dot(             self.scaling_matrix, scaling([0.7, 0.7, 0.7]))         for child_node in self.child_nodes:             child_node.color_index = color.MIN_COLOR         self.aabb = AABB([0.0, 0.0, 0.0], [0.5, 1.1, 0.5])<\/code><\/pre>\n<p>  \u0412\u044b \u043c\u043e\u0433\u043b\u0438 \u0437\u0430\u043c\u0435\u0442\u0438\u0442\u044c, \u0447\u0442\u043e \u043e\u0431\u044a\u0435\u043a\u0442\u044b <code>Node<\/code> \u043e\u0431\u0440\u0430\u0437\u0443\u044e\u0442 \u0434\u0440\u0435\u0432\u043e\u0432\u0438\u0434\u043d\u0443\u044e \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443 \u0434\u0430\u043d\u043d\u044b\u0445. \u0424\u0443\u043d\u043a\u0446\u0438\u044f <code>render<\/code>, \u043f\u0440\u043e\u0445\u043e\u0434\u044f\u0449\u0430\u044f \u0438\u0435\u0440\u0430\u0440\u0445\u0438\u0447\u0435\u0441\u043a\u0438\u0435 \u0443\u0437\u043b\u044b, \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442 \u043e\u0431\u0445\u043e\u0434 \u0432 \u0433\u043b\u0443\u0431\u0438\u043d\u0443 \u043f\u043e \u0434\u0435\u0440\u0435\u0432\u0443. \u041f\u0440\u0438 \u043e\u0431\u0445\u043e\u0434\u0435 \u043e\u043d\u0430 \u0445\u0440\u0430\u043d\u0438\u0442 \u0441\u0442\u0435\u043a \u043c\u0430\u0442\u0440\u0438\u0446 <code>ModelView<\/code>, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u044b\u0445 \u0434\u043b\u044f \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u0432 \u043c\u0438\u0440\u043e\u0432\u043e\u0435 \u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u043e. \u041d\u0430 \u043a\u0430\u0436\u0434\u043e\u043c \u0448\u0430\u0433\u0435 \u043e\u043d\u0430 \u0437\u0430\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u0442 \u0432 \u0441\u0442\u0435\u043a \u0442\u0435\u043a\u0443\u0449\u0443\u044e \u043c\u0430\u0442\u0440\u0438\u0446\u0443 <code>ModelView<\/code>, \u0430 \u043a\u043e\u0433\u0434\u0430 \u0437\u0430\u0432\u0435\u0440\u0448\u0430\u0435\u0442 \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433 \u0432\u0441\u0435\u0445 \u0434\u043e\u0447\u0435\u0440\u043d\u0438\u0445 \u0443\u0437\u043b\u043e\u0432, \u043e\u043d\u0430 \u0438\u0437\u0432\u043b\u0435\u043a\u0430\u0435\u0442 \u043c\u0430\u0442\u0440\u0438\u0446\u0443 \u0438\u0437 \u0441\u0442\u0435\u043a\u0430, \u043e\u0441\u0442\u0430\u0432\u043b\u044f\u044f \u043d\u0430 \u0432\u0435\u0440\u0448\u0438\u043d\u0435 \u0441\u0442\u0435\u043a\u0430 \u043c\u0430\u0442\u0440\u0438\u0446\u0443 <code>ModelView<\/code> \u0440\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u0441\u043a\u043e\u0433\u043e \u0443\u0437\u043b\u0430.<\/p>\n<p>  \u0411\u043b\u0430\u0433\u043e\u0434\u0430\u0440\u044f \u0442\u043e\u043c\u0443, \u0447\u0442\u043e \u043c\u044b \u0441\u0434\u0435\u043b\u0430\u043b\u0438 \u043a\u043b\u0430\u0441\u0441 <code>Node<\/code> \u0440\u0430\u0441\u0448\u0438\u0440\u044f\u0435\u043c\u044b\u043c, \u043c\u043e\u0436\u043d\u043e \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0442\u044c \u0432 \u0441\u0446\u0435\u043d\u0443 \u043d\u043e\u0432\u044b\u0435 \u0442\u0438\u043f\u044b \u0444\u0438\u0433\u0443\u0440, \u043d\u0435 \u043c\u0435\u043d\u044f\u044f \u0432\u0435\u0441\u044c \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u043e\u0439 \u043a\u043e\u0434 \u043c\u0430\u043d\u0438\u043f\u0443\u043b\u044f\u0446\u0438\u0439 \u0441\u0446\u0435\u043d\u043e\u0439 \u0438 \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433\u0430. \u0411\u043b\u0430\u0433\u043e\u0434\u0430\u0440\u044f \u043a\u043e\u043d\u0446\u0435\u043f\u0446\u0438\u0438 \u0443\u0437\u043b\u043e\u0432 \u043c\u044b \u0430\u0431\u0441\u0442\u0440\u0430\u0433\u0438\u0440\u0443\u0435\u043c\u0441\u044f \u043e\u0442 \u0442\u043e\u0433\u043e \u0444\u0430\u043a\u0442\u0430, \u0447\u0442\u043e \u043e\u0431\u044a\u0435\u043a\u0442 <code>Scene<\/code> \u043c\u043e\u0436\u0435\u0442 \u0438\u043c\u0435\u0442\u044c \u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u043e \u0434\u043e\u0447\u0435\u0440\u043d\u0438\u0445 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432. \u042d\u0442\u043e \u043d\u0430\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0448\u0430\u0431\u043b\u043e\u043d\u043e\u043c \u043f\u0440\u043e\u0435\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u00ab\u041a\u043e\u043c\u043f\u043e\u043d\u043e\u0432\u0449\u0438\u043a\u00bb.<\/p>\n<h3>\u0412\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0435 \u0441 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u043c<\/h3>\n<p>  \u0422\u0435\u043f\u0435\u0440\u044c, \u043a\u043e\u0433\u0434\u0430 \u043d\u0430\u0448\u0430 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0430 \u043c\u043e\u0434\u0435\u043b\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0441\u043f\u043e\u0441\u043e\u0431\u043d\u0430 \u0445\u0440\u0430\u043d\u0438\u0442\u044c \u0438 \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0430\u0442\u044c \u0441\u0446\u0435\u043d\u0443, \u043d\u0430\u043c \u043d\u0443\u0436\u0435\u043d \u0441\u043f\u043e\u0441\u043e\u0431 \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f \u0441 \u043d\u0435\u0439. \u041d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u0443\u043f\u0440\u043e\u0441\u0442\u0438\u0442\u044c \u0434\u0432\u0430 \u0432\u0438\u0434\u0430 \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0439. \u0412\u043e-\u043f\u0435\u0440\u0432\u044b\u0445, \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u0430 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u043f\u0435\u0440\u0441\u043f\u0435\u043a\u0442\u0438\u0432\u044b \u043e\u0431\u0437\u043e\u0440\u0430 \u0441\u0446\u0435\u043d\u044b. \u041c\u044b \u0445\u043e\u0442\u0438\u043c \u0438\u043c\u0435\u0442\u044c \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0434\u0432\u0438\u0433\u0430\u0442\u044c \u0433\u043b\u0430\u0437 (\u043a\u0430\u043c\u0435\u0440\u0443) \u043f\u043e \u0441\u0446\u0435\u043d\u0435. \u0412\u043e-\u0432\u0442\u043e\u0440\u044b\u0445, \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u0430 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u043d\u043e\u0432\u044b\u0445 \u0443\u0437\u043b\u043e\u0432 \u0438 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u0443\u0437\u043b\u043e\u0432 \u0432 \u0441\u0446\u0435\u043d\u0435.<\/p>\n<p>  \u0414\u043b\u044f \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f \u0441 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u043c \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u0437\u043d\u0430\u0442\u044c, \u043a\u043e\u0433\u0434\u0430 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043d\u0430\u0436\u0438\u043c\u0430\u0435\u0442 \u043a\u043b\u0430\u0432\u0438\u0448\u0438 \u0438\u043b\u0438 \u0434\u0432\u0438\u0433\u0430\u0435\u0442 \u043c\u044b\u0448\u044c. \u041a \u0441\u0447\u0430\u0441\u0442\u044c\u044e, \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u043e\u043d\u043d\u0430\u044f \u0441\u0438\u0441\u0442\u0435\u043c\u0430 \u0437\u043d\u0430\u0435\u0442, \u043a\u043e\u0433\u0434\u0430 \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u044f\u0442 \u044d\u0442\u0438 \u0441\u043e\u0431\u044b\u0442\u0438\u044f. GLUT \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043d\u0430\u043c \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0444\u0443\u043d\u043a\u0446\u0438\u044e, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u0437\u044b\u0432\u0430\u0442\u044c\u0441\u044f \u043f\u0440\u0438 \u0441\u043e\u0432\u0435\u0440\u0448\u0435\u043d\u0438\u0438 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0451\u043d\u043d\u043e\u0433\u043e \u0441\u043e\u0431\u044b\u0442\u0438\u044f. \u041c\u044b \u043d\u0430\u043f\u0438\u0448\u0435\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0434\u043b\u044f \u0438\u043d\u0442\u0435\u0440\u043f\u0440\u0435\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u043d\u0430\u0436\u0430\u0442\u0438\u0439 \u043a\u043b\u0430\u0432\u0438\u0448 \u0438 \u0434\u0432\u0438\u0436\u0435\u043d\u0438\u044f \u043c\u044b\u0448\u0438, \u0430 \u0437\u0430\u0442\u0435\u043c \u043f\u0440\u0438\u043a\u0430\u0436\u0435\u043c GLUT \u0432\u044b\u0437\u044b\u0432\u0430\u0442\u044c \u044d\u0442\u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u043f\u0440\u0438 \u043d\u0430\u0436\u0430\u0442\u0438\u0438 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0445 \u043a\u043b\u0430\u0432\u0438\u0448. \u0423\u0437\u043d\u0430\u0432, \u043a\u0430\u043a\u0438\u0435 \u043a\u043b\u0430\u0432\u0438\u0448\u0438 \u043d\u0430\u0436\u0438\u043c\u0430\u0435\u0442 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c, \u043c\u044b \u0434\u043e\u043b\u0436\u043d\u044b \u0431\u0443\u0434\u0435\u043c \u0438\u043d\u0442\u0435\u0440\u043f\u0440\u0435\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0432\u0432\u043e\u0434 \u0438 \u043f\u0440\u0438\u043c\u0435\u043d\u0438\u0442\u044c \u043a \u0441\u0446\u0435\u043d\u0435 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0435 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f.<\/p>\n<p>  \u041b\u043e\u0433\u0438\u043a\u0430 \u043f\u0440\u043e\u0441\u043b\u0443\u0448\u0438\u0432\u0430\u043d\u0438\u044f \u0441\u043e\u0431\u044b\u0442\u0438\u0439 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u043e\u043d\u043d\u043e\u0439 \u0441\u0438\u0441\u0442\u0435\u043c\u044b \u0438 \u0438\u043d\u0442\u0435\u0440\u043f\u0440\u0435\u0442\u0430\u0446\u0438\u0438 \u0438\u0445 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u0432 \u043a\u043b\u0430\u0441\u0441\u0435 <code>Interaction<\/code>. \u041d\u0430\u043f\u0438\u0441\u0430\u043d\u043d\u044b\u0439 \u043d\u0430\u043c\u0438 \u0440\u0430\u043d\u0435\u0435 \u043a\u043b\u0430\u0441\u0441 <code>Viewer<\/code> \u0432\u043b\u0430\u0434\u0435\u0435\u0442 \u0435\u0434\u0438\u043d\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u043c \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440\u043e\u043c <code>Interaction<\/code>. \u041c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u043c\u0435\u0445\u0430\u043d\u0438\u0437\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u0439 \u043e\u0431\u0440\u0430\u0442\u043d\u043e\u0433\u043e \u0432\u044b\u0437\u043e\u0432\u0430 GLUT \u0434\u043b\u044f \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0430\u0446\u0438\u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u0439, \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u043c\u044b\u0445 \u043f\u0440\u0438 \u043d\u0430\u0436\u0430\u0442\u0438\u0438 \u043a\u043b\u0430\u0432\u0438\u0448\u0438 \u043c\u044b\u0448\u0438 (<code>glutMouseFunc<\/code>), \u043f\u0440\u0438 \u043f\u0435\u0440\u0435\u043c\u0435\u0449\u0435\u043d\u0438\u0438 \u043c\u044b\u0448\u0438 (<code>glutMotionFunc<\/code>), \u043f\u0440\u0438 \u043d\u0430\u0436\u0430\u0442\u0438\u0438 \u043a\u043b\u0430\u0432\u0438\u0448\u0438 \u043a\u043b\u0430\u0432\u0438\u0430\u0442\u0443\u0440\u044b (<code>glutKeyboardFunc<\/code>) \u0438 \u043f\u0440\u0438 \u043d\u0430\u0436\u0430\u0442\u0438\u0438 \u043a\u043b\u0430\u0432\u0438\u0448 \u0441\u043e \u0441\u0442\u0440\u0435\u043b\u043a\u0430\u043c\u0438 (<code>glutSpecialFunc<\/code>). \u0427\u0443\u0442\u044c \u043d\u0438\u0436\u0435 \u0432\u044b \u0443\u0432\u0438\u0434\u0438\u0442\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438, \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u044e\u0449\u0438\u0435 \u0441\u043e\u0431\u044b\u0442\u0438\u044f \u0432\u0432\u043e\u0434\u0430.<\/p>\n<pre><code class=\"python\">class Interaction(object):     def __init__(self):         &quot;&quot;&quot; Handles user interaction &quot;&quot;&quot;         # currently pressed mouse button         self.pressed = None         # the current location of the camera         self.translation = [0, 0, 0, 0]         # the trackball to calculate rotation         self.trackball = trackball.Trackball(theta = -25, distance=15)         # the current mouse location         self.mouse_loc = None         # Unsophisticated callback mechanism         self.callbacks = defaultdict(list)          self.register()      def register(self):         &quot;&quot;&quot; register callbacks with glut &quot;&quot;&quot;         glutMouseFunc(self.handle_mouse_button)         glutMotionFunc(self.handle_mouse_move)         glutKeyboardFunc(self.handle_keystroke)         glutSpecialFunc(self.handle_keystroke)<\/code><\/pre>\n<p>  <\/p>\n<h4>\u0424\u0443\u043d\u043a\u0446\u0438\u0438 \u043e\u0431\u0440\u0430\u0442\u043d\u043e\u0433\u043e \u0432\u044b\u0437\u043e\u0432\u0430 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u043e\u043d\u043d\u043e\u0439 \u0441\u0438\u0441\u0442\u0435\u043c\u044b<\/h4>\n<p>  \u0414\u043b\u044f \u043e\u0441\u043c\u044b\u0441\u043b\u0435\u043d\u043d\u043e\u0433\u043e \u0438\u043d\u0442\u0435\u0440\u043f\u0440\u0435\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u0441\u043a\u043e\u0433\u043e \u0432\u0432\u043e\u0434\u0430 \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u0441\u043a\u043e\u043c\u0431\u0438\u043d\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0437\u043d\u0430\u043d\u0438\u0435 \u043e \u043f\u043e\u0437\u0438\u0446\u0438\u0438 \u043c\u044b\u0448\u0438, \u043a\u043b\u0430\u0432\u0438\u0448\u0430\u0445 \u043c\u044b\u0448\u0438 \u0438 \u043a\u043b\u0430\u0432\u0438\u0430\u0442\u0443\u0440\u0435. \u041f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u0434\u043b\u044f \u0438\u043d\u0442\u0435\u0440\u043f\u0440\u0435\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0432\u0432\u043e\u0434\u0430 \u0432 \u043e\u0441\u043c\u044b\u0441\u043b\u0435\u043d\u043d\u044b\u0435 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f \u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u043c\u043d\u043e\u0433\u043e \u0441\u0442\u0440\u043e\u043a \u043a\u043e\u0434\u0430, \u043c\u044b \u0438\u043d\u043a\u0430\u043f\u0441\u0443\u043b\u0438\u0440\u0443\u0435\u043c \u0435\u0433\u043e \u0432 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0439 \u043a\u043b\u0430\u0441\u0441, \u043e\u0442\u0434\u0430\u043b\u0451\u043d\u043d\u044b\u0439 \u043e\u0442 \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u0433\u043e \u043f\u0443\u0442\u0438 \u0438\u0441\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u043a\u043e\u0434\u0430. \u041a\u043b\u0430\u0441\u0441 <code>Interaction<\/code> \u0441\u043a\u0440\u044b\u0432\u0430\u0435\u0442 \u043d\u0435\u043d\u0443\u0436\u043d\u0443\u044e \u0441\u043b\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u043e\u0442 \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u043e\u0439 \u0447\u0430\u0441\u0442\u0438 \u043a\u043e\u0434\u043e\u0432\u043e\u0439 \u0431\u0430\u0437\u044b \u0438 \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u0443\u0435\u0442 \u0441\u043e\u0431\u044b\u0442\u0438\u044f \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u043e\u043d\u043d\u043e\u0439 \u0441\u0438\u0441\u0442\u0435\u043c\u044b \u0432 \u0441\u043e\u0431\u044b\u0442\u0438\u044f \u0443\u0440\u043e\u0432\u043d\u044f \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f.<\/p>\n<pre><code class=\"python\">    # class Interaction      def translate(self, x, y, z):         &quot;&quot;&quot; translate the camera &quot;&quot;&quot;         self.translation[0] += x         self.translation[1] += y         self.translation[2] += z      def handle_mouse_button(self, button, mode, x, y):         &quot;&quot;&quot; Called when the mouse button is pressed or released &quot;&quot;&quot;         xSize, ySize = glutGet(GLUT_WINDOW_WIDTH), glutGet(GLUT_WINDOW_HEIGHT)         y = ySize - y  # invert the y coordinate because OpenGL is inverted         self.mouse_loc = (x, y)          if mode == GLUT_DOWN:             self.pressed = button             if button == GLUT_RIGHT_BUTTON:                 pass             elif button == GLUT_LEFT_BUTTON:  # pick                 self.trigger('pick', x, y)             elif button == 3:  # scroll up                 self.translate(0, 0, 1.0)             elif button == 4:  # scroll up                 self.translate(0, 0, -1.0)         else:  # mouse button release             self.pressed = None         glutPostRedisplay()      def handle_mouse_move(self, x, screen_y):         &quot;&quot;&quot; Called when the mouse is moved &quot;&quot;&quot;         xSize, ySize = glutGet(GLUT_WINDOW_WIDTH), glutGet(GLUT_WINDOW_HEIGHT)         y = ySize - screen_y  # invert the y coordinate because OpenGL is inverted         if self.pressed is not None:             dx = x - self.mouse_loc[0]             dy = y - self.mouse_loc[1]             if self.pressed == GLUT_RIGHT_BUTTON and self.trackball is not None:                 # ignore the updated camera loc because we want to always                 # rotate around the origin                 self.trackball.drag_to(self.mouse_loc[0], self.mouse_loc[1], dx, dy)             elif self.pressed == GLUT_LEFT_BUTTON:                 self.trigger('move', x, y)             elif self.pressed == GLUT_MIDDLE_BUTTON:                 self.translate(dx\/60.0, dy\/60.0, 0)             else:                 pass             glutPostRedisplay()         self.mouse_loc = (x, y)      def handle_keystroke(self, key, x, screen_y):         &quot;&quot;&quot; Called on keyboard input from the user &quot;&quot;&quot;         xSize, ySize = glutGet(GLUT_WINDOW_WIDTH), glutGet(GLUT_WINDOW_HEIGHT)         y = ySize - screen_y         if key == 's':             self.trigger('place', 'sphere', x, y)         elif key == 'c':             self.trigger('place', 'cube', x, y)         elif key == GLUT_KEY_UP:             self.trigger('scale', up=True)         elif key == GLUT_KEY_DOWN:             self.trigger('scale', up=False)         elif key == GLUT_KEY_LEFT:             self.trigger('rotate_color', forward=True)         elif key == GLUT_KEY_RIGHT:             self.trigger('rotate_color', forward=False)         glutPostRedisplay()<\/code><\/pre>\n<p>  <\/p>\n<h4>\u0412\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u0438\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u043e\u0431\u0440\u0430\u0442\u043d\u043e\u0433\u043e \u0432\u044b\u0437\u043e\u0432\u0430<\/h4>\n<p>  \u0412 \u043f\u043e\u043a\u0430\u0437\u0430\u043d\u043d\u043e\u043c \u0432\u044b\u0448\u0435 \u0444\u0440\u0430\u0433\u043c\u0435\u043d\u0442\u0435 \u043a\u043e\u0434\u0430 \u043c\u043e\u0436\u043d\u043e \u0437\u0430\u043c\u0435\u0442\u0438\u0442\u044c, \u0447\u0442\u043e \u043a\u043e\u0433\u0434\u0430 \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440 <code>Interaction<\/code> \u0438\u043d\u0442\u0435\u0440\u043f\u0440\u0435\u0442\u0438\u0440\u0443\u0435\u0442 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0435 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f, \u043e\u043d \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442 <code>self.trigger<\/code> \u0441\u043e \u0441\u0442\u0440\u043e\u043a\u043e\u0439, \u043e\u043f\u0438\u0441\u044b\u0432\u0430\u044e\u0449\u0435\u0439 \u0442\u0438\u043f \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f. \u0424\u0443\u043d\u043a\u0446\u0438\u044f <code>trigger<\/code> \u0432 \u043a\u043b\u0430\u0441\u0441\u0435 <code>Interaction<\/code> \u2014 \u044d\u0442\u043e \u0447\u0430\u0441\u0442\u044c \u043f\u0440\u043e\u0441\u0442\u043e\u0439 \u0441\u0438\u0441\u0442\u0435\u043c\u044b \u043e\u0431\u0440\u0430\u0442\u043d\u044b\u0445 \u0432\u044b\u0437\u043e\u0432\u043e\u0432, \u043a\u043e\u0442\u043e\u0440\u0443\u044e \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0434\u043b\u044f \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0441\u043e\u0431\u044b\u0442\u0438\u0439 \u043d\u0430 \u0443\u0440\u043e\u0432\u043d\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f. \u0412\u0441\u043f\u043e\u043c\u043d\u0438\u043c, \u0447\u0442\u043e \u0444\u0443\u043d\u043a\u0446\u0438\u044f <code>init_interaction<\/code> \u0432 \u043a\u043b\u0430\u0441\u0441\u0435 <code>Viewer<\/code> \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u0443\u0435\u0442 \u043e\u0431\u0440\u0430\u0442\u043d\u044b\u0435 \u0432\u044b\u0437\u043e\u0432\u044b \u0432 \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440\u0435 <code>Interaction<\/code>, \u0432\u044b\u0437\u044b\u0432\u0430\u044f <code>register_callback<\/code>.<\/p>\n<pre><code class=\"python\">    # class Interaction     def register_callback(self, name, func):         self.callbacks[name].append(func)<\/code><\/pre>\n<p>  \u041a\u043e\u0433\u0434\u0430 \u043a\u043e\u0434\u0443 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u043d\u0443\u0436\u043d\u043e \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u0441\u043e\u0431\u044b\u0442\u0438\u0435 \u0432 \u0441\u0446\u0435\u043d\u0435, \u043a\u043b\u0430\u0441\u0441 <code>Interaction<\/code> \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442 \u0432\u0441\u0435 \u0441\u043e\u0445\u0440\u0430\u043d\u0451\u043d\u043d\u044b\u0435 \u043e\u0431\u0440\u0430\u0442\u043d\u044b\u0435 \u0432\u044b\u0437\u043e\u0432\u044b, \u0438\u043c\u0435\u044e\u0449\u0438\u0435\u0441\u044f \u0434\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0441\u043e\u0431\u044b\u0442\u0438\u044f:<\/p>\n<pre><code class=\"python\">    # class Interaction     def trigger(self, name, *args, **kwargs):         for func in self.callbacks[name]:             func(*args, **kwargs)<\/code><\/pre>\n<p>  \u042d\u0442\u0430 \u0441\u0438\u0441\u0442\u0435\u043c\u0430 \u043e\u0431\u0440\u0430\u0442\u043d\u044b\u0445 \u0432\u044b\u0437\u043e\u0432\u043e\u0432 \u0443\u0440\u043e\u0432\u043d\u044f \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0430\u0431\u0441\u0442\u0440\u0430\u0433\u0438\u0440\u0443\u0435\u0442 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0441\u0442\u044c \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u043e\u0439 \u0447\u0430\u0441\u0442\u0438 \u0441\u0438\u0441\u0442\u0435\u043c\u044b \u0437\u043d\u0430\u0442\u044c \u043e \u0432\u0432\u043e\u0434\u0435 \u0432 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u043e\u043d\u043d\u043e\u0439 \u0441\u0438\u0441\u0442\u0435\u043c\u0435. \u041a\u0430\u0436\u0434\u044b\u0439 \u043e\u0431\u0440\u0430\u0442\u043d\u044b\u0439 \u0432\u044b\u0437\u043e\u0432 \u0443\u0440\u043e\u0432\u043d\u044f \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0441\u043e\u0431\u043e\u0439 \u0437\u043d\u0430\u0447\u0438\u043c\u044b\u0439 \u0437\u0430\u043f\u0440\u043e\u0441 \u0432 \u0440\u0430\u043c\u043a\u0430\u0445 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f. \u041a\u043b\u0430\u0441\u0441 <code>Interaction<\/code> \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u043a\u0430\u043a \u043f\u0435\u0440\u0435\u0432\u043e\u0434\u0447\u0438\u043a \u043c\u0435\u0436\u0434\u0443 \u0441\u043e\u0431\u044b\u0442\u0438\u044f\u043c\u0438 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u043e\u043d\u043d\u043e\u0439 \u0441\u0438\u0441\u0442\u0435\u043c\u044b \u0438 \u0441\u043e\u0431\u044b\u0442\u0438\u044f\u043c\u0438 \u0443\u0440\u043e\u0432\u043d\u044f \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f. \u042d\u0442\u043e \u043e\u0437\u043d\u0430\u0447\u0430\u0435\u0442, \u0447\u0442\u043e \u0435\u0441\u043b\u0438 \u0431\u044b \u043c\u044b \u0440\u0435\u0448\u0438\u043b\u0438 \u043f\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0443 \u043c\u043e\u0434\u0435\u043b\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u043d\u0430 \u0434\u0440\u0443\u0433\u043e\u0439 \u0442\u0443\u043b\u043a\u0438\u0442, \u043d\u0430\u043c \u0431\u044b \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0431\u044b\u043b\u043e \u0437\u0430\u043c\u0435\u043d\u0438\u0442\u044c \u043a\u043b\u0430\u0441\u0441 <code>Interaction<\/code> \u043d\u0430 \u043a\u043b\u0430\u0441\u0441, \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u0443\u044e\u0449\u0438\u0439 \u0432\u0432\u043e\u0434 \u0438\u0437 \u043d\u043e\u0432\u043e\u0433\u043e \u0442\u0443\u043b\u043a\u0438\u0442\u0430 \u0432 \u0442\u043e\u0442 \u0436\u0435 \u043d\u0430\u0431\u043e\u0440 \u0437\u043d\u0430\u0447\u0438\u043c\u044b\u0445 \u043e\u0431\u0440\u0430\u0442\u043d\u044b\u0445 \u0432\u044b\u0437\u043e\u0432\u043e\u0432 \u0443\u0440\u043e\u0432\u043d\u044f \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f. \u041c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u043e\u0431\u0440\u0430\u0442\u043d\u044b\u0435 \u0432\u044b\u0437\u043e\u0432\u044b \u0438 \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u044b \u0432 \u0422\u0430\u0431\u043b\u0438\u0446\u0435 1.<\/p>\n<div class=\"scrollable-table\">\n<table>\n<caption><b>\u0422\u0430\u0431\u043b\u0438\u0446\u0430 1<\/b> \u2014 \u043e\u0431\u0440\u0430\u0442\u043d\u044b\u0435 \u0432\u044b\u0437\u043e\u0432\u044b \u0438 \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u044b \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f<\/caption>\n<thead>\n<tr>\n<th align=\"left\">\u041e\u0431\u0440\u0430\u0442\u043d\u044b\u0439 \u0432\u044b\u0437\u043e\u0432<\/th>\n<th align=\"left\">\u0410\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u044b<\/th>\n<th align=\"left\">\u041f\u0440\u0435\u0434\u043d\u0430\u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td align=\"left\"><code>pick<\/code><\/td>\n<td align=\"left\">x:number, y:number<\/td>\n<td align=\"left\">\u0412\u044b\u0431\u0438\u0440\u0430\u0435\u0442 \u0443\u0437\u0435\u043b \u0432 \u0442\u043e\u0447\u043a\u0435 \u0440\u0430\u0441\u043f\u043e\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0443\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u044f \u043c\u044b\u0448\u0438.<\/td>\n<\/tr>\n<tr>\n<td align=\"left\"><code>move<\/code><\/td>\n<td align=\"left\">x:number, y:number<\/td>\n<td align=\"left\">\u041f\u0435\u0440\u0435\u043c\u0435\u0449\u0430\u0435\u0442 \u0442\u0435\u043a\u0443\u0449\u0438\u0439 \u0432\u044b\u0431\u0440\u0430\u043d\u043d\u044b\u0439 \u0443\u0437\u0435\u043b \u0432 \u0442\u043e\u0447\u043a\u0443 \u0440\u0430\u0441\u043f\u043e\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0443\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u044f \u043c\u044b\u0448\u0438.<\/td>\n<\/tr>\n<tr>\n<td align=\"left\"><code>place<\/code><\/td>\n<td align=\"left\">shape:string, x:number, y:number<\/td>\n<td align=\"left\">\u0420\u0430\u0437\u043c\u0435\u0449\u0430\u0435\u0442 \u0444\u0438\u0433\u0443\u0440\u0443 \u0443\u043a\u0430\u0437\u0430\u043d\u043d\u043e\u0433\u043e \u0442\u0438\u043f\u0430 \u0432 \u0442\u043e\u0447\u043a\u0443 \u0440\u0430\u0441\u043f\u043e\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0443\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u044f \u043c\u044b\u0448\u0438.<\/td>\n<\/tr>\n<tr>\n<td align=\"left\"><code>rotate_color<\/code><\/td>\n<td align=\"left\">forward:boolean<\/td>\n<td align=\"left\">\u0426\u0438\u043a\u043b\u0438\u0447\u0435\u0441\u043a\u0438 \u043c\u0435\u043d\u044f\u0435\u0442 \u0446\u0432\u0435\u0442 \u0442\u0435\u043a\u0443\u0449\u0435\u0433\u043e \u0432\u044b\u0431\u0440\u0430\u043d\u043d\u043e\u0433\u043e \u0443\u0437\u043b\u0430 \u0432\u043f\u0435\u0440\u0451\u0434 \u0438\u043b\u0438 \u043d\u0430\u0437\u0430\u0434 \u043f\u043e \u0441\u043f\u0438\u0441\u043a\u0443 \u0446\u0432\u0435\u0442\u043e\u0432.<\/td>\n<\/tr>\n<tr>\n<td align=\"left\"><code>scale<\/code><\/td>\n<td align=\"left\">up:boolean<\/td>\n<td align=\"left\">\u0423\u0432\u0435\u043b\u0438\u0447\u0438\u0432\u0430\u0435\u0442 \u0438\u043b\u0438 \u0443\u043c\u0435\u043d\u044c\u0448\u0430\u0435\u0442 \u043c\u0430\u0441\u0448\u0442\u0430\u0431 \u0442\u0435\u043a\u0443\u0449\u0435\u0433\u043e \u0432\u044b\u0431\u0440\u0430\u043d\u043d\u043e\u0433\u043e \u0443\u0437\u043b\u0430 \u0441\u043e\u0433\u043b\u0430\u0441\u043d\u043e \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0443.<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<p>  \u042d\u0442\u0430 \u043f\u0440\u043e\u0441\u0442\u0430\u044f \u0441\u0438\u0441\u0442\u0435\u043c\u0430 \u043e\u0431\u0440\u0430\u0442\u043d\u044b\u0445 \u0432\u044b\u0437\u043e\u0432\u043e\u0432 \u043e\u0431\u0435\u0441\u043f\u0435\u0447\u0438\u0432\u0430\u0435\u0442 \u0432\u0441\u044e \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u043e\u0441\u0442\u044c, \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u0443\u044e \u0434\u043b\u044f \u043d\u0430\u0448\u0435\u0439 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b. \u041e\u0434\u043d\u0430\u043a\u043e \u0432 \u0433\u043e\u0442\u043e\u0432\u043e\u043c 3D-\u0440\u0435\u0434\u0430\u043a\u0442\u043e\u0440\u0435 \u043e\u0431\u044a\u0435\u043a\u0442\u044b \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u0447\u0430\u0441\u0442\u043e \u0441\u043e\u0437\u0434\u0430\u044e\u0442\u0441\u044f \u0438 \u0443\u043d\u0438\u0447\u0442\u043e\u0436\u0430\u044e\u0442\u0441\u044f \u0434\u0438\u043d\u0430\u043c\u0438\u0447\u0435\u0441\u043a\u0438. \u0412 \u0442\u0430\u043a\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u043d\u0430\u043c \u043f\u043e\u0442\u0440\u0435\u0431\u043e\u0432\u0430\u043b\u0430\u0441\u044c \u0431\u044b \u0431\u043e\u043b\u0435\u0435 \u0441\u043b\u043e\u0436\u043d\u0430\u044f \u0441\u0438\u0441\u0442\u0435\u043c\u0430 \u043f\u0440\u043e\u0441\u043b\u0443\u0448\u0438\u0432\u0430\u043d\u0438\u044f \u0441\u043e\u0431\u044b\u0442\u0438\u0439, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u043e\u0431\u044a\u0435\u043a\u0442\u044b \u043c\u043e\u0433\u0443\u0442 \u0438 \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0438 \u043e\u0442\u043c\u0435\u043d\u044f\u0442\u044c \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0430\u0446\u0438\u044e \u043e\u0431\u0440\u0430\u0442\u043d\u044b\u0445 \u0432\u044b\u0437\u043e\u0432\u043e\u0432 \u0434\u043b\u044f \u0441\u043e\u0431\u044b\u0442\u0438\u0439.<\/p>\n<h3>\u0412\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0435 \u0441\u043e \u0441\u0446\u0435\u043d\u043e\u0439<\/h3>\n<p>  \u0411\u043b\u0430\u0433\u043e\u0434\u0430\u0440\u044f \u043c\u0435\u0445\u0430\u043d\u0438\u0437\u043c\u0443 \u043e\u0431\u0440\u0430\u0442\u043d\u044b\u0445 \u0432\u044b\u0437\u043e\u0432\u043e\u0432 \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u043f\u043e\u043b\u0443\u0447\u0430\u0442\u044c \u0437\u043d\u0430\u0447\u0438\u043c\u0443\u044e \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e \u043e \u0441\u043e\u0431\u044b\u0442\u0438\u044f\u0445 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u0441\u043a\u043e\u0433\u043e \u0432\u0432\u043e\u0434\u0430 \u043e\u0442 \u043a\u043b\u0430\u0441\u0441\u0430 <code>Interaction<\/code>. \u041c\u044b \u0433\u043e\u0442\u043e\u0432\u044b \u043a \u043f\u0440\u0438\u043c\u0435\u043d\u0435\u043d\u0438\u044e \u044d\u0442\u0438\u0445 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0439 \u043a <code>Scene<\/code>.<\/p>\n<h4>\u041f\u0435\u0440\u0435\u043c\u0435\u0449\u0435\u043d\u0438\u0435 \u0441\u0446\u0435\u043d\u044b<\/h4>\n<p>  \u0412 \u044d\u0442\u043e\u0439 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0435 \u043c\u044b \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u043c \u0434\u0432\u0438\u0436\u0435\u043d\u0438\u0435 \u043a\u0430\u043c\u0435\u0440\u044b \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c \u0441\u0446\u0435\u043d\u044b. \u0414\u0440\u0443\u0433\u0438\u043c\u0438 \u0441\u043b\u043e\u0432\u0430\u043c\u0438, \u043a\u0430\u043c\u0435\u0440\u0430 \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u043d\u0430 \u043e\u0434\u043d\u043e\u043c \u043c\u0435\u0441\u0442\u0435, \u0430 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u0441\u043a\u0438\u0439 \u0432\u0432\u043e\u0434 \u0434\u0432\u0438\u0433\u0430\u0435\u0442 \u0441\u0446\u0435\u043d\u0443, \u0430 \u043d\u0435 \u043a\u0430\u043c\u0435\u0440\u0443. \u041a\u0430\u043c\u0435\u0440\u0430 \u0440\u0430\u0441\u043f\u043e\u043b\u043e\u0436\u0435\u043d\u0430 \u0432 \u0442\u043e\u0447\u043a\u0435 <code>[0, 0, -15]<\/code> \u0438 \u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0430 \u043d\u0430 \u0442\u043e\u0447\u043a\u0443 \u043d\u0430\u0447\u0430\u043b\u0430 \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442 \u043c\u0438\u0440\u0430. (\u0418\u043b\u0438 \u0436\u0435 \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0438\u0437\u043c\u0435\u043d\u0438\u0442\u044c \u043c\u0430\u0442\u0440\u0438\u0446\u0443 \u043f\u0435\u0440\u0441\u043f\u0435\u043a\u0442\u0438\u0432\u044b \u0442\u0430\u043a, \u0447\u0442\u043e\u0431\u044b \u043e\u043d\u0430 \u0434\u0432\u0438\u0433\u0430\u043b\u0430 \u043a\u0430\u043c\u0435\u0440\u0443 \u0432\u043c\u0435\u0441\u0442\u043e \u0441\u0446\u0435\u043d\u044b. \u042d\u0442\u043e \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u043d\u043e\u0435 \u0440\u0435\u0448\u0435\u043d\u0438\u0435 \u043e\u0447\u0435\u043d\u044c \u0441\u043b\u0430\u0431\u043e \u043f\u043e\u0432\u043b\u0438\u044f\u0435\u0442 \u043d\u0430 \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u0443\u044e \u0447\u0430\u0441\u0442\u044c \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b.) \u0412\u0435\u0440\u043d\u0443\u0432\u0448\u0438\u0441\u044c \u043a \u0444\u0443\u043d\u043a\u0446\u0438\u0438 <code>render<\/code> \u0432 <code>Viewer<\/code>, \u043c\u044b \u0432\u0438\u0434\u0438\u043c, \u0447\u0442\u043e \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 <code>Interaction<\/code> \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0434\u043b\u044f \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u043c\u0430\u0442\u0440\u0438\u0446\u044b OpenGL \u043f\u0435\u0440\u0435\u0434 \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433\u043e\u043c <code>Scene<\/code>. \u0421\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442 \u0434\u0432\u0430 \u0442\u0438\u043f\u0430 \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f \u0441\u043e \u0441\u0446\u0435\u043d\u043e\u0439: \u043f\u043e\u0432\u043e\u0440\u043e\u0442 \u0438 \u043f\u0435\u0440\u0435\u043c\u0435\u0449\u0435\u043d\u0438\u0435.<\/p>\n<h4>\u041f\u043e\u0432\u043e\u0440\u043e\u0442 \u0441\u0446\u0435\u043d\u044b \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0442\u0440\u0435\u043a\u0431\u043e\u043b\u0430<\/h4>\n<p>  \u041c\u044b \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u043c \u043f\u043e\u0432\u043e\u0440\u043e\u0442 \u0441\u0446\u0435\u043d\u044b \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c\u0430 <em>trackball<\/em>. \u0422\u0440\u0435\u043a\u0431\u043e\u043b \u2014 \u044d\u0442\u043e \u0438\u043d\u0442\u0443\u0438\u0442\u0438\u0432\u043d\u043e-\u043f\u043e\u043d\u044f\u0442\u043d\u044b\u0439 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 \u0434\u043b\u044f \u043c\u0430\u043d\u0438\u043f\u0443\u043b\u044f\u0446\u0438\u0439 \u0441\u043e \u0441\u0446\u0435\u043d\u043e\u0439 \u0432 \u0442\u0440\u0451\u0445 \u0438\u0437\u043c\u0435\u0440\u0435\u043d\u0438\u044f\u0445. \u0418\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 \u0442\u0440\u0435\u043a\u0431\u043e\u043b\u0430 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0442\u0430\u043a, \u043a\u0430\u043a \u0431\u0443\u0434\u0442\u043e \u0441\u0446\u0435\u043d\u0430 \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u0432\u043d\u0443\u0442\u0440\u0438 \u043f\u0440\u043e\u0437\u0440\u0430\u0447\u043d\u043e\u0433\u043e \u0448\u0430\u0440\u0430. \u0415\u0441\u043b\u0438 \u043f\u043e\u043b\u043e\u0436\u0438\u0442\u044c \u0440\u0443\u043a\u0443 \u043d\u0430 \u043f\u043e\u0432\u0435\u0440\u0445\u043d\u043e\u0441\u0442\u044c \u0448\u0430\u0440\u0430 \u0438 \u0442\u043e\u043b\u043a\u043d\u0443\u0442\u044c \u0435\u0433\u043e, \u0448\u0430\u0440 \u043f\u043e\u0432\u0435\u0440\u043d\u0451\u0442\u0441\u044f. \u0410\u043d\u0430\u043b\u043e\u0433\u0438\u0447\u043d\u043e, \u043f\u0440\u0438 \u0437\u0430\u0436\u0438\u043c\u0430\u043d\u0438\u0438 \u043f\u0440\u0430\u0432\u043e\u0439 \u043a\u043b\u0430\u0432\u0438\u0448\u0438 \u043c\u044b\u0448\u0438 \u0438 \u043f\u0435\u0440\u0435\u043c\u0435\u0449\u0435\u043d\u0438\u0438 \u043a\u0443\u0440\u0441\u043e\u0440\u0430 \u043f\u043e \u044d\u043a\u0440\u0430\u043d\u0443 \u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u0441\u0446\u0435\u043d\u0443. \u041f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435 \u043e \u0442\u0435\u043e\u0440\u0438\u0438 \u0442\u0440\u0435\u043a\u0431\u043e\u043b\u0430 \u043c\u043e\u0436\u043d\u043e \u043f\u0440\u043e\u0447\u0438\u0442\u0430\u0442\u044c \u0432 <a href=\"http:\/\/www.opengl.org\/wiki\/Object_Mouse_Trackball\" rel=\"nofollow\">OpenGL Wiki<\/a>. \u0412 \u043d\u0430\u0448\u0435\u0439 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0435 \u043c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e \u0442\u0440\u0435\u043a\u0431\u043e\u043b\u0430, \u044f\u0432\u043b\u044f\u044e\u0449\u0443\u044e\u0441\u044f \u0447\u0430\u0441\u0442\u044c\u044e <a href=\"https:\/\/code.google.com\/p\/glumpy\/source\/browse\/glumpy\/trackball.py\" rel=\"nofollow\">Glumpy<\/a>.<\/p>\n<p>  \u041c\u044b \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0443\u0435\u043c \u0441 \u0442\u0440\u0435\u043a\u0431\u043e\u043b\u043e\u043c \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0444\u0443\u043d\u043a\u0446\u0438\u0438 <code>drag_to<\/code>: \u0442\u0435\u043a\u0443\u0449\u0435\u0435 \u043f\u043e\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u043c\u044b\u0448\u0438 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e\u0439 \u0442\u043e\u0447\u043a\u043e\u0439, \u0430 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0435 \u043f\u043e\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u043c\u044b\u0448\u0438 \u2014 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430\u043c\u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u0438.<\/p>\n<pre><code class=\"python\">self.trackball.drag_to(self.mouse_loc[0], self.mouse_loc[1], dx, dy)<\/code><\/pre>\n<p>  \u041f\u043e\u043b\u0443\u0447\u0438\u0432\u0448\u0430\u044f\u0441\u044f \u043c\u0430\u0442\u0440\u0438\u0446\u0430 \u043f\u043e\u0432\u043e\u0440\u043e\u0442\u0430 \u2014 \u044d\u0442\u043e <code>trackball.matrix<\/code> \u0432 \u043e\u043a\u043d\u0435 \u043f\u0440\u043e\u0441\u043c\u043e\u0442\u0440\u0430 \u043f\u0440\u0438 \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433\u0435 \u0441\u0446\u0435\u043d\u044b.<\/p>\n<h4>\u041f\u0440\u0438\u043c\u0435\u0447\u0430\u043d\u0438\u0435: \u043a\u0432\u0430\u0442\u0435\u0440\u043d\u0438\u043e\u043d\u044b<\/h4>\n<p>  \u0422\u0440\u0430\u0434\u0438\u0446\u0438\u043e\u043d\u043d\u043e \u043f\u043e\u0432\u043e\u0440\u043e\u0442\u044b \u043e\u043f\u0438\u0441\u044b\u0432\u0430\u044e\u0442\u0441\u044f \u043e\u0434\u043d\u0438\u043c \u0438\u0437 \u0434\u0432\u0443\u0445 \u0441\u043f\u043e\u0441\u043e\u0431\u043e\u0432. \u041f\u0435\u0440\u0432\u044b\u0439 \u2014 \u044d\u0442\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u043f\u043e\u0432\u043e\u0440\u043e\u0442\u0430 \u0432\u043e\u043a\u0440\u0443\u0433 \u043a\u0430\u0436\u0434\u043e\u0439 \u0438\u0437 \u043e\u0441\u0435\u0439; \u043c\u043e\u0436\u043d\u043e \u0445\u0440\u0430\u043d\u0438\u0442\u044c \u0438\u0445 \u043a\u0430\u043a \u043a\u043e\u0440\u0442\u0435\u0436 \u0438\u0437 \u0442\u0440\u0451\u0445 \u0447\u043b\u0435\u043d\u043e\u0432, \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u044e\u0449\u0438\u0445 \u0441\u043e\u0431\u043e\u0439 \u0447\u0438\u0441\u043b\u0430 \u0441 \u043f\u043b\u0430\u0432\u0430\u044e\u0449\u0435\u0439 \u0437\u0430\u043f\u044f\u0442\u043e\u0439. \u0414\u0440\u0443\u0433\u0438\u043c \u0440\u0430\u0441\u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0451\u043d\u043d\u044b\u043c \u0441\u043f\u043e\u0441\u043e\u0431\u043e\u043c \u0437\u0430\u0434\u0430\u043d\u0438\u044f \u043f\u043e\u0432\u043e\u0440\u043e\u0442\u043e\u0432 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043a\u0432\u0430\u0442\u0435\u0440\u043d\u0438\u043e\u043d \u2014 \u044d\u043b\u0435\u043c\u0435\u043d\u0442, \u0441\u043e\u0441\u0442\u043e\u044f\u0449\u0438\u0439 \u0438\u0437 \u0432\u0435\u043a\u0442\u043e\u0440\u0430 \u0441 \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u0430\u043c\u0438 <math><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/formulas\/817\/b92\/407\/817b92407f764f57af9226e50cc788fd.svg\" alt=\"$x$\" data-tex=\"inline\"><\/math>, <math><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/formulas\/9b3\/4c4\/da5\/9b34c4da5c757d4982bbd1b6f2e8998a.svg\" alt=\"$y$\" data-tex=\"inline\"><\/math> \u0438 <math><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/formulas\/4ec\/3e2\/363\/4ec3e23638b6073b649999485c251c94.svg\" alt=\"$z$\" data-tex=\"inline\"><\/math>, \u0430 \u0442\u0430\u043a\u0436\u0435 \u043f\u043e\u0432\u043e\u0440\u043e\u0442\u0430 <math><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/formulas\/1d0\/034\/a09\/1d0034a09108db7af7cf42ea23a91ecd.svg\" alt=\"$w$\" data-tex=\"inline\"><\/math>. \u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u043a\u0432\u0430\u0442\u0435\u0440\u043d\u0438\u043e\u043d\u043e\u0432 \u0438\u043c\u0435\u0435\u0442 \u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u043e \u043f\u0440\u0435\u0438\u043c\u0443\u0449\u0435\u0441\u0442\u0432 \u043f\u043e \u0441\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u044e \u0441 \u043f\u043e\u0432\u043e\u0440\u043e\u0442\u043e\u043c \u043f\u043e \u043e\u0441\u044f\u043c; \u0432 \u0447\u0430\u0441\u0442\u043d\u043e\u0441\u0442\u0438, \u043e\u043d\u0438 \u0431\u043e\u043b\u0435\u0435 \u0441\u0442\u0430\u0431\u0438\u043b\u044c\u043d\u044b \u0447\u0438\u0441\u043b\u0435\u043d\u043d\u043e. \u0411\u043b\u0430\u0433\u043e\u0434\u0430\u0440\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044e \u043a\u0432\u0430\u0442\u0435\u0440\u043d\u0438\u043e\u043d\u043e\u0432 \u043c\u043e\u0436\u043d\u043e \u0438\u0437\u0431\u0435\u0436\u0430\u0442\u044c \u0442\u0430\u043a\u0438\u0445 \u043f\u0440\u043e\u0431\u043b\u0435\u043c, \u043a\u0430\u043a \u00ab\u0448\u0430\u0440\u043d\u0438\u0440\u043d\u044b\u0439 \u0437\u0430\u043c\u043e\u043a\u00bb (gimbal lock). \u041d\u0435\u0434\u043e\u0441\u0442\u0430\u0442\u043e\u043a \u043a\u0432\u0430\u0442\u0435\u0440\u043d\u0438\u043e\u043d\u043e\u0432 \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e \u043e\u043d\u0438 \u043c\u0435\u043d\u0435\u0435 \u0438\u043d\u0442\u0443\u0438\u0442\u0438\u0432\u043d\u043e-\u043f\u043e\u043d\u044f\u0442\u043d\u044b \u0432 \u0440\u0430\u0431\u043e\u0442\u0435. \u0415\u0441\u043b\u0438 \u0432\u044b \u043d\u0435 \u0431\u043e\u0438\u0442\u0435\u0441\u044c \u0438 \u0445\u043e\u0442\u0438\u0442\u0435 \u0443\u0437\u043d\u0430\u0442\u044c \u0431\u043e\u043b\u044c\u0448\u0435 \u043e \u043a\u0432\u0430\u0442\u0435\u0440\u043d\u0438\u043e\u043d\u0430\u0445, \u0442\u043e \u043c\u043e\u0436\u0435\u0442\u0435 \u0438\u0437\u0443\u0447\u0438\u0442\u044c <a href=\"http:\/\/3dgep.com\/?p=1815\" rel=\"nofollow\">\u044d\u0442\u043e \u043e\u0431\u044a\u044f\u0441\u043d\u0435\u043d\u0438\u0435<\/a>.<\/p>\n<p>  \u0420\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u0442\u0440\u0435\u043a\u0431\u043e\u043b\u0430 \u0438\u0437\u0431\u0435\u0433\u0430\u0435\u0442 gimbal lock \u0431\u043b\u0430\u0433\u043e\u0434\u0430\u0440\u044f \u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044e \u043f\u043e\u0432\u043e\u0440\u043e\u0442\u0430 \u0441\u0446\u0435\u043d\u044b \u043f\u0440\u0438 \u043f\u043e\u043c\u043e\u0449\u0438 \u043a\u0432\u0430\u0442\u0435\u0440\u043d\u0438\u043e\u043d\u043e\u0432. \u041a \u0441\u0447\u0430\u0441\u0442\u044c\u044e, \u043d\u0430\u043c \u043d\u0435 \u043d\u0443\u0436\u043d\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0441 \u043a\u0432\u0430\u0442\u0435\u0440\u043d\u0438\u043e\u043d\u0430\u043c\u0438 \u043d\u0430\u043f\u0440\u044f\u043c\u0443\u044e, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u043c\u0430\u0442\u0440\u0438\u0447\u043d\u044b\u0439 \u0447\u043b\u0435\u043d \u0442\u0440\u0435\u043a\u0431\u043e\u043b\u0430 \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u0443\u0435\u0442 \u043f\u043e\u0432\u043e\u0440\u043e\u0442 \u0432 \u043c\u0430\u0442\u0440\u0438\u0446\u0443.<\/p>\n<h4>\u041f\u0435\u0440\u0435\u043c\u0435\u0449\u0435\u043d\u0438\u0435 \u0441\u0446\u0435\u043d\u044b<\/h4>\n<p>  \u041f\u0435\u0440\u0435\u043c\u0435\u0449\u0435\u043d\u0438\u0435 \u0441\u0446\u0435\u043d\u044b (\u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0441\u0434\u0432\u0438\u0433) \u0433\u043e\u0440\u0430\u0437\u0434\u043e \u043f\u0440\u043e\u0449\u0435, \u0447\u0435\u043c \u0435\u0451 \u043f\u043e\u0432\u043e\u0440\u043e\u0442. \u041f\u0435\u0440\u0435\u043c\u0435\u0449\u0435\u043d\u0438\u044f \u0441\u0446\u0435\u043d\u044b \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u044e\u0442\u0441\u044f \u043a\u043e\u043b\u0435\u0441\u043e\u043c \u0438 \u043b\u0435\u0432\u043e\u0439 \u043a\u043b\u0430\u0432\u0438\u0448\u0435\u0439 \u043c\u044b\u0448\u0438. \u041b\u0435\u0432\u0430\u044f \u043a\u043b\u0430\u0432\u0438\u0448\u0430 \u043c\u044b\u0448\u0438 \u043f\u0435\u0440\u0435\u043c\u0435\u0449\u0430\u0435\u0442 \u0441\u0446\u0435\u043d\u0443 \u043f\u043e \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u0430\u043c <math><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/formulas\/817\/b92\/407\/817b92407f764f57af9226e50cc788fd.svg\" alt=\"$x$\" data-tex=\"inline\"><\/math> \u0438 <math><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/formulas\/9b3\/4c4\/da5\/9b34c4da5c757d4982bbd1b6f2e8998a.svg\" alt=\"$y$\" data-tex=\"inline\"><\/math>. \u041f\u0440\u043e\u043a\u0440\u0443\u0442\u043a\u0430 \u043a\u043e\u043b\u0435\u0441\u0430 \u043c\u044b\u0448\u0438 \u043f\u0435\u0440\u0435\u043c\u0435\u0449\u0430\u0435\u0442 \u0441\u0446\u0435\u043d\u0443 \u043f\u043e \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u0435 <math><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/formulas\/4ec\/3e2\/363\/4ec3e23638b6073b649999485c251c94.svg\" alt=\"$z$\" data-tex=\"inline\"><\/math> (\u0431\u043b\u0438\u0436\u0435 \u0438\u043b\u0438 \u0434\u0430\u043b\u044c\u0448\u0435 \u043e\u0442 \u043a\u0430\u043c\u0435\u0440\u044b). \u041a\u043b\u0430\u0441\u0441 <code>Interaction<\/code> \u0445\u0440\u0430\u043d\u0438\u0442 \u0442\u0435\u043a\u0443\u0449\u0435\u0435 \u043f\u0435\u0440\u0435\u043c\u0435\u0449\u0435\u043d\u0438\u0435 \u0441\u0446\u0435\u043d\u044b \u0438 \u043c\u043e\u0434\u0438\u0444\u0438\u0446\u0438\u0440\u0443\u0435\u0442 \u0435\u0433\u043e \u043f\u0440\u0438 \u043f\u043e\u043c\u043e\u0449\u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 <code>translate<\/code>. \u041e\u043a\u043d\u043e \u043f\u0440\u043e\u0441\u043c\u043e\u0442\u0440\u0430 \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442 \u0440\u0430\u0441\u043f\u043e\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u043a\u0430\u043c\u0435\u0440\u044b \u043a\u043b\u0430\u0441\u0441\u0430 <code>Interaction<\/code> \u043f\u0440\u0438 \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433\u0435 \u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 \u0435\u0433\u043e \u0432 \u0432\u044b\u0437\u043e\u0432\u0435 <code>glTranslated<\/code>.<\/p>\n<h4>\u0412\u044b\u0431\u043e\u0440 \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432 \u0441\u0446\u0435\u043d\u044b<\/h4>\n<p>  \u0422\u0435\u043f\u0435\u0440\u044c, \u043a\u043e\u0433\u0434\u0430 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043c\u043e\u0436\u0435\u0442 \u043f\u0435\u0440\u0435\u043c\u0435\u0449\u0430\u0442\u044c \u0438 \u043f\u043e\u0432\u043e\u0440\u0430\u0447\u0438\u0432\u0430\u0442\u044c \u0432\u0441\u044e \u0441\u0446\u0435\u043d\u0443 \u0434\u043b\u044f \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u043d\u0443\u0436\u043d\u043e\u0433\u043e \u043e\u0431\u0437\u043e\u0440\u0430, \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u0448\u0430\u0433\u043e\u043c \u0431\u0443\u0434\u0435\u0442 \u043e\u0431\u0435\u0441\u043f\u0435\u0447\u0435\u043d\u0438\u0435 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432 \u0438 \u043c\u0430\u043d\u0438\u043f\u0443\u043b\u044f\u0446\u0438\u0439 \u0438\u043c\u0438.<\/p>\n<p>  \u0427\u0442\u043e\u0431\u044b \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043c\u043e\u0433 \u043c\u0430\u043d\u0438\u043f\u0443\u043b\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043e\u0431\u044a\u0435\u043a\u0442\u0430\u043c\u0438 \u0441\u0446\u0435\u043d\u044b, \u043e\u043d \u0434\u043e\u043b\u0436\u0435\u043d \u0438\u043c\u0435\u0442\u044c \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0432\u044b\u0431\u043e\u0440\u0430 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432.<\/p>\n<p>  \u0414\u043b\u044f \u0432\u044b\u0431\u043e\u0440\u0430 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430 \u043c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u0442\u0435\u043a\u0443\u0449\u0443\u044e \u043c\u0430\u0442\u0440\u0438\u0446\u0443 \u043f\u0440\u043e\u0435\u0446\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0434\u043b\u044f \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 \u043b\u0443\u0447\u0430, \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u044e\u0449\u0435\u0433\u043e \u0449\u0435\u043b\u0447\u043e\u043a \u043c\u044b\u0448\u0438, \u043a\u0430\u043a \u0431\u0443\u0434\u0442\u043e \u0443\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u044c \u043c\u044b\u0448\u0438 \u0438\u0441\u043f\u0443\u0441\u043a\u0430\u0435\u0442 \u0432 \u0441\u0446\u0435\u043d\u0443 \u043b\u0443\u0447. \u0412\u044b\u0431\u0440\u0430\u043d\u043d\u044b\u043c \u0443\u0437\u043b\u043e\u043c \u0431\u0443\u0434\u0435\u0442 \u0431\u043b\u0438\u0436\u0430\u0439\u0448\u0438\u0439 \u043a \u043a\u0430\u043c\u0435\u0440\u0435 \u0443\u0437\u0435\u043b, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u0435\u0440\u0435\u0441\u0451\u043a \u043b\u0443\u0447. \u0421\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e, \u0437\u0430\u0434\u0430\u0447\u0430 \u0432\u044b\u0431\u043e\u0440\u0430 \u0441\u0432\u043e\u0434\u0438\u0442\u0441\u044f \u043a \u0437\u0430\u0434\u0430\u0447\u0435 \u043d\u0430\u0445\u043e\u0436\u0434\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 \u0443\u0437\u043b\u0430\u043c\u0438 \u0441\u0446\u0435\u043d\u044b. \u0422\u043e \u0435\u0441\u0442\u044c \u0432\u043e\u043f\u0440\u043e\u0441 \u0437\u0430\u043a\u043b\u044e\u0447\u0430\u0435\u0442\u0441\u044f \u0432 \u0442\u043e\u043c, \u043a\u0430\u043a \u043d\u0430\u043c \u0443\u0437\u043d\u0430\u0442\u044c, \u0447\u0442\u043e \u043b\u0443\u0447 \u0441\u0442\u043e\u043b\u043a\u043d\u0443\u043b\u0441\u044f \u0441 \u0443\u0437\u043b\u043e\u043c.<\/p>\n<p>  \u0412\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u0435 \u0442\u043e\u0447\u043d\u043e\u0433\u043e \u043e\u0442\u0432\u0435\u0442\u0430 \u043d\u0430 \u0432\u043e\u043f\u0440\u043e\u0441, \u043f\u0435\u0440\u0435\u0441\u0451\u043a\u0441\u044f \u043b\u0438 \u043b\u0443\u0447 \u0441 \u0443\u0437\u043b\u043e\u043c \u2014 \u044d\u0442\u043e \u0441\u043b\u043e\u0436\u043d\u0430\u044f \u0437\u0430\u0434\u0430\u0447\u0430, \u0441 \u0442\u043e\u0447\u043a\u0438 \u0437\u0440\u0435\u043d\u0438\u044f \u0438 \u043a\u043e\u0434\u0430, \u0438 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438. \u041d\u0430\u043c \u0431\u044b \u043f\u043e\u0442\u0440\u0435\u0431\u043e\u0432\u0430\u043b\u043e\u0441\u044c \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0443 \u043f\u0435\u0440\u0435\u0441\u0435\u0447\u0435\u043d\u0438\u044f \u043b\u0443\u0447\u0430 \u0441 \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u043c \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0442\u0438\u043f\u0430 \u043f\u0440\u0438\u043c\u0438\u0442\u0438\u0432\u0430. \u0414\u043b\u044f \u0443\u0437\u043b\u043e\u0432 \u0441\u0446\u0435\u043d\u044b \u0441\u043e \u0441\u043b\u043e\u0436\u043d\u044b\u043c\u0438 \u0433\u0435\u043e\u043c\u0435\u0442\u0440\u0438\u044f\u043c\u0438 \u043c\u0435\u0448\u0435\u0439 <br \/>  \u0438 \u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u043e\u043c \u0433\u0440\u0430\u043d\u0435\u0439 \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u0435 \u0442\u043e\u0447\u043d\u043e\u0433\u043e \u043f\u0435\u0440\u0435\u0441\u0435\u0447\u0435\u043d\u0438\u044f \u043b\u0443\u0447\u0430 \u0441 \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u043c \u043f\u043e\u0442\u0440\u0435\u0431\u0443\u0435\u0442 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u043b\u0443\u0447\u0430 \u0441 \u043a\u0430\u0436\u0434\u043e\u0439 \u0433\u0440\u0430\u043d\u044c\u044e, \u0447\u0442\u043e \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u0447\u0438\u0441\u043b\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0437\u0430\u0442\u0440\u0430\u0442\u043d\u043e\u0439 \u0437\u0430\u0434\u0430\u0447\u0435\u0439.<\/p>\n<p>  \u0414\u043b\u044f \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u043a\u043e\u043c\u043f\u0430\u043a\u0442\u043d\u043e\u0441\u0442\u0438 \u043a\u043e\u0434\u0430 \u0438 \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e\u0439 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438 \u043c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u043f\u0440\u043e\u0441\u0442\u0443\u044e \u0438 \u0431\u044b\u0441\u0442\u0440\u0443\u044e \u0430\u043f\u043f\u0440\u043e\u043a\u0441\u0438\u043c\u0430\u0446\u0438\u044e \u0442\u0435\u0441\u0442\u0430 \u043f\u0435\u0440\u0435\u0441\u0435\u0447\u0435\u043d\u0438\u044f \u043b\u0443\u0447\u0430 \u0441 \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u043c. \u0412 \u043d\u0430\u0448\u0435\u0439 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u043a\u0430\u0436\u0434\u044b\u0439 \u0443\u0437\u0435\u043b \u0445\u0440\u0430\u043d\u0438\u0442 \u043f\u0430\u0440\u0430\u043b\u043b\u0435\u043b\u044c\u043d\u044b\u0439 \u043e\u0441\u044f\u043c \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0438\u0432\u0430\u044e\u0449\u0438\u0439 \u043f\u0430\u0440\u0430\u043b\u043b\u0435\u043b\u0435\u043f\u0438\u043f\u0435\u0434 (axis-aligned bounding box, AABB), \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0430\u043f\u043f\u0440\u043e\u043a\u0441\u0438\u043c\u0430\u0446\u0438\u0435\u0439 \u0437\u0430\u043d\u0438\u043c\u0430\u0435\u043c\u043e\u0433\u043e \u0443\u0437\u043b\u043e\u043c \u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u0430. \u0427\u0442\u043e\u0431\u044b \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c, \u043f\u0435\u0440\u0435\u0441\u0435\u043a\u0430\u0435\u0442\u0441\u044f \u043b\u0438 \u043b\u0443\u0447 \u0441 \u0443\u0437\u043b\u043e\u043c, \u043c\u044b \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u043c, \u043f\u0435\u0440\u0435\u0441\u0435\u043a\u0430\u0435\u0442\u0441\u044f \u043b\u0438 \u043b\u0443\u0447 \u0441 AABB \u0443\u0437\u043b\u0430. \u0422\u0430\u043a\u0430\u044f \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u043e\u0437\u043d\u0430\u0447\u0430\u0435\u0442, \u0447\u0442\u043e \u0432\u0441\u0435 \u0443\u0437\u043b\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442 \u043e\u0434\u0438\u043d \u043a\u043e\u0434 \u0434\u043b\u044f \u0442\u0435\u0441\u0442\u043e\u0432 \u043f\u0435\u0440\u0435\u0441\u0435\u0447\u0435\u043d\u0438\u044f, \u0430 \u0432\u044b\u0447\u0438\u0441\u043b\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u0437\u0430\u0442\u0440\u0430\u0442\u044b \u043e\u0441\u0442\u0430\u044e\u0442\u0441\u044f \u043f\u043e\u0441\u0442\u043e\u044f\u043d\u043d\u044b\u043c\u0438 \u0438 \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u0438\u043c\u0438 \u0434\u043b\u044f \u0432\u0441\u0435\u0445 \u0442\u0438\u043f\u043e\u0432 \u0443\u0437\u043b\u043e\u0432.<\/p>\n<pre><code class=\"python\">    # class Viewer     def get_ray(self, x, y):         &quot;&quot;&quot;          Generate a ray beginning at the near plane, in the direction that         the x, y coordinates are facing           Consumes: x, y coordinates of mouse on screen          Return: start, direction of the ray          &quot;&quot;&quot;         self.init_view()          glMatrixMode(GL_MODELVIEW)         glLoadIdentity()          # get two points on the line.         start = numpy.array(gluUnProject(x, y, 0.001))         end = numpy.array(gluUnProject(x, y, 0.999))          # convert those points into a ray         direction = end - start         direction = direction \/ norm(direction)          return (start, direction)      def pick(self, x, y):         &quot;&quot;&quot; Execute pick of an object. Selects an object in the scene. &quot;&quot;&quot;         start, direction = self.get_ray(x, y)         self.scene.pick(start, direction, self.modelView)<\/code><\/pre>\n<p>  \u0427\u0442\u043e\u0431\u044b \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u0442\u044c, \u043a\u0430\u043a\u043e\u0439 \u0438\u0437 \u0443\u0437\u043b\u043e\u0432 \u0449\u0451\u043b\u043a\u043d\u0443\u043b\u0438 \u043c\u044b\u0448\u044c\u044e, \u043c\u044b \u043e\u0431\u0445\u043e\u0434\u0438\u043c \u0441\u0446\u0435\u043d\u0443, \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u044f, \u043f\u0435\u0440\u0435\u0441\u0451\u043a\u0441\u044f \u043b\u0438 \u043b\u0443\u0447 \u0441 \u043a\u0430\u043a\u0438\u043c-\u043d\u0438\u0431\u0443\u0434\u044c \u0438\u0437 \u0443\u0437\u043b\u043e\u0432. \u0412\u044b \u0441\u043d\u0438\u043c\u0430\u0435\u043c \u0432\u044b\u0431\u043e\u0440 \u0441 \u0442\u0435\u043a\u0443\u0449\u0435\u0433\u043e \u0443\u0437\u043b\u0430 \u0438 \u0432\u044b\u0431\u0438\u0440\u0430\u0435\u043c \u0443\u0437\u0435\u043b, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u043b\u0438\u0436\u0435 \u0432\u0441\u0435\u0433\u043e \u043f\u0435\u0440\u0435\u0441\u0435\u043a\u0430\u0435\u0442\u0441\u044f \u043a \u0442\u043e\u0447\u043a\u0435 \u043d\u0430\u0447\u0430\u043b\u0430 \u043b\u0443\u0447\u0430.<\/p>\n<pre><code class=\"python\">    # class Scene     def pick(self, start, direction, mat):         &quot;&quot;&quot;          Execute selection.                      start, direction describe a Ray.          mat is the inverse of the current modelview matrix for the scene.         &quot;&quot;&quot;         if self.selected_node is not None:             self.selected_node.select(False)             self.selected_node = None          # Keep track of the closest hit.         mindist = sys.maxint         closest_node = None         for node in self.node_list:             hit, distance = node.pick(start, direction, mat)             if hit and distance &lt; mindist:                 mindist, closest_node = distance, node          # If we hit something, keep track of it.         if closest_node is not None:             closest_node.select()             closest_node.depth = mindist             closest_node.selected_loc = start + direction * mindist             self.selected_node = closest_node<\/code><\/pre>\n<p>  \u0412 \u043a\u043b\u0430\u0441\u0441\u0435 <code>Node<\/code> \u0444\u0443\u043d\u043a\u0446\u0438\u044f <code>pick<\/code> \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u0442, \u043f\u0435\u0440\u0435\u0441\u0435\u043a\u0430\u0435\u0442\u0441\u044f \u043b\u0438 \u043b\u0443\u0447 \u0441 AABB <code>Node<\/code>. \u0415\u0441\u043b\u0438 \u0443\u0437\u0435\u043b \u0432\u044b\u0431\u0440\u0430\u043d, \u0442\u043e \u0444\u0443\u043d\u043a\u0446\u0438\u044f <code>select<\/code> \u043f\u0435\u0440\u0435\u043a\u043b\u044e\u0447\u0430\u0435\u0442 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0432\u044b\u0431\u043e\u0440\u0430 \u0443\u0437\u043b\u0430. \u041e\u0431\u0440\u0430\u0442\u0438\u0442\u0435 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435, \u0447\u0442\u043e \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0442\u0440\u0435\u0442\u044c\u0435\u0433\u043e \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u044f <code>ray_hit<\/code> AABB \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442 \u043c\u0430\u0442\u0440\u0438\u0446\u0443 \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u0439 \u043c\u0435\u0436\u0434\u0443 \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u043d\u044b\u043c \u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u043e\u043c \u043f\u0430\u0440\u0430\u043b\u043b\u0435\u043b\u0435\u043f\u0438\u043f\u0435\u0434\u0430 \u0438 \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u043d\u044b\u043c \u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u043e\u043c \u043b\u0443\u0447\u0430. \u041f\u0435\u0440\u0435\u0434 \u0432\u044b\u0437\u043e\u0432\u043e\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u0438 <code>ray_hit<\/code> \u043a\u0430\u0436\u0434\u044b\u0439 \u0443\u0437\u0435\u043b \u0432\u043d\u043e\u0441\u0438\u0442 \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0435 \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u0432 \u043c\u0430\u0442\u0440\u0438\u0446\u0443.<\/p>\n<pre><code class=\"python\">    # class Node     def pick(self, start, direction, mat):         &quot;&quot;&quot;          Return whether or not the ray hits the object          Consume:           start, direction form the ray to check         mat is the modelview matrix to transform the ray by          &quot;&quot;&quot;          # transform the modelview matrix by the current translation         newmat = numpy.dot(             numpy.dot(mat, self.translation_matrix),              numpy.linalg.inv(self.scaling_matrix)         )         results = self.aabb.ray_hit(start, direction, newmat)         return results      def select(self, select=None):        &quot;&quot;&quot; Toggles or sets selected state &quot;&quot;&quot;        if select is not None:            self.selected = select        else:            self.selected = not self.selected<\/code><\/pre>\n<p>  \u0421\u0445\u0435\u043c\u0443 \u0432\u044b\u0431\u043e\u0440\u0430 \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0435 \u043f\u0435\u0440\u0435\u0441\u0435\u0447\u0435\u043d\u0438\u044f \u043b\u0443\u0447\u0430 \u0438 AABB \u043e\u0447\u0435\u043d\u044c \u043b\u0435\u0433\u043a\u043e \u043f\u043e\u043d\u044f\u0442\u044c \u0438 \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c. \u041e\u0434\u043d\u0430\u043a\u043e \u0432 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u0441\u0438\u0442\u0443\u0430\u0446\u0438\u044f\u0445 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u044b \u043e\u043a\u0430\u0437\u044b\u0432\u0430\u044e\u0442\u0441\u044f \u043e\u0448\u0438\u0431\u043e\u0447\u043d\u044b\u043c\u0438.<\/p>\n<div style=\"text-align:center;\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/post_images\/1b6\/d49\/be0\/1b6d49be070fb475dde98d84f4263c95.png\" alt=\"image\"><\/div>\n<p>  <i>\u0420\u0438\u0441\u0443\u043d\u043e\u043a 3 \u2014 \u041e\u0448\u0438\u0431\u043a\u0430 AABB<\/i><\/p>\n<p>  \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0432 \u0441\u043b\u0443\u0447\u0430\u0435 \u043f\u0440\u0438\u043c\u0438\u0442\u0438\u0432\u0430 <code>Sphere<\/code>, \u0441\u0430\u043c\u0430 \u0441\u0444\u0435\u0440\u0430 \u043a\u0430\u0441\u0430\u0435\u0442\u0441\u044f AABB \u0442\u043e\u043b\u044c\u043a\u043e \u0432 \u0446\u0435\u043d\u0442\u0440\u0435 \u043a\u0430\u0436\u0434\u043e\u0439 \u0438\u0437 \u0433\u0440\u0430\u043d\u0435\u0439 AABB. \u041e\u0434\u043d\u0430\u043a\u043e \u0435\u0441\u043b\u0438 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043d\u0430\u0436\u043c\u0451\u0442 \u043d\u0430 \u0443\u0433\u043e\u043b AABB \u0441\u0444\u0435\u0440\u044b, \u0431\u0443\u0434\u0435\u0442 \u043e\u0431\u043d\u0430\u0440\u0443\u0436\u0435\u043d\u0430 \u043a\u043e\u043b\u043b\u0438\u0437\u0438\u044f \u0441\u043e \u0441\u0444\u0435\u0440\u043e\u0439, \u0434\u0430\u0436\u0435 \u0435\u0441\u043b\u0438 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u0445\u043e\u0442\u0435\u043b \u043d\u0430\u0436\u0430\u0442\u044c \u043d\u0430 \u0447\u0442\u043e-\u0442\u043e \u0437\u0430 \u043d\u0435\u0439 (\u0420\u0438\u0441\u0443\u043d\u043e\u043a 3).<\/p>\n<p>  \u0422\u0430\u043a\u043e\u0439 \u043a\u043e\u043c\u043f\u0440\u043e\u043c\u0438\u0441\u0441 \u043c\u0435\u0436\u0434\u0443 \u0441\u043b\u043e\u0436\u043d\u043e\u0441\u0442\u044c\u044e, \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c\u044e \u0438 \u0442\u043e\u0447\u043d\u043e\u0441\u0442\u044c\u044e \u043e\u0447\u0435\u043d\u044c \u0440\u0430\u0441\u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0451\u043d \u0432 \u043a\u043e\u043c\u043f\u044c\u044e\u0442\u0435\u0440\u043d\u043e\u0439 \u0433\u0440\u0430\u0444\u0438\u043a\u0435 \u0438 \u0432\u043e \u043c\u043d\u043e\u0433\u0438\u0445 \u043e\u0431\u043b\u0430\u0441\u0442\u044f\u0445 \u043f\u0440\u043e\u0435\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u041f\u041e.<\/p>\n<h4>\u0418\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0435 \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432 \u0441\u0446\u0435\u043d\u044b<\/h4>\n<p>  \u0414\u0430\u043b\u0435\u0435 \u043c\u044b \u0445\u043e\u0442\u0438\u043c \u0434\u0430\u0442\u044c \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044e \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u043c\u0430\u043d\u0438\u043f\u0443\u043b\u044f\u0446\u0438\u0439 \u0441 \u0432\u044b\u0431\u0440\u0430\u043d\u043d\u044b\u043c\u0438 \u0443\u0437\u043b\u0430\u043c\u0438. \u0415\u043c\u0443 \u043c\u043e\u0436\u0435\u0442 \u043f\u043e\u0442\u0440\u0435\u0431\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u043f\u0435\u0440\u0435\u043c\u0435\u0449\u0430\u0442\u044c \u0432\u044b\u0431\u0440\u0430\u043d\u043d\u044b\u0439 \u0443\u0437\u0435\u043b, \u0438\u0437\u043c\u0435\u043d\u044f\u0442\u044c \u0435\u0433\u043e \u0440\u0430\u0437\u043c\u0435\u0440 \u0438\u043b\u0438 \u0446\u0432\u0435\u0442. \u041a\u043e\u0433\u0434\u0430 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u0432\u0432\u043e\u0434\u0438\u0442 \u043a\u043e\u043c\u0430\u043d\u0434\u0443 \u043c\u0430\u043d\u0438\u043f\u0443\u043b\u044f\u0446\u0438\u0438 \u0441 \u0443\u0437\u043b\u043e\u043c, \u043a\u043b\u0430\u0441\u0441 <code>Interaction<\/code> \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u0443\u0435\u0442 \u0432\u0432\u043e\u0434 \u0432 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0435, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u043d\u0430\u043c\u0435\u0440\u0435\u0432\u0430\u043b\u0441\u044f \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c, \u0438 \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0443\u044e \u0444\u0443\u043d\u043a\u0446\u0438\u044e \u043e\u0431\u0440\u0430\u0442\u043d\u043e\u0433\u043e \u0432\u044b\u0437\u043e\u0432\u0430.<\/p>\n<p>  \u041a\u043e\u0433\u0434\u0430 <code>Viewer<\/code> \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442 \u043e\u0431\u0440\u0430\u0442\u043d\u044b\u0439 \u0432\u044b\u0437\u043e\u0432 \u0434\u043b\u044f \u043e\u0434\u043d\u043e\u0433\u043e \u0438\u0437 \u044d\u0442\u0438\u0445 \u0441\u043e\u0431\u044b\u0442\u0438\u0439, \u043e\u043d \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0443\u044e \u0444\u0443\u043d\u043a\u0446\u0438\u044e <code>Scene<\/code>, \u043a\u043e\u0442\u043e\u0440\u0430\u044f, \u0432 \u0441\u0432\u043e\u044e \u043e\u0447\u0435\u0440\u0435\u0434\u044c, \u043f\u0440\u0438\u043c\u0435\u043d\u044f\u0435\u0442 \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u043a \u0442\u0435\u043a\u0443\u0449\u0435\u043c\u0443 \u0432\u044b\u0431\u0440\u0430\u043d\u043d\u043e\u043c\u0443 <code>Node<\/code>.<\/p>\n<pre><code class=\"python\">    # class Viewer     def move(self, x, y):         &quot;&quot;&quot; Execute a move command on the scene. &quot;&quot;&quot;         start, direction = self.get_ray(x, y)         self.scene.move_selected(start, direction, self.inverseModelView)      def rotate_color(self, forward):         &quot;&quot;&quot;          Rotate the color of the selected Node.          Boolean 'forward' indicates direction of rotation.          &quot;&quot;&quot;         self.scene.rotate_selected_color(forward)      def scale(self, up):         &quot;&quot;&quot; Scale the selected Node. Boolean up indicates scaling larger.&quot;&quot;&quot;         self.scene.scale_selected(up)<\/code><\/pre>\n<p>  <\/p>\n<h4>\u0421\u043c\u0435\u043d\u0430 \u0446\u0432\u0435\u0442\u0430<\/h4>\n<p>  \u041c\u0430\u043d\u0438\u043f\u0443\u043b\u044f\u0446\u0438\u044f \u0446\u0432\u0435\u0442\u043e\u043c \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442\u0441\u044f \u0447\u0435\u0440\u0435\u0437 \u0441\u043f\u0438\u0441\u043e\u043a \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u044b\u0445 \u0446\u0432\u0435\u0442\u043e\u0432. \u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043c\u043e\u0436\u0435\u0442 \u043f\u0435\u0440\u0435\u043c\u0435\u0449\u0430\u0442\u044c\u0441\u044f \u043f\u043e \u0441\u043f\u0438\u0441\u043a\u0443 \u043a\u043b\u0430\u0432\u0438\u0448\u0430\u043c\u0438 \u0441\u043e \u0441\u0442\u0440\u0435\u043b\u043a\u0430\u043c\u0438. \u0421\u0446\u0435\u043d\u0430 \u043e\u0442\u0434\u0430\u0451\u0442 \u043a\u043e\u043c\u0430\u043d\u0434\u0443 \u0441\u043c\u0435\u043d\u044b \u0446\u0432\u0435\u0442\u0430 \u0442\u0435\u043a\u0443\u0449\u0435\u043c\u0443 \u0432\u044b\u0431\u0440\u0430\u043d\u043d\u043e\u043c\u0443 \u0443\u0437\u043b\u0443.<\/p>\n<pre><code class=\"python\">    # class Scene     def rotate_selected_color(self, forwards):         &quot;&quot;&quot; Rotate the color of the currently selected node &quot;&quot;&quot;         if self.selected_node is None: return         self.selected_node.rotate_color(forwards)<\/code><\/pre>\n<p>  \u041a\u0430\u0436\u0434\u044b\u0439 \u0446\u0432\u0435\u0442 \u0445\u0440\u0430\u043d\u0438\u0442 \u0441\u0432\u043e\u0439 \u0442\u0435\u043a\u0443\u0449\u0438\u0439 \u0446\u0432\u0435\u0442. \u0424\u0443\u043d\u043a\u0446\u0438\u044f <code>rotate_color<\/code> \u043f\u0440\u043e\u0441\u0442\u043e \u0438\u0437\u043c\u0435\u043d\u044f\u0435\u0442 \u0442\u0435\u043a\u0443\u0449\u0438\u0439 \u0446\u0432\u0435\u0442 \u0443\u0437\u043b\u0430. \u0426\u0432\u0435\u0442 \u043f\u0435\u0440\u0435\u0434\u0430\u0451\u0442\u0441\u044f OpenGL \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e <code>glColor<\/code> \u043f\u0440\u0438 \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433\u0435 \u0443\u0437\u043b\u0430.<\/p>\n<pre><code class=\"python\">    # class Node     def rotate_color(self, forwards):         self.color_index += 1 if forwards else -1         if self.color_index &gt; color.MAX_COLOR:             self.color_index = color.MIN_COLOR         if self.color_index &lt; color.MIN_COLOR:             self.color_index = color.MAX_COLOR<\/code><\/pre>\n<p>  <\/p>\n<h4>\u041c\u0430\u0441\u0448\u0442\u0430\u0431\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0443\u0437\u043b\u043e\u0432<\/h4>\n<p>  \u041a\u0430\u043a \u0438 \u0432 \u0441\u043b\u0443\u0447\u0430\u0435 \u0441 \u0446\u0432\u0435\u0442\u043e\u043c, \u0441\u0446\u0435\u043d\u0430 \u043e\u0442\u0434\u0430\u0451\u0442 \u043a\u043e\u043c\u0430\u043d\u0434\u044b \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u043c\u0430\u0441\u0448\u0442\u0430\u0431\u0430 \u0432\u044b\u0431\u0440\u0430\u043d\u043d\u043e\u043c\u0443 \u0443\u0437\u043b\u0443, \u0435\u0441\u043b\u0438 \u043e\u043d \u0435\u0441\u0442\u044c.<\/p>\n<pre><code class=\"python\">    # class Scene     def scale_selected(self, up):         &quot;&quot;&quot; Scale the current selection &quot;&quot;&quot;         if self.selected_node is None: return         self.selected_node.scale(up)<\/code><\/pre>\n<p>  \u041a\u0430\u0436\u0434\u044b\u0439 \u0443\u0437\u0435\u043b \u0445\u0440\u0430\u043d\u0438\u0442 \u0442\u0435\u043a\u0443\u0449\u0443\u044e \u043c\u0430\u0442\u0440\u0438\u0446\u0443, \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0449\u0443\u044e \u0435\u0433\u043e \u043c\u0430\u0441\u0448\u0442\u0430\u0431. \u041c\u0430\u0442\u0440\u0438\u0446\u0430, \u0438\u0437\u043c\u0435\u043d\u044f\u044e\u0449\u0430\u044f \u043c\u0430\u0441\u0448\u0442\u0430\u0431 \u043f\u043e \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430\u043c <math><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/formulas\/817\/b92\/407\/817b92407f764f57af9226e50cc788fd.svg\" alt=\"$x$\" data-tex=\"inline\"><\/math>, <math><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/formulas\/9b3\/4c4\/da5\/9b34c4da5c757d4982bbd1b6f2e8998a.svg\" alt=\"$y$\" data-tex=\"inline\"><\/math> \u0438 <math><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/formulas\/4ec\/3e2\/363\/4ec3e23638b6073b649999485c251c94.svg\" alt=\"$z$\" data-tex=\"inline\"><\/math> \u0432 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0445 \u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f\u0445, \u0438\u043c\u0435\u0435\u0442 \u0432\u0438\u0434:<\/p>\n<p><math><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/formulas\/76b\/3f8\/7c6\/76b3f87c641697b0cdaa2172164a0529.svg\" alt=\"$\\begin{bmatrix} x &amp; 0 &amp; 0 &amp; 0 \\\\ 0 &amp; y &amp; 0 &amp; 0 \\\\ 0 &amp; 0 &amp; z &amp; 0 \\\\ 0 &amp; 0 &amp; 0 &amp; 1 \\\\ \\end{bmatrix}$\" data-tex=\"display\"><\/math><\/p>\n<p>  \u041a\u043e\u0433\u0434\u0430 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u0438\u0437\u043c\u0435\u043d\u044f\u0435\u0442 \u043c\u0430\u0441\u0448\u0442\u0430\u0431 \u0443\u0437\u043b\u0430, \u043f\u043e\u043b\u0443\u0447\u0438\u0432\u0448\u0430\u044f\u0441\u044f \u043c\u0430\u0442\u0440\u0438\u0446\u0430 \u043c\u0430\u0441\u0448\u0442\u0430\u0431\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0443\u043c\u043d\u043e\u0436\u0430\u0435\u0442\u0441\u044f \u043d\u0430 \u0442\u0435\u043a\u0443\u0449\u0443\u044e \u043c\u0430\u0442\u0440\u0438\u0446\u0443 \u043c\u0430\u0441\u0448\u0442\u0430\u0431\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0443\u0437\u043b\u0430.<\/p>\n<pre><code class=\"python\">    # class Node     def scale(self, up):         s =  1.1 if up else 0.9         self.scaling_matrix = numpy.dot(self.scaling_matrix, scaling([s, s, s]))         self.aabb.scale(s)<\/code><\/pre>\n<p>  \u0424\u0443\u043d\u043a\u0446\u0438\u044f <code>scaling<\/code> \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u043c\u0430\u0442\u0440\u0438\u0446\u0443, \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0443\u044e \u043a\u043e\u044d\u0444\u0444\u0438\u0446\u0438\u0435\u043d\u0442\u0430\u043c \u043c\u0430\u0441\u0448\u0442\u0430\u0431\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f <math><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/formulas\/817\/b92\/407\/817b92407f764f57af9226e50cc788fd.svg\" alt=\"$x$\" data-tex=\"inline\"><\/math>, <math><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/formulas\/9b3\/4c4\/da5\/9b34c4da5c757d4982bbd1b6f2e8998a.svg\" alt=\"$y$\" data-tex=\"inline\"><\/math> \u0438 <math><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/formulas\/4ec\/3e2\/363\/4ec3e23638b6073b649999485c251c94.svg\" alt=\"$z$\" data-tex=\"inline\"><\/math>.<\/p>\n<pre><code class=\"python\">def scaling(scale):     s = numpy.identity(4)     s[0, 0] = scale[0]     s[1, 1] = scale[1]     s[2, 2] = scale[2]     s[3, 3] = 1     return s<\/code><\/pre>\n<p>  <\/p>\n<h4>\u041f\u0435\u0440\u0435\u043c\u0435\u0449\u0435\u043d\u0438\u0435 \u0443\u0437\u043b\u043e\u0432<\/h4>\n<p>  \u0414\u043b\u044f \u043f\u0435\u0440\u0435\u043c\u0435\u0449\u0435\u043d\u0438\u044f \u0443\u0437\u043b\u0430 \u043c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u0442\u043e \u0436\u0435 \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u0435 \u043b\u0443\u0447\u0430, \u0447\u0442\u043e \u0438 \u0434\u043b\u044f \u0432\u044b\u0431\u043e\u0440\u0430. \u041c\u044b \u043f\u0435\u0440\u0435\u0434\u0430\u0451\u043c \u043b\u0443\u0447, \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u044e\u0449\u0438\u0439 \u0442\u0435\u043a\u0443\u0449\u0443\u044e \u043f\u043e\u0437\u0438\u0446\u0438\u044e \u043c\u044b\u0448\u0438, \u0432 \u0444\u0443\u043d\u043a\u0446\u0438\u044e <code>move<\/code> \u0441\u0446\u0435\u043d\u044b. \u041d\u043e\u0432\u043e\u0435 \u043c\u0435\u0441\u0442\u043e\u043f\u043e\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0443\u0437\u043b\u0430 \u0434\u043e\u043b\u0436\u043d\u043e \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u043d\u0430 \u043b\u0443\u0447\u0435. \u0427\u0442\u043e\u0431\u044b \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u0442\u044c, \u043a\u0443\u0434\u0430 \u043b\u0443\u0447 \u0434\u043e\u043b\u0436\u0435\u043d \u043f\u043e\u043c\u0435\u0441\u0442\u0438\u0442\u044c \u0443\u0437\u0435\u043b, \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u0437\u043d\u0430\u0442\u044c, \u0440\u0430\u0441\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0443\u0437\u043b\u0430 \u043e\u0442 \u043a\u0430\u043c\u0435\u0440\u044b. \u0422\u0430\u043a \u043a\u0430\u043a \u043c\u044b \u0441\u043e\u0445\u0440\u0430\u043d\u0438\u043b\u0438 \u043c\u0435\u0441\u0442\u043e\u043f\u043e\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0443\u0437\u043b\u0430 \u0438 \u0440\u0430\u0441\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0434\u043e \u043a\u0430\u043c\u0435\u0440\u044b \u043f\u0440\u0438 \u0435\u0433\u043e \u0432\u044b\u0431\u043e\u0440\u0435 (\u0432 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 <code>pick<\/code>), \u043c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0437\u0434\u0435\u0441\u044c \u044d\u0442\u0438 \u0434\u0430\u043d\u043d\u044b\u0435. \u041c\u044b \u043d\u0430\u0445\u043e\u0434\u0438\u043c \u0442\u043e\u0447\u043a\u0443, \u043d\u0430\u0445\u043e\u0434\u044f\u0449\u0443\u044e\u0441\u044f \u043d\u0430 \u0442\u043e\u043c \u0436\u0435 \u0440\u0430\u0441\u0441\u0442\u043e\u044f\u043d\u0438\u0438 \u043e\u0442 \u043a\u0430\u043c\u0435\u0440\u044b \u0432\u0434\u043e\u043b\u044c \u043b\u0443\u0447\u0430 \u0438 \u0432\u044b\u0447\u0438\u0441\u043b\u044f\u0435\u043c \u0440\u0430\u0437\u043d\u043e\u0441\u0442\u044c \u0432\u0435\u043a\u0442\u043e\u0440\u043e\u0432 \u043c\u0435\u0436\u0434\u0443 \u043d\u043e\u0432\u044b\u043c \u0438 \u0441\u0442\u0430\u0440\u044b\u043c \u043c\u0435\u0441\u0442\u043e\u043f\u043e\u043b\u043e\u0436\u0435\u043d\u0438\u0435\u043c. \u0417\u0430\u0442\u0435\u043c \u043c\u044b \u043f\u0435\u0440\u0435\u043c\u0435\u0449\u0430\u0435\u043c \u0443\u0437\u0435\u043b \u043d\u0430 \u043f\u043e\u043b\u0443\u0447\u0438\u0432\u0448\u0438\u0439\u0441\u044f \u0432\u0435\u043a\u0442\u043e\u0440.<\/p>\n<pre><code class=\"python\">    # class Scene     def move_selected(self, start, direction, inv_modelview):         &quot;&quot;&quot;          Move the selected node, if there is one.                      Consume:          start, direction describes the Ray to move to         mat is the modelview matrix for the scene          &quot;&quot;&quot;         if self.selected_node is None: return          # Find the current depth and location of the selected node         node = self.selected_node         depth = node.depth         oldloc = node.selected_loc          # The new location of the node is the same depth along the new ray         newloc = (start + direction * depth)          # transform the translation with the modelview matrix         translation = newloc - oldloc         pre_tran = numpy.array([translation[0], translation[1], translation[2], 0])         translation = inv_modelview.dot(pre_tran)          # translate the node and track its location         node.translate(translation[0], translation[1], translation[2])         node.selected_loc = newloc<\/code><\/pre>\n<p>  \u041e\u0431\u0440\u0430\u0442\u0438\u0442\u0435 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435, \u0447\u0442\u043e \u043d\u043e\u0432\u043e\u0435 \u0438 \u0441\u0442\u0430\u0440\u043e\u0435 \u043c\u0435\u0441\u0442\u043e\u043f\u043e\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0437\u0430\u0434\u0430\u044e\u0442\u0441\u044f \u0432 \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u043d\u043e\u043c \u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u0435 \u043a\u0430\u043c\u0435\u0440\u044b. \u041d\u0430\u043c \u043d\u0443\u0436\u043d\u043e, \u0447\u0442\u043e\u0431\u044b \u043f\u0435\u0440\u0435\u043c\u0435\u0449\u0435\u043d\u0438\u0435 \u0437\u0430\u0434\u0430\u0432\u0430\u043b\u043e\u0441\u044c \u0432 \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u043d\u043e\u043c \u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u0435 \u043c\u0438\u0440\u0430. \u0421\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e, \u043c\u044b \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u0443\u0435\u043c \u043f\u0435\u0440\u0435\u043c\u0435\u0449\u0435\u043d\u0438\u0435 \u0432 \u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u0435 \u043a\u0430\u043c\u0435\u0440\u044b \u0432 \u043f\u0435\u0440\u0435\u043c\u0435\u0449\u0435\u043d\u0438\u0435 \u0432 \u043c\u0438\u0440\u043e\u0432\u043e\u043c \u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u0435, \u0443\u043c\u043d\u043e\u0436\u0438\u0432 \u043d\u0430 \u043c\u0430\u0442\u0440\u0438\u0446\u0443, \u043e\u0431\u0440\u0430\u0442\u043d\u0443\u044e modelview.<\/p>\n<p>  \u041a\u0430\u043a \u0438 \u0432 \u0441\u043b\u0443\u0447\u0430\u0435 \u0441 \u043c\u0430\u0441\u0448\u0442\u0430\u0431\u043e\u043c, \u043a\u0430\u0436\u0434\u044b\u0439 \u0443\u0437\u0435\u043b \u0445\u0440\u0430\u043d\u0438\u0442 \u043c\u0430\u0442\u0440\u0438\u0446\u0443, \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u044e\u0449\u0443\u044e \u0435\u0433\u043e \u043f\u0435\u0440\u0435\u043c\u0435\u0449\u0435\u043d\u0438\u0435. \u041c\u0430\u0442\u0440\u0438\u0446\u0430 \u043f\u0435\u0440\u0435\u043c\u0435\u0449\u0435\u043d\u0438\u044f \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u0442\u0430\u043a:<\/p>\n<p><math><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/formulas\/fd8\/074\/2e1\/fd80742e1fd2e51b6c36f006a77e59f2.svg\" alt=\"$ \\begin{bmatrix} 1 &amp; 0 &amp; 0 &amp; x \\\\ 0 &amp; 1 &amp; 0 &amp; y \\\\ 0 &amp; 0 &amp; 1 &amp; z \\\\ 0 &amp; 0 &amp; 0 &amp; 1 \\\\ \\end{bmatrix}$\" data-tex=\"display\"><\/math><\/p>\n<p>  \u041f\u0440\u0438 \u043f\u0435\u0440\u0435\u043c\u0435\u0449\u0435\u043d\u0438\u0438 \u0443\u0437\u043b\u0430 \u043c\u044b \u0441\u043e\u0437\u0434\u0430\u0451\u043c \u043d\u043e\u0432\u0443\u044e \u043c\u0430\u0442\u0440\u0438\u0446\u0443 \u043f\u0435\u0440\u0435\u043c\u0435\u0449\u0435\u043d\u0438\u044f \u0434\u043b\u044f \u0442\u0435\u043a\u0443\u0449\u0435\u0433\u043e \u043f\u0435\u0440\u0435\u043c\u0435\u0449\u0435\u043d\u0438\u044f, \u0438 \u0443\u043c\u043d\u043e\u0436\u0430\u0435\u043c \u0435\u0451 \u043d\u0430 \u043c\u0430\u0442\u0440\u0438\u0446\u0443 \u043f\u0435\u0440\u0435\u043c\u0435\u0449\u0435\u043d\u0438\u044f \u0443\u0437\u043b\u0430, \u0447\u0442\u043e\u0431\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0432\u043e \u0432\u0440\u0435\u043c\u044f \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433\u0430.<\/p>\n<pre><code class=\"python\">    # class Node     def translate(self, x, y, z):         self.translation_matrix = numpy.dot(             self.translation_matrix,              translation([x, y, z]))<\/code><\/pre>\n<p>  \u0424\u0443\u043d\u043a\u0446\u0438\u044f <code>translation<\/code> \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u043c\u0430\u0442\u0440\u0438\u0446\u0443 \u043f\u0435\u0440\u0435\u043c\u0435\u0449\u0435\u043d\u0438\u044f, \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0443\u044e \u0441\u043f\u0438\u0441\u043a\u0443 \u0440\u0430\u0441\u0441\u0442\u043e\u044f\u043d\u0438\u0439 \u043f\u0435\u0440\u0435\u043c\u0435\u0449\u0435\u043d\u0438\u044f \u043f\u043e <math><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/formulas\/817\/b92\/407\/817b92407f764f57af9226e50cc788fd.svg\" alt=\"$x$\" data-tex=\"inline\"><\/math>, <math><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/formulas\/9b3\/4c4\/da5\/9b34c4da5c757d4982bbd1b6f2e8998a.svg\" alt=\"$y$\" data-tex=\"inline\"><\/math> \u0438 <math><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/formulas\/4ec\/3e2\/363\/4ec3e23638b6073b649999485c251c94.svg\" alt=\"$z$\" data-tex=\"inline\"><\/math>.<\/p>\n<pre><code class=\"python\">def translation(displacement):     t = numpy.identity(4)     t[0, 3] = displacement[0]     t[1, 3] = displacement[1]     t[2, 3] = displacement[2]     return t<\/code><\/pre>\n<p>  <\/p>\n<h4>\u0420\u0430\u0437\u043c\u0435\u0449\u0435\u043d\u0438\u0435 \u043d\u043e\u0432\u044b\u0445 \u0443\u0437\u043b\u043e\u0432<\/h4>\n<p>  \u0414\u043b\u044f \u0440\u0430\u0437\u043c\u0435\u0449\u0435\u043d\u0438\u044f \u0443\u0437\u043b\u043e\u0432 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442\u0441\u044f \u043c\u0435\u0442\u043e\u0434\u0438\u043a\u0438 \u0438 \u0438\u0437 \u0432\u044b\u0431\u043e\u0440\u0430, \u0438 \u0438\u0437 \u043f\u0435\u0440\u0435\u043c\u0435\u0449\u0435\u043d\u0438\u044f. \u0414\u043b\u044f \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u044f \u043c\u0435\u0441\u0442\u0430 \u0440\u0430\u0437\u043c\u0435\u0449\u0435\u043d\u0438\u044f \u0443\u0437\u043b\u0430 \u043c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u0442\u043e \u0436\u0435 \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u0435 \u043b\u0443\u0447\u0430 \u0434\u043b\u044f \u0442\u0435\u043a\u0443\u0449\u0435\u0433\u043e \u0440\u0430\u0441\u043f\u043e\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u043a\u0443\u0440\u0441\u043e\u0440\u0430 \u043c\u044b\u0448\u0438.<\/p>\n<pre><code class=\"python\">    # class Viewer     def place(self, shape, x, y):         &quot;&quot;&quot; Execute a placement of a new primitive into the scene. &quot;&quot;&quot;         start, direction = self.get_ray(x, y)         self.scene.place(shape, start, direction, self.inverseModelView)<\/code><\/pre>\n<p>  \u0414\u043b\u044f \u0440\u0430\u0437\u043c\u0435\u0449\u0435\u043d\u0438\u044f \u043d\u043e\u0432\u043e\u0433\u043e \u0443\u0437\u043b\u0430 \u043c\u044b \u0441\u043d\u0430\u0447\u0430\u043b\u0430 \u043f\u0440\u043e\u0441\u0442\u043e \u0441\u043e\u0437\u0434\u0430\u0451\u043c \u043d\u043e\u0432\u044b\u0439 \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0435\u0433\u043e \u0442\u0438\u043f\u0430 \u0443\u0437\u043b\u0430 \u0438 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u0435\u0433\u043e \u0432 \u0441\u0446\u0435\u043d\u0443. \u041c\u044b \u0445\u043e\u0442\u0438\u043c \u0440\u0430\u0437\u043c\u0435\u0441\u0442\u0438\u0442\u044c \u0443\u0437\u0435\u043b \u043f\u043e\u0434 \u043a\u0443\u0440\u0441\u043e\u0440\u043e\u043c \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043d\u0430\u0445\u043e\u0434\u0438\u043c \u0442\u043e\u0447\u043a\u0443 \u043d\u0430 \u043b\u0443\u0447\u0435 \u043d\u0430 \u0444\u0438\u043a\u0441\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u043c \u0440\u0430\u0441\u0441\u0442\u043e\u044f\u043d\u0438\u0438 \u043e\u0442 \u043a\u0430\u043c\u0435\u0440\u044b. \u041b\u0443\u0447 \u0442\u043e\u0436\u0435 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d \u0432 \u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u0435 \u043a\u0430\u043c\u0435\u0440\u044b, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043c\u044b \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u0443\u0435\u043c \u043f\u043e\u043b\u0443\u0447\u0438\u0432\u0448\u0438\u0439\u0441\u044f \u0432\u0435\u043a\u0442\u043e\u0440 \u043f\u0435\u0440\u0435\u043c\u0435\u0449\u0435\u043d\u0438\u044f \u0432 \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u043d\u043e\u0435 \u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u043e \u043c\u0438\u0440\u0430, \u0443\u043c\u043d\u043e\u0436\u0438\u0432 \u0435\u0433\u043e \u043d\u0430 \u043c\u0430\u0442\u0440\u0438\u0446\u0443, \u043e\u0431\u0440\u0430\u0442\u043d\u0443\u044e modelview. \u0417\u0430\u0442\u0435\u043c \u043c\u044b \u043f\u0435\u0440\u0435\u043c\u0435\u0449\u0430\u0435\u043c \u043d\u043e\u0432\u044b\u0439 \u0443\u0437\u0435\u043b \u043d\u0430 \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u043d\u044b\u0439 \u0432\u0435\u043a\u0442\u043e\u0440.<\/p>\n<pre><code class=\"python\">    # class Scene     def place(self, shape, start, direction, inv_modelview):         &quot;&quot;&quot;          Place a new node.                      Consume:           shape the shape to add         start, direction describes the Ray to move to         inv_modelview is the inverse modelview matrix for the scene          &quot;&quot;&quot;         new_node = None         if shape == 'sphere': new_node = Sphere()         elif shape == 'cube': new_node = Cube()         elif shape == 'figure': new_node = SnowFigure()          self.add_node(new_node)          # place the node at the cursor in camera-space         translation = (start + direction * self.PLACE_DEPTH)          # convert the translation to world-space         pre_tran = numpy.array([translation[0], translation[1], translation[2], 1])         translation = inv_modelview.dot(pre_tran)          new_node.translate(translation[0], translation[1], translation[2])<\/code><\/pre>\n<p>  <\/p>\n<h2>\u0418\u0442\u043e\u0433<\/h2>\n<p>  \u041f\u043e\u0437\u0434\u0440\u0430\u0432\u043b\u044f\u044e! \u041c\u044b \u0443\u0441\u043f\u0435\u0448\u043d\u043e \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043b\u0438 \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u043e\u0439 3D-\u0440\u0435\u0434\u0430\u043a\u0442\u043e\u0440!<\/p>\n<div style=\"text-align:center;\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/post_images\/28b\/2c8\/df7\/28b2c8df777bcae9096ff592d8fd90c4.png\" alt=\"image\"><\/div>\n<p>  <i>\u0420\u0438\u0441\u0443\u043d\u043e\u043a 4 \u2014 \u041f\u0440\u0438\u043c\u0435\u0440 \u0441\u0446\u0435\u043d\u044b<\/i><\/p>\n<p>  \u041c\u044b \u0443\u0437\u043d\u0430\u043b\u0438, \u043a\u0430\u043a \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0440\u0430\u0441\u0448\u0438\u0440\u044f\u0435\u043c\u0443\u044e \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443 \u0434\u0430\u043d\u043d\u044b\u0445, \u043e\u043f\u0438\u0441\u044b\u0432\u0430\u044e\u0449\u0443\u044e \u043c\u043e\u0434\u0435\u043b\u0438 \u0432 \u0441\u0446\u0435\u043d\u0435. \u0422\u0430\u043a\u0436\u0435 \u043c\u044b \u043f\u043e\u043d\u044f\u043b\u0438, \u0447\u0442\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u0448\u0430\u0431\u043b\u043e\u043d\u0430 \u043f\u0440\u043e\u0435\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u00ab\u041a\u043e\u043c\u043f\u043e\u043d\u043e\u0432\u0449\u0438\u043a\u00bb \u0438 \u0434\u0440\u0435\u0432\u043e\u0432\u0438\u0434\u043d\u044b\u0445 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440 \u0434\u0430\u043d\u043d\u044b\u0445 \u0443\u043f\u0440\u043e\u0449\u0430\u0435\u0442 \u043e\u0431\u0445\u043e\u0434 \u0441\u0446\u0435\u043d\u044b \u0434\u043b\u044f \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433\u0430 \u0438 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0442\u044c \u043d\u043e\u0432\u044b\u0435 \u0442\u0438\u043f\u044b \u0443\u0437\u043b\u043e\u0432 \u0431\u0435\u0437 \u043f\u043e\u0432\u044b\u0448\u0435\u043d\u0438\u044f \u0441\u043b\u043e\u0436\u043d\u043e\u0441\u0442\u0438 \u043a\u043e\u0434\u0430. \u041c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043b\u0438 \u044d\u0442\u0443 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443 \u0434\u0430\u043d\u043d\u044b\u0445 \u0434\u043b\u044f \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433\u0430 \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u043d\u0430 \u044d\u043a\u0440\u0430\u043d \u0438 \u043c\u0430\u043d\u0438\u043f\u0443\u043b\u0438\u0440\u043e\u0432\u0430\u043b\u0438 \u043c\u0430\u0442\u0440\u0438\u0446\u0430\u043c\u0438 OpenGL \u043f\u0440\u0438 \u043e\u0431\u0445\u043e\u0434\u0435 \u0433\u0440\u0430\u0444\u0430 \u0441\u0446\u0435\u043d\u044b. \u041c\u044b \u0441\u043e\u0437\u0434\u0430\u043b\u0438 \u043e\u0447\u0435\u043d\u044c \u043f\u0440\u043e\u0441\u0442\u0443\u044e \u0441\u0438\u0441\u0442\u0435\u043c\u0443 \u043e\u0431\u0440\u0430\u0442\u043d\u044b\u0445 \u0432\u044b\u0437\u043e\u0432\u043e\u0432 \u0434\u043b\u044f \u0441\u043e\u0431\u044b\u0442\u0438\u0439 \u0443\u0440\u043e\u0432\u043d\u044f \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f, \u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043b\u0438 \u0435\u0451 \u0434\u043b\u044f \u0438\u043d\u043a\u0430\u043f\u0441\u0443\u043b\u044f\u0446\u0438\u0438 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0441\u043e\u0431\u044b\u0442\u0438\u0439 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u043e\u043d\u043d\u043e\u0439 \u0441\u0438\u0441\u0442\u0435\u043c\u044b. \u0414\u0430\u043b\u0435\u0435 \u043c\u044b \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0435\u043b\u0438 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u044b\u0435 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u043e\u0431\u043d\u0430\u0440\u0443\u0436\u0435\u043d\u0438\u044f \u043a\u043e\u043b\u043b\u0438\u0437\u0438\u0439 \u043b\u0443\u0447\u0430 \u0441 \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u043c \u0438 \u043a\u043e\u043c\u043f\u0440\u043e\u043c\u0438\u0441\u0441\u044b \u043c\u0435\u0436\u0434\u0443 \u0442\u043e\u0447\u043d\u043e\u0441\u0442\u044c\u044e, \u0441\u043b\u043e\u0436\u043d\u043e\u0441\u0442\u044c\u044e \u0438 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c\u044e. \u0412 \u043a\u043e\u043d\u0446\u0435 \u043c\u044b \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043b\u0438 \u043c\u0435\u0442\u043e\u0434\u044b \u043c\u0430\u043d\u0438\u043f\u0443\u043b\u044f\u0446\u0438\u0439 \u0441 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u044b\u043c \u0441\u0446\u0435\u043d\u044b.<\/p>\n<p>  \u041f\u0440\u0438 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0435 \u043f\u043e\u043b\u043d\u043e\u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u043e\u0433\u043e 3D-\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0432\u044b \u0441\u0442\u043e\u043b\u043a\u043d\u0451\u0442\u0435\u0441\u044c \u0441 \u044d\u0442\u0438\u043c\u0438 \u0436\u0435 \u0431\u0430\u0437\u043e\u0432\u044b\u043c\u0438 \u0441\u0442\u0440\u043e\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u043c\u0438 \u0431\u043b\u043e\u043a\u0430\u043c\u0438. \u0421\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 \u0433\u0440\u0430\u0444\u0430 \u0441\u0446\u0435\u043d\u044b \u0438 \u043e\u0442\u043d\u043e\u0441\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u043d\u044b\u0435 \u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u0430 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442\u0441\u044f \u0432\u043e \u043c\u043d\u043e\u0433\u0438\u0445 \u0432\u0438\u0434\u0430\u0445 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439 \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441 3D-\u0433\u0440\u0430\u0444\u0438\u043a\u043e\u0439, \u043e\u0442 \u0421\u0410\u041f\u0420 \u0434\u043e \u0438\u0433\u0440\u043e\u0432\u044b\u0445 \u0434\u0432\u0438\u0436\u043a\u043e\u0432. \u0421\u0438\u043b\u044c\u043d\u044b\u043c \u0443\u043f\u0440\u043e\u0449\u0435\u043d\u0438\u0435\u043c \u0432 \u044d\u0442\u043e\u043c \u043f\u0440\u043e\u0435\u043a\u0442\u0435 \u0441\u0442\u0430\u043b \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f. \u0413\u043e\u0442\u043e\u0432\u044b\u0439 3D-\u0440\u0435\u0434\u0430\u043a\u0442\u043e\u0440 \u0434\u043e\u043b\u0436\u0435\u043d \u0438\u043c\u0435\u0442\u044c \u043f\u043e\u043b\u043d\u044b\u0439 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f, \u043a\u043e\u0442\u043e\u0440\u043e\u043c\u0443 \u043f\u043e\u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u0433\u043e\u0440\u0430\u0437\u0434\u043e \u0431\u043e\u043b\u0435\u0435 \u0441\u043b\u043e\u0436\u043d\u0430\u044f \u0441\u0438\u0441\u0442\u0435\u043c\u0430 \u0441\u043e\u0431\u044b\u0442\u0438\u0439, \u0447\u0435\u043c \u043d\u0430\u0448\u0430 \u043f\u0440\u043e\u0441\u0442\u0430\u044f \u0441\u0438\u0441\u0442\u0435\u043c\u0430 \u043e\u0431\u0440\u0430\u0442\u043d\u044b\u0445 \u0432\u044b\u0437\u043e\u0432\u043e\u0432.<\/p>\n<p>  \u0412\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u044d\u043a\u0441\u043f\u0435\u0440\u0438\u043c\u0435\u043d\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0434\u0430\u043b\u044c\u0448\u0435 \u0438 \u043f\u043e\u043f\u0440\u043e\u0431\u043e\u0432\u0430\u0442\u044c \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0432 \u043f\u0440\u043e\u0435\u043a\u0442 \u043d\u043e\u0432\u044b\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438. \u041f\u043e\u043f\u0440\u043e\u0431\u0443\u0439\u0442\u0435 \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u0447\u0442\u043e-\u043d\u0438\u0431\u0443\u0434\u044c \u0438\u0437 \u044d\u0442\u043e\u0433\u043e \u0441\u043f\u0438\u0441\u043a\u0430:<\/p>\n<ul>\n<li>\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0442\u0438\u043f <code>Node<\/code> \u0434\u043b\u044f \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0438 \u043c\u0435\u0448\u0435\u0439 \u0442\u0440\u0435\u0443\u0433\u043e\u043b\u044c\u043d\u0438\u043a\u043e\u0432 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u043b\u044c\u043d\u043e\u0439 \u0444\u043e\u0440\u043c\u044b.<\/li>\n<li>\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0441\u0442\u0435\u043a \u043e\u0442\u043c\u0435\u043d\u044b \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0439, \u0447\u0442\u043e\u0431\u044b \u043c\u043e\u0436\u043d\u043e \u0431\u044b\u043b\u043e \u043e\u0442\u043c\u0435\u043d\u044f\u0442\u044c\/\u043f\u043e\u0432\u0442\u043e\u0440\u044f\u0442\u044c \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f.<\/li>\n<li>\u0421\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u0435\/\u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0430 \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u0432 \u0442\u0440\u0451\u0445\u043c\u0435\u0440\u043d\u044b\u0439 \u0444\u043e\u0440\u043c\u0430\u0442 \u0444\u0430\u0439\u043b\u043e\u0432, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0432 DXF.<\/li>\n<li>\u0418\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u044f \u0434\u0432\u0438\u0436\u043a\u0430 \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433\u0430: \u044d\u043a\u0441\u043f\u043e\u0440\u0442 \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u0434\u043b\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u0432 \u0444\u043e\u0442\u043e\u0440\u0435\u0430\u043b\u0438\u0441\u0442\u0438\u0447\u043d\u043e\u043c \u0440\u0435\u043d\u0434\u0435\u0440\u0435\u0440\u0435.<\/li>\n<li>\u0423\u043b\u0443\u0447\u0448\u0438\u0442\u044c \u0440\u0430\u0441\u043f\u043e\u0437\u043d\u0430\u0432\u0430\u043d\u0438\u0435 \u043a\u043e\u043b\u043b\u0438\u0437\u0438\u0439 \u0442\u043e\u0447\u043d\u044b\u043c \u043f\u0435\u0440\u0435\u0441\u0435\u0447\u0435\u043d\u0438\u0435\u043c \u043b\u0443\u0447\u0430 \u0441 \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u043c.<\/li>\n<\/ul>\n<p>  <\/p>\n<h2>\u0414\u0430\u043b\u044c\u043d\u0435\u0439\u0448\u0435\u0435 \u0438\u0441\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u043d\u0438\u0435<\/h2>\n<p>  \u0414\u043b\u044f \u0434\u0430\u043b\u044c\u043d\u0435\u0439\u0448\u0435\u0433\u043e \u0438\u0437\u0443\u0447\u0435\u043d\u0438\u044f \u0440\u0435\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u041f\u041e 3D-\u043c\u043e\u0434\u0435\u043b\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u043e \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u043f\u0440\u043e\u0435\u043a\u0442\u044b \u0441 \u043e\u0442\u043a\u0440\u044b\u0442\u044b\u043c \u0438\u0441\u0445\u043e\u0434\u043d\u044b\u043c \u043a\u043e\u0434\u043e\u043c.<\/p>\n<p>  <a href=\"http:\/\/www.blender.org\/\" rel=\"nofollow\">Blender<\/a> \u2014 \u044d\u0442\u043e \u043f\u043e\u043b\u043d\u043e\u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u044b\u0439 \u043f\u0430\u043a\u0435\u0442 \u0434\u043b\u044f 3D-\u0430\u043d\u0438\u043c\u0430\u0446\u0438\u0439 \u0441 \u043e\u0442\u043a\u0440\u044b\u0442\u044b\u043c \u0438\u0441\u0445\u043e\u0434\u043d\u044b\u043c \u043a\u043e\u0434\u043e\u043c. \u0412 \u043d\u0451\u043c \u0435\u0441\u0442\u044c \u043f\u043e\u043b\u043d\u044b\u0439 3D-\u043a\u043e\u043d\u0432\u0435\u0439\u0435\u0440 \u0434\u043b\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0441\u043f\u0435\u0446\u044d\u0444\u0444\u0435\u043a\u0442\u043e\u0432 \u0432 \u0432\u0438\u0434\u0435\u043e \u0438\u043b\u0438 \u0434\u043b\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0438\u0433\u0440. \u041c\u043e\u0434\u0435\u043b\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u2014 \u044d\u0442\u043e \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u0430\u044f \u0447\u0430\u0441\u0442\u044c \u0434\u0430\u043d\u043d\u043e\u0433\u043e \u043f\u0440\u043e\u0435\u043a\u0442\u0430, \u0438 \u043e\u043d\u043e \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0445\u043e\u0440\u043e\u0448\u0438\u043c \u043f\u0440\u0438\u043c\u0435\u0440\u043e\u043c \u0438\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u0438 \u043c\u043e\u0434\u0435\u043b\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0432 \u0431\u043e\u043b\u044c\u0448\u043e\u0439 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u043d\u044b\u0439 \u043f\u0430\u043a\u0435\u0442.<\/p>\n<p>  <a href=\"http:\/\/www.openscad.org\/\" rel=\"nofollow\">OpenSCAD<\/a> \u2014 \u044d\u0442\u043e \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442 \u0434\u043b\u044f 3D-\u043c\u043e\u0434\u0435\u043b\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0441 \u043e\u0442\u043a\u0440\u044b\u0442\u044b\u043c \u0438\u0441\u0445\u043e\u0434\u043d\u044b\u043c \u043a\u043e\u0434\u043e\u043c. \u041e\u043d \u043d\u0435 \u0438\u043d\u0442\u0435\u0440\u0430\u043a\u0442\u0438\u0432\u0435\u043d \u2014 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0430 \u0441\u0447\u0438\u0442\u044b\u0432\u0430\u0435\u0442 \u0441\u043a\u0440\u0438\u043f\u0442, \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u044e\u0449\u0438\u0439, \u043a\u0430\u043a \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0441\u0446\u0435\u043d\u0443. \u042d\u0442\u043e \u0434\u0430\u0451\u0442 \u043f\u0440\u043e\u0435\u043a\u0442\u0438\u0440\u043e\u0432\u0449\u0438\u043a\u0443 \u00ab\u043f\u043e\u043b\u043d\u044b\u0439 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u044c \u043d\u0430\u0434 \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u043e\u043c \u043c\u043e\u0434\u0435\u043b\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f\u00bb.<\/p>\n<p>  \u041f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435 \u043e\u0431 \u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c\u0430\u0445 \u0438 \u0442\u0435\u0445\u043d\u0438\u043a\u0430\u0445 \u043a\u043e\u043c\u043f\u044c\u044e\u0442\u0435\u0440\u043d\u043e\u0439 \u0433\u0440\u0430\u0444\u0438\u043a\u0438 \u043c\u043e\u0436\u043d\u043e \u0443\u0437\u043d\u0430\u0442\u044c \u0438\u0437 \u0437\u0430\u043c\u0435\u0447\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0433\u043e \u0440\u0435\u0441\u0443\u0440\u0441\u0430 <a href=\"http:\/\/tog.acm.org\/resources\/GraphicsGems\/\" rel=\"nofollow\">Graphics Gems<\/a>.<\/p>\n<h2>\u041e\u0431 \u0430\u0432\u0442\u043e\u0440\u0435<\/h2>\n<p>  \u042d\u0440\u0438\u043a \u2014 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a \u041f\u041e \u0438 \u0444\u0430\u043d\u0430\u0442 \u0434\u0432\u0443\u0445\u043c\u0435\u0440\u043d\u043e\u0439 \u0438 \u0442\u0440\u0451\u0445\u043c\u0435\u0440\u043d\u043e\u0439 \u043a\u043e\u043c\u043f\u044c\u044e\u0442\u0435\u0440\u043d\u043e\u0439 \u0433\u0440\u0430\u0444\u0438\u043a\u0438. \u041e\u043d \u0437\u0430\u043d\u0438\u043c\u0430\u043b\u0441\u044f \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u043e\u0439 \u0432\u0438\u0434\u0435\u043e\u0438\u0433\u0440, \u041f\u041e \u0434\u043b\u044f \u0442\u0440\u0451\u0445\u043c\u0435\u0440\u043d\u044b\u0445 \u0441\u043f\u0435\u0446\u044d\u0444\u0444\u0435\u043a\u0442\u043e\u0432 \u0438 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u043e\u0432 \u0421\u0410\u041f\u0420. \u0415\u0441\u043b\u0438 \u0434\u0435\u043b\u043e \u043a\u0430\u0441\u0430\u0435\u0442\u0441\u044f \u0441\u0438\u043c\u0443\u043b\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0440\u0435\u0430\u043b\u044c\u043d\u043e\u0441\u0442\u0438, \u0442\u043e \u0435\u0441\u0442\u044c \u0432\u0435\u0440\u043e\u044f\u0442\u043d\u043e\u0441\u0442\u044c, \u0447\u0442\u043e \u0435\u043c\u0443 \u0437\u0430\u0445\u043e\u0447\u0435\u0442\u0441\u044f \u043e\u0431 \u044d\u0442\u043e\u043c \u0443\u0437\u043d\u0430\u0442\u044c. \u041d\u0430\u0439\u0442\u0438 \u0435\u0433\u043e \u043e\u043d\u043b\u0430\u0439\u043d \u043c\u043e\u0436\u043d\u043e \u043d\u0430 \u0441\u0430\u0439\u0442\u0435 <a href=\"http:\/\/erickdransch.com\" rel=\"nofollow\">erickdransch.com<\/a>.<\/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\/post\/527914\/\"> https:\/\/habr.com\/ru\/post\/527914\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"\n<div class=\"post__text post__text-html post__text_v1\" id=\"post-content-body\">\n<div style=\"text-align:center;\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/post_images\/1b6\/d49\/be0\/1b6d49be070fb475dde98d84f4263c95.png\" alt=\"image\"><\/div>\n<p>  <\/p>\n<h2>\u0412\u0432\u0435\u0434\u0435\u043d\u0438\u0435<\/h2>\n<p>  \u041b\u044e\u0434\u0438 \u043e\u0442 \u043f\u0440\u0438\u0440\u043e\u0434\u044b \u043a\u0440\u0435\u0430\u0442\u0438\u0432\u043d\u044b. \u041c\u044b \u043f\u043e\u0441\u0442\u043e\u044f\u043d\u043d\u043e \u043f\u0440\u043e\u0435\u043a\u0442\u0438\u0440\u0443\u0435\u043c \u0438 \u0441\u043e\u0437\u0434\u0430\u0451\u043c \u043d\u043e\u0432\u044b\u0435, \u043f\u043e\u043b\u0435\u0437\u043d\u044b\u0435 \u0438 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u044b\u0435 \u0432\u0435\u0449\u0438. \u0421\u0435\u0433\u043e\u0434\u043d\u044f \u043c\u044b \u043f\u0438\u0448\u0435\u043c \u041f\u041e, \u043f\u043e\u043c\u043e\u0433\u0430\u044e\u0449\u0435\u0435 \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u0443 \u043f\u0440\u043e\u0435\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0438 \u0442\u0432\u043e\u0440\u0447\u0435\u0441\u0442\u0432\u0430. \u041f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b \u0421\u0410\u041f\u0420 (Computer-aided design, CAD) \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u044e\u0442 \u0442\u0432\u043e\u0440\u0446\u0430\u043c \u043f\u0440\u043e\u0435\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0437\u0434\u0430\u043d\u0438\u044f, \u043c\u043e\u0441\u0442\u044b, \u0433\u0440\u0430\u0444\u0438\u043a\u0443 \u0432\u0438\u0434\u0435\u043e\u0438\u0433\u0440, \u0447\u0443\u0434\u043e\u0432\u0438\u0449 \u0434\u043b\u044f \u0444\u0438\u043b\u044c\u043c\u043e\u0432, \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432 \u0434\u043b\u044f 3D-\u043f\u0435\u0447\u0430\u0442\u0438 \u0438 \u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u043e \u0434\u0440\u0443\u0433\u0438\u0445 \u0432\u0435\u0449\u0435\u0439 \u043f\u0435\u0440\u0435\u0434 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435\u043c \u0444\u0438\u0437\u0438\u0447\u0435\u0441\u043a\u043e\u0439 \u0432\u0435\u0440\u0441\u0438\u0438 \u043f\u0440\u043e\u0435\u043a\u0442\u0430.<\/p>\n<p>  \u041f\u043e \u0441\u0432\u043e\u0435\u0439 \u0441\u0443\u0442\u0438, \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u044b CAD \u044f\u0432\u043b\u044f\u044e\u0442\u0441\u044f \u0441\u043f\u043e\u0441\u043e\u0431\u043e\u043c \u0430\u0431\u0441\u0442\u0440\u0430\u0433\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0442\u0440\u0451\u0445\u043c\u0435\u0440\u043d\u043e\u0433\u043e \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u0432 \u043d\u0435\u0447\u0442\u043e, \u0447\u0442\u043e \u043c\u043e\u0436\u043d\u043e \u043f\u0440\u043e\u0441\u043c\u0430\u0442\u0440\u0438\u0432\u0430\u0442\u044c \u0438 \u0440\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043d\u0430 \u0434\u0432\u0443\u0445\u043c\u0435\u0440\u043d\u043e\u043c \u044d\u043a\u0440\u0430\u043d\u0435. \u0427\u0442\u043e\u0431\u044b \u0441\u043f\u0440\u0430\u0432\u043b\u044f\u0442\u044c\u0441\u044f \u0441\u043e \u0441\u0432\u043e\u0435\u0439 \u0437\u0430\u0434\u0430\u0447\u0435\u0439, \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u044b CAD \u0434\u043e\u043b\u0436\u043d\u044b \u043e\u0431\u0435\u0441\u043f\u0435\u0447\u0438\u0432\u0430\u0442\u044c \u0442\u0440\u0438 \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u0445 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u043e\u0441\u0442\u0438. \u0412\u043e-\u043f\u0435\u0440\u0432\u044b\u0445, \u043e\u043d\u0438 \u0434\u043e\u043b\u0436\u043d\u044b \u0438\u043c\u0435\u0442\u044c \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443 \u0434\u0430\u043d\u043d\u044b\u0445, \u043e\u043f\u0438\u0441\u044b\u0432\u0430\u044e\u0449\u0443\u044e \u043f\u0440\u043e\u0435\u043a\u0442\u0438\u0440\u0443\u0435\u043c\u044b\u0439 \u043e\u0431\u044a\u0435\u043a\u0442: \u044d\u0442\u043e \u0442\u043e, \u043a\u0430\u043a \u043a\u043e\u043c\u043f\u044c\u044e\u0442\u0435\u0440 \u043f\u043e\u043d\u0438\u043c\u0430\u0435\u0442 \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0435\u043c\u044b\u0439 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u043c \u0442\u0440\u0451\u0445\u043c\u0435\u0440\u043d\u044b\u0439 \u043c\u0438\u0440. \u0412\u043e-\u0432\u0442\u043e\u0440\u044b\u0445, \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442 CAD \u0434\u043e\u043b\u0436\u0435\u043d \u043e\u0431\u0435\u0441\u043f\u0435\u0447\u0438\u0432\u0430\u0442\u044c \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u043d\u0430 \u044d\u043a\u0440\u0430\u043d\u0435 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f. \u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043f\u0440\u043e\u0435\u043a\u0442\u0438\u0440\u0443\u0435\u0442 \u0444\u0438\u0437\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u043e\u0431\u044a\u0435\u043a\u0442 \u0441 \u0442\u0440\u0435\u043c\u044f \u0438\u0437\u043c\u0435\u0440\u0435\u043d\u0438\u044f\u043c\u0438, \u043d\u043e \u044d\u043a\u0440\u0430\u043d \u043a\u043e\u043c\u043f\u044c\u044e\u0442\u0435\u0440\u0430 \u0438\u043c\u0435\u0435\u0442 \u0432\u0441\u0435\u0433\u043e \u0434\u0432\u0430 \u0438\u0437\u043c\u0435\u0440\u0435\u043d\u0438\u044f. \u0418\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442 CAD \u0434\u043e\u043b\u0436\u0435\u043d \u043c\u043e\u0434\u0435\u043b\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0441\u043f\u043e\u0441\u043e\u0431 \u0432\u043e\u0441\u043f\u0440\u0438\u044f\u0442\u0438\u044f \u043d\u0430\u043c\u0438 \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432 \u0438 \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u044b\u0432\u0430\u0442\u044c \u0438\u0445 \u043d\u0430 \u044d\u043a\u0440\u0430\u043d\u0435 \u0442\u0430\u043a, \u0447\u0442\u043e\u0431\u044b \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u0441\u043c\u043e\u0433 \u043f\u043e\u043d\u044f\u0442\u044c \u0432\u0441\u0435 \u0442\u0440\u0438 \u0438\u0437\u043c\u0435\u0440\u0435\u043d\u0438\u044f \u043e\u0431\u044a\u0435\u043a\u0442\u0430. \u0412-\u0442\u0440\u0435\u0442\u044c\u0438\u0445, CAD \u0434\u043e\u043b\u0436\u0435\u043d \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0442\u044c \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f \u0441 \u043f\u0440\u043e\u0435\u043a\u0442\u0438\u0440\u0443\u0435\u043c\u044b\u043c \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u043c. \u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u0434\u043e\u043b\u0436\u0435\u043d \u0431\u044b\u0442\u044c \u0441\u043f\u043e\u0441\u043e\u0431\u0435\u043d \u0434\u043e\u043f\u043e\u043b\u043d\u044f\u0442\u044c \u0438\u043b\u0438 \u043c\u043e\u0434\u0438\u0444\u0438\u0446\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043f\u0440\u043e\u0435\u043a\u0442, \u0447\u0442\u043e\u0431\u044b \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u043d\u0443\u0436\u043d\u044b\u0439 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442. \u041a\u0440\u043e\u043c\u0435 \u0442\u043e\u0433\u043e, \u0432\u0441\u0435 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u044b \u0434\u043e\u043b\u0436\u043d\u044b \u0438\u043c\u0435\u0442\u044c \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u0438 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u043f\u0440\u043e\u0435\u043a\u0442\u043e\u0432 \u0441 \u0434\u0438\u0441\u043a\u0430, \u0447\u0442\u043e\u0431\u044b \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0438 \u043c\u043e\u0433\u043b\u0438 \u0441\u043e\u0442\u0440\u0443\u0434\u043d\u0438\u0447\u0430\u0442\u044c, \u043e\u0431\u043c\u0435\u043d\u0438\u0432\u0430\u0442\u044c\u0441\u044f \u0441\u0432\u043e\u0435\u0439 \u0440\u0430\u0431\u043e\u0442\u043e\u0439 \u0438 \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0442\u044c \u0435\u0451.  <\/p>\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-314338","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/314338","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=314338"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/314338\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=314338"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=314338"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=314338"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}