Compare commits
10 commits
fb49164b15
...
2adcb73c8b
Author | SHA1 | Date | |
---|---|---|---|
2adcb73c8b | |||
b711b965a3 | |||
ccc67783d0 | |||
1e2821bd04 | |||
d5b064adcc | |||
e3c61f7d78 | |||
6c235d1b4c | |||
e7072bf822 | |||
80533ed026 | |||
f2e0e0f461 |
23 changed files with 209 additions and 213 deletions
|
@ -6,8 +6,6 @@
|
||||||
│ ├─ <a href='jekyll_site/_includes'>_includes</a>
|
│ ├─ <a href='jekyll_site/_includes'>_includes</a>
|
||||||
│ │ ├─ <a href='jekyll_site/_includes/classes-point-cube-en.md'>classes-point-cube-en.md</a>
|
│ │ ├─ <a href='jekyll_site/_includes/classes-point-cube-en.md'>classes-point-cube-en.md</a>
|
||||||
│ │ ├─ <a href='jekyll_site/_includes/classes-point-cube-ru.md'>classes-point-cube-ru.md</a>
|
│ │ ├─ <a href='jekyll_site/_includes/classes-point-cube-ru.md'>classes-point-cube-ru.md</a>
|
||||||
│ │ ├─ <a href='jekyll_site/_includes/counters_body.html'>counters_body.html</a>
|
|
||||||
│ │ ├─ <a href='jekyll_site/_includes/counters_head.html'>counters_head.html</a>
|
|
||||||
│ │ ├─ <a href='jekyll_site/_includes/volumetric-tetris-en.html'>volumetric-tetris-en.html</a>
|
│ │ ├─ <a href='jekyll_site/_includes/volumetric-tetris-en.html'>volumetric-tetris-en.html</a>
|
||||||
│ │ └─ <a href='jekyll_site/_includes/volumetric-tetris-ru.html'>volumetric-tetris-ru.html</a>
|
│ │ └─ <a href='jekyll_site/_includes/volumetric-tetris-ru.html'>volumetric-tetris-ru.html</a>
|
||||||
│ ├─ <a href='jekyll_site/css'>css</a>/<a href='jekyll_site/css/pomodoro1.css'>pomodoro1.css</a>
|
│ ├─ <a href='jekyll_site/css'>css</a>/<a href='jekyll_site/css/pomodoro1.css'>pomodoro1.css</a>
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
© Головин Г.Г., 2021-2023
|
© Головин Г.Г., 2021-2024
|
||||||
|
|
||||||
Опубликовано под [Открытой лицензией 1.1](OPEN_LICENSE.txt)
|
Опубликовано под [Открытой лицензией 1.1](OPEN_LICENSE.txt)
|
||||||
|
|
||||||
|
@ -8,7 +8,7 @@
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
© Golovin G.G., translation from Russian, 2021-2023
|
© Golovin G.G., translation from Russian, 2021-2024
|
||||||
|
|
||||||
Published under the [Open License 1.1](OPEN_LICENSE.txt)
|
Published under the [Open License 1.1](OPEN_LICENSE.txt)
|
||||||
|
|
||||||
|
|
90
build.sh
90
build.sh
|
@ -1,39 +1,37 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
echo "Сборка сайта в двух помидорных темах и оптимизация результатов."
|
echo "Сборка сайта в двух помидорных темах и оптимизация результатов."
|
||||||
currentTimeMillis=$(date '+%s%3N')
|
time_ms="$(date '+%s%3N')"
|
||||||
rm -rf _site
|
# удаление каталогов предыдущей сборки, если таковые имеются
|
||||||
rm -rf _site_older
|
find . -maxdepth 1 -type d -name "_site*" -exec rm -rf {} \;
|
||||||
rm -rf _site_color
|
# сборка сайта в двух помидорных темах
|
||||||
echo "Сборка старого помидора."
|
function jekyll_build {
|
||||||
mkdir -p _site_older
|
case "$1" in
|
||||||
cp -r jekyll_site/_includes _site_older
|
"older") echo "Сборка старого помидора." ;;
|
||||||
cp -r jekyll_site/ru _site_older
|
"color") echo "Сборка цветного помидора." ;;
|
||||||
cp -r jekyll_site/en _site_older
|
*) return ;; # две помидорные темы оформления
|
||||||
cp -r jekyll_site/ru/index.md _site_older
|
esac
|
||||||
cp -r jekyll_site/_config_older.yml _site_older/_config.yml
|
mkdir -p "_site_$1"
|
||||||
cp -r jekyll_site/Gemfile_older _site_older/Gemfile
|
cp -r "jekyll_site/_includes" "_site_$1"
|
||||||
cd _site_older || exit
|
cp -r "jekyll_site/ru" "_site_$1"
|
||||||
jekyll build --disable-disk-cache
|
cp -r "jekyll_site/en" "_site_$1"
|
||||||
cp -r _site ..
|
cp -r "jekyll_site/ru/index.md" "_site_$1"
|
||||||
cd ..
|
cp -r "jekyll_site/_config_$1.yml" "_site_$1/_config.yml"
|
||||||
echo "Сборка цветного помидора."
|
cp -r "jekyll_site/Gemfile_$1" "_site_$1/Gemfile"
|
||||||
mkdir -p _site_color
|
cd "_site_$1" || return
|
||||||
cp -r jekyll_site/_includes _site_color
|
jekyll build --disable-disk-cache --quiet
|
||||||
cp -r jekyll_site/ru _site_color
|
}
|
||||||
cp -r jekyll_site/en _site_color
|
export -f jekyll_build
|
||||||
cp -r jekyll_site/ru/index.md _site_color
|
# запуск параллельной сборки сайта в двух помидорных темах оформления
|
||||||
cp -r jekyll_site/_config_color.yml _site_color/_config.yml
|
printf 'jekyll_build "%s"\0' {older,color} | xargs -n1 -0 -P0 bash -c
|
||||||
cp -r jekyll_site/Gemfile_color _site_color/Gemfile
|
# объединение двух сборок
|
||||||
cd _site_color || exit
|
cp -r _site_older/_site .
|
||||||
jekyll build --disable-disk-cache
|
cp -r _site_color/_site ./_site/color
|
||||||
cp -r _site ../_site/color
|
# копирование без сборки
|
||||||
cd ..
|
|
||||||
echo "Копирование без сборки."
|
|
||||||
cp -r jekyll_site/css _site
|
cp -r jekyll_site/css _site
|
||||||
cp -r jekyll_site/img _site
|
cp -r jekyll_site/img _site
|
||||||
cp -r jekyll_site/js _site
|
cp -r jekyll_site/js _site
|
||||||
cp -r jekyll_site/robots.txt _site
|
cp -r jekyll_site/robots.txt _site
|
||||||
echo "Оптимизация собранного контента."
|
# оптимизация собранного контента
|
||||||
cd _site || exit
|
cd _site || exit
|
||||||
cp -r assets/* .
|
cp -r assets/* .
|
||||||
rm -r assets
|
rm -r assets
|
||||||
|
@ -41,16 +39,22 @@ rm -r color/assets/favicon.ico
|
||||||
cp -r color/assets/* .
|
cp -r color/assets/* .
|
||||||
rm -r color/assets
|
rm -r color/assets
|
||||||
rm -r color/404.html
|
rm -r color/404.html
|
||||||
find . -type f -name '*.html' | sort -r | while read -r file; do
|
rm -r color/return.html
|
||||||
sed -i 's/layout-padding=""/layout-padding/g' "$file"
|
# шаблоны для оптимизации ряда тегов
|
||||||
sed -i 's/ class="language-plaintext highlighter-rouge"//g' "$file"
|
expr+=('s|layout-padding=""|layout-padding|g')
|
||||||
sed -i 's/ class="language-java highlighter-rouge"//g' "$file"
|
expr+=('s| class="language-plaintext highlighter-rouge"||g')
|
||||||
sed -i 's/ class="language-html highlighter-rouge"//g' "$file"
|
expr+=('s| class="language-java highlighter-rouge"||g')
|
||||||
sed -i 's/ class="language-js highlighter-rouge"//g' "$file"
|
expr+=('s| class="language-html highlighter-rouge"||g')
|
||||||
sed -i 's/<div><div class="highlight"><pre class="highlight">/<div class="highlight"><pre class="highlight">/g' "$file"
|
expr+=('s| class="language-js highlighter-rouge"||g')
|
||||||
sed -i 's/<\/code><\/pre><\/div><\/div>/<\/code><\/pre><\/div>/g' "$file"
|
expr+=('s|<div><div class="highlight">|<div class="highlight">|g')
|
||||||
sed -i 's/<hr \/>/<hr>/g' "$file"
|
expr+=('s|</pre></div></div>|</pre></div>|g')
|
||||||
sed -i -r 's/<input(.+) \/>/<input\1>/g' "$file"
|
expr+=('s|<hr />|<hr>|g')
|
||||||
sed -i -r 's/<img(.+) \/>/<img\1>/g' "$file"
|
expr+=('s|<input(.+) />|<input\1>|g')
|
||||||
done
|
expr+=('s|<img(.+) />|<img\1>|g')
|
||||||
echo "Время выполнения сборки: $(("$(date '+%s%3N')" - "$currentTimeMillis")) мс."
|
# запуск параллельной обработки собранных страниц и оптимизация ряда тегов
|
||||||
|
find . -type f -name "*.html" -printf '%p\0' | xargs -I{} -n1 -0 -P0 bash -c \
|
||||||
|
"echo 'Оптимизация: {}' && sed -i -E $(printf " -e '%s'" "${expr[@]}") '{}'"
|
||||||
|
# переход в корень сайта для каталогов без заглавной страницы
|
||||||
|
find . -type d -exec cp -n return.html {}/index.html \;
|
||||||
|
rm -r return.html
|
||||||
|
echo "Общее время выполнения: $(($(date '+%s%3N') - time_ms)) мс."
|
||||||
|
|
|
@ -4,12 +4,12 @@ name: "Код с комментариями"
|
||||||
name_translated: "Code with comments"
|
name_translated: "Code with comments"
|
||||||
# URL адрес сайта, включая протокол
|
# URL адрес сайта, включая протокол
|
||||||
url: "https://pomodoro1.mircloud.ru"
|
url: "https://pomodoro1.mircloud.ru"
|
||||||
# подпапка этой сборки для относительных URLs
|
# подпапка этой сборки для относительных URL-ов
|
||||||
baseurl: "/color"
|
baseurl: "/color"
|
||||||
# ссылка в верхнем левом углу заглавных страниц
|
# ссылка в верхнем левом углу заглавных страниц
|
||||||
homepage_url: "https://git.org.ru/pomodoro/1"
|
homepage_url: "https://gitea.com/pomodoro/1"
|
||||||
# представление ссылки
|
# представление ссылки
|
||||||
homepage_name: "GIT.ORG.RU"
|
homepage_name: "GITEA"
|
||||||
# подпапка альтернативной сборки
|
# подпапка альтернативной сборки
|
||||||
older_tomato_baseurl: ""
|
older_tomato_baseurl: ""
|
||||||
# часовой пояс для формата даты ISO-8601
|
# часовой пояс для формата даты ISO-8601
|
||||||
|
@ -20,6 +20,9 @@ author: "Головин Г.Г."
|
||||||
author_translated: "Golovin G.G."
|
author_translated: "Golovin G.G."
|
||||||
# дополнение к подписи в футере для переведённых страниц
|
# дополнение к подписи в футере для переведённых страниц
|
||||||
translation_caption: "translation from Russian"
|
translation_caption: "translation from Russian"
|
||||||
|
# номера счётчиков для страниц
|
||||||
|
live_internet: "pomodoro"
|
||||||
|
yandex_metrika: "95699479"
|
||||||
# тема оформления для сборки
|
# тема оформления для сборки
|
||||||
theme: color-tomato-theme
|
theme: color-tomato-theme
|
||||||
# макет для сборки
|
# макет для сборки
|
||||||
|
|
|
@ -4,12 +4,12 @@ name: "Код с комментариями"
|
||||||
name_translated: "Code with comments"
|
name_translated: "Code with comments"
|
||||||
# URL адрес сайта, включая протокол
|
# URL адрес сайта, включая протокол
|
||||||
url: "https://pomodoro1.mircloud.ru"
|
url: "https://pomodoro1.mircloud.ru"
|
||||||
# подпапка этой сборки для относительных URLs
|
# подпапка этой сборки для относительных URL-ов
|
||||||
baseurl: ""
|
baseurl: ""
|
||||||
# ссылка в верхнем левом углу заглавных страниц
|
# ссылка в верхнем левом углу заглавных страниц
|
||||||
homepage_url: "https://git.org.ru/pomodoro/1"
|
homepage_url: "https://gitea.com/pomodoro/1"
|
||||||
# представление ссылки
|
# представление ссылки
|
||||||
homepage_name: "GIT.ORG.RU"
|
homepage_name: "GITEA"
|
||||||
# подпапка альтернативной сборки
|
# подпапка альтернативной сборки
|
||||||
color_tomato_baseurl: "/color"
|
color_tomato_baseurl: "/color"
|
||||||
# часовой пояс для формата даты ISO-8601
|
# часовой пояс для формата даты ISO-8601
|
||||||
|
@ -20,6 +20,9 @@ author: "Головин Г.Г."
|
||||||
author_translated: "Golovin G.G."
|
author_translated: "Golovin G.G."
|
||||||
# дополнение к подписи в футере для переведённых страниц
|
# дополнение к подписи в футере для переведённых страниц
|
||||||
translation_caption: "translation from Russian"
|
translation_caption: "translation from Russian"
|
||||||
|
# номера счётчиков для страниц
|
||||||
|
live_internet: "pomodoro"
|
||||||
|
yandex_metrika: "95699479"
|
||||||
# тема оформления для сборки
|
# тема оформления для сборки
|
||||||
theme: older-tomato-theme
|
theme: older-tomato-theme
|
||||||
# макет для сборки
|
# макет для сборки
|
||||||
|
|
|
@ -1,2 +0,0 @@
|
||||||
<noscript><div><img src="https://mc.yandex.ru/watch/85726914" style="position:absolute; left:-9999px;" alt=""></div></noscript>
|
|
||||||
<!-- /Yandex.Metrika counter -->
|
|
|
@ -1,16 +0,0 @@
|
||||||
<!-- Google tag (gtag.js) -->
|
|
||||||
<script async src="https://www.googletagmanager.com/gtag/js?id=G-1L7J3YNRZ7"></script>
|
|
||||||
<script>
|
|
||||||
window.dataLayer = window.dataLayer || [];
|
|
||||||
function gtag(){dataLayer.push(arguments);}
|
|
||||||
gtag('js', new Date());
|
|
||||||
gtag('config', 'G-1L7J3YNRZ7');
|
|
||||||
</script>
|
|
||||||
<!-- Yandex.Metrika counter -->
|
|
||||||
<script>
|
|
||||||
(function(m,e,t,r,i,k,a){m[i]=m[i]||function(){(m[i].a=m[i].a||[]).push(arguments)};
|
|
||||||
m[i].l=1*new Date();for(var j=0;j<document.scripts.length;j++){if(document.scripts[j].src===r){return;}}
|
|
||||||
k=e.createElement(t),a=e.getElementsByTagName(t)[0],k.async=1,k.src=r,a.parentNode.insertBefore(k,a)})
|
|
||||||
(window,document,"script","https://mc.yandex.ru/metrika/tag.js","ym");
|
|
||||||
ym(85726914,"init",{clickmap:true,trackLinks:true,accurateTrackBounce:true,webvisor:true});
|
|
||||||
</script>
|
|
|
@ -17,12 +17,12 @@
|
||||||
<div style="display: flex; flex-direction: row; align-items: start; flex-wrap: wrap;">
|
<div style="display: flex; flex-direction: row; align-items: start; flex-wrap: wrap;">
|
||||||
<div style="padding: 0 8px 8px 0;">
|
<div style="padding: 0 8px 8px 0;">
|
||||||
<canvas id="container">
|
<canvas id="container">
|
||||||
<p>Your browser does not support Canvas</p>
|
<p>Canvas for displaying computations results</p>
|
||||||
</canvas>
|
</canvas>
|
||||||
</div>
|
</div>
|
||||||
<div style="padding: 0 8px 8px 0;">
|
<div style="padding: 0 8px 8px 0;">
|
||||||
<canvas id="next">
|
<canvas id="next">
|
||||||
<p>Your browser does not support Canvas</p>
|
<p>Canvas for displaying computations results</p>
|
||||||
</canvas>
|
</canvas>
|
||||||
</div>
|
</div>
|
||||||
<div style="display: flex; flex-direction: column; align-items: start;">
|
<div style="display: flex; flex-direction: column; align-items: start;">
|
||||||
|
@ -102,7 +102,7 @@
|
||||||
<label for="dist">Z</label>
|
<label for="dist">Z</label>
|
||||||
<output id="oDist" name="oDist">640</output>
|
<output id="oDist" name="oDist">640</output>
|
||||||
</div>
|
</div>
|
||||||
<label for="center">Show the central point:</label>
|
<label for="center">Move the central point:</label>
|
||||||
<input type="checkbox" id="center" name="center" oninput="showCenter(event)">
|
<input type="checkbox" id="center" name="center" oninput="showCenter(event)">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -17,12 +17,12 @@
|
||||||
<div style="display: flex; flex-direction: row; align-items: start; flex-wrap: wrap;">
|
<div style="display: flex; flex-direction: row; align-items: start; flex-wrap: wrap;">
|
||||||
<div style="padding: 0 8px 8px 0;">
|
<div style="padding: 0 8px 8px 0;">
|
||||||
<canvas id="container">
|
<canvas id="container">
|
||||||
<p>Ваш браузер не поддерживает Canvas</p>
|
<p>Холст для отображения результатов вычислений</p>
|
||||||
</canvas>
|
</canvas>
|
||||||
</div>
|
</div>
|
||||||
<div style="padding: 0 8px 8px 0;">
|
<div style="padding: 0 8px 8px 0;">
|
||||||
<canvas id="next">
|
<canvas id="next">
|
||||||
<p>Ваш браузер не поддерживает Canvas</p>
|
<p>Холст для отображения результатов вычислений</p>
|
||||||
</canvas>
|
</canvas>
|
||||||
</div>
|
</div>
|
||||||
<div style="display: flex; flex-direction: column; align-items: start;">
|
<div style="display: flex; flex-direction: column; align-items: start;">
|
||||||
|
@ -102,7 +102,7 @@
|
||||||
<label for="dist">Z</label>
|
<label for="dist">Z</label>
|
||||||
<output id="oDist" name="oDist">640</output>
|
<output id="oDist" name="oDist">640</output>
|
||||||
</div>
|
</div>
|
||||||
<label for="center">Показать центральную точку:</label>
|
<label for="center">Двигать центральную точку:</label>
|
||||||
<input type="checkbox" id="center" name="center" oninput="showCenter(event)">
|
<input type="checkbox" id="center" name="center" oninput="showCenter(event)">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -35,7 +35,7 @@ with lines and draw lines on the canvas. We renew the image at a frequency of 20
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<canvas id="canvas" width="300" height="300" style="border: 1px solid gray;">
|
<canvas id="canvas" width="300" height="300" style="border: 1px solid gray;">
|
||||||
<p>Your browser does not support Canvas</p>
|
<p>Canvas for displaying computations results</p>
|
||||||
</canvas>
|
</canvas>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -43,7 +43,7 @@ with lines and draw lines on the canvas. We renew the image at a frequency of 20
|
||||||
|
|
||||||
```html
|
```html
|
||||||
<canvas id="canvas" width="300" height="300" style="border: 1px solid gray;">
|
<canvas id="canvas" width="300" height="300" style="border: 1px solid gray;">
|
||||||
<p>Your browser does not support Canvas</p>
|
<p>Canvas for displaying computations results</p>
|
||||||
</canvas>
|
</canvas>
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -116,7 +116,7 @@ central point — counterclockwise. This code works in conjunction with the prev
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<canvas id="canvas2" width="300" height="300" style="border: 1px solid gray;">
|
<canvas id="canvas2" width="300" height="300" style="border: 1px solid gray;">
|
||||||
<p>Your browser does not support Canvas</p>
|
<p>Canvas for displaying computations results</p>
|
||||||
</canvas>
|
</canvas>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -124,7 +124,7 @@ central point — counterclockwise. This code works in conjunction with the prev
|
||||||
|
|
||||||
```html
|
```html
|
||||||
<canvas id="canvas2" width="300" height="300" style="border: 1px solid gray;">
|
<canvas id="canvas2" width="300" height="300" style="border: 1px solid gray;">
|
||||||
<p>Your browser does not support Canvas</p>
|
<p>Canvas for displaying computations results</p>
|
||||||
</canvas>
|
</canvas>
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
title: Spinning cube in space
|
title: Spinning cube in space
|
||||||
description: We consider the difference between parallel and perspective projection. Both are widely used in practice for various purposes. In the previous example, we...
|
description: We consider the difference between parallel and perspective projection. Both are widely used in practice for various purposes. In the previous example, we...
|
||||||
sections: [Linear perspective,Rotation matrix,Experimental model]
|
sections: [Linear perspective,Rotation matrix,Experimental model]
|
||||||
tags: [javascript,online,canvas,geometry,graphics,image,picture,square,cube]
|
tags: [javascript,online,canvas,geometry,graphics,image,picture,square,cube,3d,three-dimensional]
|
||||||
scripts: [/js/classes-point-cube.js,/js/spinning-cube.js,/js/spinning-cube2.js]
|
scripts: [/js/classes-point-cube.js,/js/spinning-cube.js,/js/spinning-cube2.js]
|
||||||
styles: [/css/pomodoro1.css]
|
styles: [/css/pomodoro1.css]
|
||||||
canonical_url: /en/2023/01/11/spinning-cube-in-space.html
|
canonical_url: /en/2023/01/11/spinning-cube-in-space.html
|
||||||
|
@ -18,6 +18,7 @@ are widely used in practice for various purposes. In the previous example, we
|
||||||
— we pass into three-dimensional space. Now, to display the rotation of a three-dimensional object
|
— we pass into three-dimensional space. Now, to display the rotation of a three-dimensional object
|
||||||
on the screen plane, we first need to create a *mathematical model* of a three-dimensional object,
|
on the screen plane, we first need to create a *mathematical model* of a three-dimensional object,
|
||||||
rotate it by an angle, draw a projection from it and display already the projection on the screen.
|
rotate it by an angle, draw a projection from it and display already the projection on the screen.
|
||||||
|
For clarity, we will use the cartesian coordinate system.
|
||||||
|
|
||||||
Complicated model, many cubes: [Spinning spatial cross]({{ '/en/2023/01/16/spinning-spatial-cross.html' | relative_url }}).
|
Complicated model, many cubes: [Spinning spatial cross]({{ '/en/2023/01/16/spinning-spatial-cross.html' | relative_url }}).
|
||||||
|
|
||||||
|
@ -25,13 +26,13 @@ Complicated model, many cubes: [Spinning spatial cross]({{ '/en/2023/01/16/spinn
|
||||||
<div style="display: flex; flex-direction: column; padding-right: 8px;">
|
<div style="display: flex; flex-direction: column; padding-right: 8px;">
|
||||||
<span>Parallel projection</span>
|
<span>Parallel projection</span>
|
||||||
<canvas id="canvas1" width="300" height="300" style="border: 1px solid gray;">
|
<canvas id="canvas1" width="300" height="300" style="border: 1px solid gray;">
|
||||||
<p>Your browser does not support Canvas</p>
|
<p>Canvas for displaying computations results</p>
|
||||||
</canvas>
|
</canvas>
|
||||||
</div>
|
</div>
|
||||||
<div style="display: flex; flex-direction: column;">
|
<div style="display: flex; flex-direction: column;">
|
||||||
<span>Perspective projection</span>
|
<span>Perspective projection</span>
|
||||||
<canvas id="canvas2" width="300" height="300" style="border: 1px solid gray;">
|
<canvas id="canvas2" width="300" height="300" style="border: 1px solid gray;">
|
||||||
<p>Your browser does not support Canvas</p>
|
<p>Canvas for displaying computations results</p>
|
||||||
</canvas>
|
</canvas>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -48,12 +49,12 @@ Cube size 200, canvas size 300, origin of coordinates is in the upper left corne
|
||||||
is in the middle of the canvas. The `X` axis is directed to the right, the `Y` axis is directed downwards,
|
is in the middle of the canvas. The `X` axis is directed to the right, the `Y` axis is directed downwards,
|
||||||
the `Z` axis is directed to the distance. The rotation is performed sequentially around all three axes: first
|
the `Z` axis is directed to the distance. The rotation is performed sequentially around all three axes: first
|
||||||
around the `X` axis, then around the `Y` axis and then around the `Z` axis. Model settings can be controlled,
|
around the `X` axis, then around the `Y` axis and then around the `Z` axis. Model settings can be controlled,
|
||||||
for example, you can switch off redundant rotation around the axes and change the position of the projection
|
for example, you can switch off redundant rotation around the axes and move the central point of the projection
|
||||||
center onto the observer screen.
|
onto the observer screen.
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<canvas id="canvas3" width="300" height="300" style="border: 1px solid gray;">
|
<canvas id="canvas3" width="300" height="300" style="border: 1px solid gray;">
|
||||||
<p>Your browser does not support Canvas</p>
|
<p>Canvas for displaying computations results</p>
|
||||||
</canvas>
|
</canvas>
|
||||||
</div>
|
</div>
|
||||||
<form>
|
<form>
|
||||||
|
@ -93,7 +94,7 @@ center onto the observer screen.
|
||||||
<output name="result">300</output>
|
<output name="result">300</output>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<label for="center">Show the central point:</label>
|
<label for="center">Move the central point:</label>
|
||||||
<input type="checkbox" id="center" name="center" oninput="showCenter(event)">
|
<input type="checkbox" id="center" name="center" oninput="showCenter(event)">
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
@ -154,8 +155,8 @@ alt="{(x-x_1)\over(y-y_1)}={(x_2-x_1)\over(y_2-y_1)}." %}
|
||||||
First, we bypass the vertices of the cube and rotate them by an angle relative to the center point. Then
|
First, we bypass the vertices of the cube and rotate them by an angle relative to the center point. Then
|
||||||
we bypass the faces of the cube and get projections of the vertices included in them. After that, we sort
|
we bypass the faces of the cube and get projections of the vertices included in them. After that, we sort
|
||||||
the projections of the faces by remoteness. Then we draw projections on the plane — we link the points
|
the projections of the faces by remoteness. Then we draw projections on the plane — we link the points
|
||||||
with lines. We draw with a translucent color first the far faces and atop them the near ones, so that
|
with lines. We draw with an almost transparent color first the far faces and atop them the near ones,
|
||||||
the far faces can be seen through the near ones.
|
so that the far faces can be seen through the near ones.
|
||||||
|
|
||||||
At each step of displaying the figure, we repeat the sorting of the faces by remoteness, since
|
At each step of displaying the figure, we repeat the sorting of the faces by remoteness, since
|
||||||
with a change in the angle of rotation, the coordinates shift, and the near faces become far.
|
with a change in the angle of rotation, the coordinates shift, and the near faces become far.
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
---
|
---
|
||||||
title: Spinning spatial cross
|
title: Spinning spatial cross
|
||||||
description: We are writing an algorithm for rotating a three-dimensional figure by an angle around its center along all three axes at once. In the previous example...
|
description: We are writing an algorithm for rotating a three-dimensional figure around its center along all three axes at once. In the previous example, we rotated cube...
|
||||||
sections: [Volumetric figures,Rotation matrix,Experimental model]
|
sections: [Volumetric figures,Rotation matrix,Experimental model]
|
||||||
tags: [javascript,online,canvas,geometry,matrix,graphics,image,picture,square,cube]
|
tags: [javascript,online,canvas,geometry,matrix,graphics,image,picture,square,cube,3d,three-dimensional]
|
||||||
scripts: [/js/classes-point-cube.js,/js/spinning-spatial-cross.js,/js/spinning-spatial-cross2.js]
|
scripts: [/js/classes-point-cube.js,/js/spinning-spatial-cross.js,/js/spinning-spatial-cross2.js]
|
||||||
styles: [/css/pomodoro1.css]
|
styles: [/css/pomodoro1.css]
|
||||||
canonical_url: /en/2023/01/16/spinning-spatial-cross.html
|
canonical_url: /en/2023/01/16/spinning-spatial-cross.html
|
||||||
|
@ -12,12 +12,12 @@ date: 2023.01.16
|
||||||
lang: en
|
lang: en
|
||||||
---
|
---
|
||||||
|
|
||||||
We are writing an algorithm for rotating a three-dimensional figure by an angle
|
We are writing an algorithm for rotating a three-dimensional figure around
|
||||||
around its center along all three axes at once. In the previous example, we
|
its center along all three axes at once. In the previous example, we
|
||||||
[rotated cube in space]({{ '/en/2023/01/11/spinning-cube-in-space.html' | relative_url }})
|
[rotated cube in space]({{ '/en/2023/01/11/spinning-cube-in-space.html' | relative_url }})
|
||||||
— now there are a lot of cubes, the algorithm is almost the same and we use the same formulas.
|
— in this example, there are a lot of cubes, the algorithm will be almost the same, and we will use
|
||||||
We draw two variants of the figure: *spatial cross* and *cross-cube* in two types of projections,
|
the same formulas. For clarity, let's take two variants of a symmetrical volumetric figure in two
|
||||||
consider the difference.
|
types of projections — *spatial cross* and *cross-cube* — we consider the difference between them.
|
||||||
|
|
||||||
Testing the experimental interface: [Volumetric tetris]({{ '/en/2023/01/22/volumetric-tetris.html' | relative_url }}).
|
Testing the experimental interface: [Volumetric tetris]({{ '/en/2023/01/22/volumetric-tetris.html' | relative_url }}).
|
||||||
|
|
||||||
|
@ -27,13 +27,13 @@ Testing the experimental interface: [Volumetric tetris]({{ '/en/2023/01/22/volum
|
||||||
<div style="display: flex; flex-direction: column; padding-right: 8px;">
|
<div style="display: flex; flex-direction: column; padding-right: 8px;">
|
||||||
<span>Parallel projection</span>
|
<span>Parallel projection</span>
|
||||||
<canvas id="canvas1" width="300" height="300" style="border: 1px solid gray;">
|
<canvas id="canvas1" width="300" height="300" style="border: 1px solid gray;">
|
||||||
<p>Your browser does not support Canvas</p>
|
<p>Canvas for displaying computations results</p>
|
||||||
</canvas>
|
</canvas>
|
||||||
</div>
|
</div>
|
||||||
<div style="display: flex; flex-direction: column;">
|
<div style="display: flex; flex-direction: column;">
|
||||||
<span>Perspective projection</span>
|
<span>Perspective projection</span>
|
||||||
<canvas id="canvas2" width="300" height="300" style="border: 1px solid gray;">
|
<canvas id="canvas2" width="300" height="300" style="border: 1px solid gray;">
|
||||||
<p>Your browser does not support Canvas</p>
|
<p>Canvas for displaying computations results</p>
|
||||||
</canvas>
|
</canvas>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -44,13 +44,13 @@ Testing the experimental interface: [Volumetric tetris]({{ '/en/2023/01/22/volum
|
||||||
<div style="display: flex; flex-direction: column; padding-right: 8px;">
|
<div style="display: flex; flex-direction: column; padding-right: 8px;">
|
||||||
<span>Parallel projection</span>
|
<span>Parallel projection</span>
|
||||||
<canvas id="canvas3" width="300" height="300" style="border: 1px solid gray;">
|
<canvas id="canvas3" width="300" height="300" style="border: 1px solid gray;">
|
||||||
<p>Your browser does not support Canvas</p>
|
<p>Canvas for displaying computations results</p>
|
||||||
</canvas>
|
</canvas>
|
||||||
</div>
|
</div>
|
||||||
<div style="display: flex; flex-direction: column;">
|
<div style="display: flex; flex-direction: column;">
|
||||||
<span>Perspective projection</span>
|
<span>Perspective projection</span>
|
||||||
<canvas id="canvas4" width="300" height="300" style="border: 1px solid gray;">
|
<canvas id="canvas4" width="300" height="300" style="border: 1px solid gray;">
|
||||||
<p>Your browser does not support Canvas</p>
|
<p>Canvas for displaying computations results</p>
|
||||||
</canvas>
|
</canvas>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -62,12 +62,12 @@ Testing the experimental interface: [Volumetric tetris]({{ '/en/2023/01/22/volum
|
||||||
{% include heading.html text="Experimental model" hash="experimental-model" %}
|
{% include heading.html text="Experimental model" hash="experimental-model" %}
|
||||||
|
|
||||||
Slightly complicated version from the previous example — now there are a lot of cubes. In addition to the
|
Slightly complicated version from the previous example — now there are a lot of cubes. In addition to the
|
||||||
previous settings there can be changed: figure variant — *spatial cross* or *cross-cube*, face sorting
|
previous settings there can be changed: variant of the figure — *spatial cross* or *cross-cube*, face sorting
|
||||||
direction — *linear perspective* or *reverse perspective* and transparency of the cube walls.
|
direction — *straight perspective* or *reverse perspective* and transparency of the cube walls.
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<canvas id="canvas5" width="300" height="300" style="border: 1px solid gray;">
|
<canvas id="canvas5" width="300" height="300" style="border: 1px solid gray;">
|
||||||
<p>Your browser does not support Canvas</p>
|
<p>Canvas for displaying computations results</p>
|
||||||
</canvas>
|
</canvas>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
|
@ -108,7 +108,7 @@ direction — *linear perspective* or *reverse perspective* and transparency of
|
||||||
<output name="result">300</output>
|
<output name="result">300</output>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<label for="center">Show the central point:</label>
|
<label for="center">Move the central point:</label>
|
||||||
<input type="checkbox" id="center" name="center" oninput="showCenter(event)">
|
<input type="checkbox" id="center" name="center" oninput="showCenter(event)">
|
||||||
</div>
|
</div>
|
||||||
<span>Transparency of cubes:</span>
|
<span>Transparency of cubes:</span>
|
||||||
|
@ -126,10 +126,10 @@ direction — *linear perspective* or *reverse perspective* and transparency of
|
||||||
<input type="radio" id="second" name="figure" value="second" checked>
|
<input type="radio" id="second" name="figure" value="second" checked>
|
||||||
<label for="second">Cube</label>
|
<label for="second">Cube</label>
|
||||||
</form>
|
</form>
|
||||||
<span>Perspective projection:</span>
|
<span>Linear perspective:</span>
|
||||||
<form oninput="changeOrder(event)">
|
<form oninput="changeOrder(event)">
|
||||||
<input type="radio" id="linear" name="order" value="linear" checked>
|
<input type="radio" id="linear" name="order" value="linear" checked>
|
||||||
<label for="linear">Linear</label>
|
<label for="linear">Straight</label>
|
||||||
<input type="radio" id="reverse" name="order" value="reverse">
|
<input type="radio" id="reverse" name="order" value="reverse">
|
||||||
<label for="reverse">Reverse</label>
|
<label for="reverse">Reverse</label>
|
||||||
</form>
|
</form>
|
||||||
|
@ -137,13 +137,13 @@ direction — *linear perspective* or *reverse perspective* and transparency of
|
||||||
|
|
||||||
{% include heading.html text="Algorithm description" hash="algorithm-description" %}
|
{% include heading.html text="Algorithm description" hash="algorithm-description" %}
|
||||||
|
|
||||||
We prepare a matrix of zeros and ones, where one means a cube in a certain place of the figure. Then we
|
We prepare a three-dimensional matrix of zeros and ones, where one means a cube in a certain place of the figure.
|
||||||
bypass this matrix and fill in the array of cubes with the corresponding coordinates of the vertices. After
|
Then we bypass this matrix and fill in the array of cubes with the corresponding coordinates of the vertices.
|
||||||
that, we start the rotation along all three axes at once. At each step, we bypass the array of cubes and get
|
After that, we start the rotation along all three axes at once. At each step, we bypass the array of cubes and
|
||||||
projections of their faces. Then we sort the array of faces by remoteness from the projection center, bypass
|
get projections of their faces. Then we sort the array of faces by remoteness from the projection center, bypass
|
||||||
this array and throw away the same pairs from it — these are the adjacent walls between neighboring cubes
|
this array and throw away the same pairs from it — these are the adjacent walls between neighboring cubes inside
|
||||||
inside the figure. After that we draw cube faces with a translucent color — first the distant and then the
|
the figure. After that we draw with a translucent color the cube faces — first the distant, and then the near ones,
|
||||||
near ones, so that the distant faces can be seen through the near ones.
|
so that the distant faces can be seen through the near ones.
|
||||||
|
|
||||||
{% include heading.html text="Implementation in JavaScript" hash="implementation-in-javascript" %}
|
{% include heading.html text="Implementation in JavaScript" hash="implementation-in-javascript" %}
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
---
|
---
|
||||||
title: Volumetric tetris
|
title: Volumetric tetris
|
||||||
description: General educational game in the broad meaning of this word. When learning programming languages, it is recommended to write your own version first and then...
|
description: General educational game in the broad meaning of this word. In the process of learning programming languages, it is recommended to write your own version...
|
||||||
sections: [Logical game,Experimental interface]
|
sections: [Logical game,Experimental interface]
|
||||||
tags: [javascript,online,canvas,game,puzzle,geometry,matrix,graphics,square,cube,3d,three-dimensional]
|
tags: [javascript,online,canvas,game,classic,puzzle,geometry,matrix,graphics,square,cube,3d,three-dimensional]
|
||||||
scripts: [/js/classes-point-cube.js,/js/tetris-figures.js,/js/tetris-model.js,/js/tetris-controller.js,/js/tetris-view.js]
|
scripts: [/js/classes-point-cube.js,/js/tetris-figures.js,/js/tetris-model.js,/js/tetris-controller.js,/js/tetris-view.js]
|
||||||
styles: [/css/pomodoro1.css]
|
styles: [/css/pomodoro1.css]
|
||||||
canonical_url: /en/2023/01/22/volumetric-tetris.html
|
canonical_url: /en/2023/01/22/volumetric-tetris.html
|
||||||
|
@ -12,17 +12,17 @@ date: 2023.01.22
|
||||||
lang: en
|
lang: en
|
||||||
---
|
---
|
||||||
|
|
||||||
General educational game in the broad meaning of this word. When learning programming languages, it is
|
General educational game in the broad meaning of this word. In the process of learning programming languages,
|
||||||
recommended to write your own version first and then use it to demonstrate and test other software or
|
it is recommended to write your own version first and then use it for demonstrating and testing another
|
||||||
hardware. The three-dimensional interface is written in JavaScript Canvas — the logic of the game itself
|
software or hardware. The three-dimensional interface is written in JavaScript Canvas — the logic of the
|
||||||
is two-dimensional.
|
game itself is two-dimensional. Additional external libraries are not used.
|
||||||
|
|
||||||
Description of graphics algorithm: [Spinning cube in space]({{ '/en/2023/01/11/spinning-cube-in-space.html' | relative_url }}).
|
Description of graphics algorithm: [Spinning cube in space]({{ '/en/2023/01/11/spinning-cube-in-space.html' | relative_url }}).
|
||||||
|
|
||||||
{% include heading.html text="Experimental interface" hash="experimental-interface" %}
|
{% include heading.html text="Experimental interface" hash="experimental-interface" %}
|
||||||
|
|
||||||
Turned off by default — you can just play Tetris. In addition to the flat version, two volumetric variants
|
Turned off by default — you can just play Tetris. In addition to the two-dimensional version, two volumetric variants
|
||||||
are added: *parallel projection* and *perspective projection* — parameters for each of them can be changed.
|
are added — *parallel projection* and *perspective projection* — parameters for each of them can be changed.
|
||||||
For perspective projection: you can change the position of the observer screen and the remoteness of the
|
For perspective projection: you can change the position of the observer screen and the remoteness of the
|
||||||
projection source. The observer looks at the center of the image, and the center of the projection is remote
|
projection source. The observer looks at the center of the image, and the center of the projection is remote
|
||||||
at a distance, comparable to the size of the playing field. For parallel projection: you can change the
|
at a distance, comparable to the size of the playing field. For parallel projection: you can change the
|
||||||
|
@ -31,24 +31,24 @@ point for rotations — is the central lower far point of the field. For all var
|
||||||
of the cube — 32, the size of the square — 30 and the indent — 2. The origin of coordinates is located at
|
of the cube — 32, the size of the square — 30 and the indent — 2. The origin of coordinates is located at
|
||||||
the upper left point, the axes are directed: `X` to the right, `Y` downwards and `Z` to the distance.
|
the upper left point, the axes are directed: `X` to the right, `Y` downwards and `Z` to the distance.
|
||||||
|
|
||||||
*Usage example:* start the game, collect a certain number of figures on the field, then pause the game,
|
<b>Testing:</b> start the game, collect a certain number of figures on the field, pause the game, and
|
||||||
and switch between the variants of the three-dimensional image, rotate the field with figures, change
|
then switch the variants of the three-dimensional image, rotate the field with figures, change the
|
||||||
the settings and so on.
|
transparency, move the central point and so on.
|
||||||
|
|
||||||
|
<b>Controls:</b> keyboard buttons with arrows — right, left, up, down and the button `pause`.
|
||||||
|
|
||||||
{% include volumetric-tetris-en.html -%}
|
{% include volumetric-tetris-en.html -%}
|
||||||
|
|
||||||
{% include heading.html text="Gaming process" hash="gaming-process" %}
|
{% include heading.html text="Gaming process" hash="gaming-process" %}
|
||||||
|
|
||||||
Controls: keyboard buttons with arrows — right, left, up, down and the button `pause`.
|
|
||||||
|
|
||||||
Game points are awarded for fully collected rows of the elements of the figures. The number of points scored
|
Game points are awarded for fully collected rows of the elements of the figures. The number of points scored
|
||||||
depends on the number of rows collected, 10 points for each row if there are 10 cubes in a row, and multiply
|
depends on the number of rows collected, 10 points for each row if there are 10 cubes in a row, and multiply
|
||||||
increases, if collected at the same time: 2 lines — by 3 times, 3 lines — by 5 times, 4 lines — by 10 times.
|
increases, if collected at the same time: 2 lines — by 3 times, 3 lines — by 5 times, 4 lines — by 10 times.
|
||||||
|
|
||||||
Game feature: the collected lines first blink and then disappear, while the gaming process is not suspended
|
<b>Game feature:</b> the collected lines first blink and then disappear — meanwhile the
|
||||||
for this time — the current figure continues to fall.
|
gaming process is not suspended for this time — the current figure continues to fall.
|
||||||
|
|
||||||
Level increases when collecting 10 completed rows, that is 100 points, if there are 10 cubes in a row. At each
|
Level increases when collecting 10 completed rows, that is 100 points, if there are 10 cubes in a row. At each
|
||||||
new level, the speed of the figures increases and reaches its maximum at level 21. In snail mode, the speed
|
new level, the speed of the figures increases and reaches a maximum at level 21. In snail mode, the speed increase
|
||||||
increases 5 times slower and reaches a maximum at level 104. The current speed is displayed above the playing
|
becomes slower 5 times, and the speed of the figures reaches a maximum at level 104. The current speed is displayed
|
||||||
field as a `meter` indicator.
|
above the playing field as a `meter` indicator.
|
||||||
|
|
|
@ -12,18 +12,19 @@ lang: en
|
||||||
{%- assign articles = "" | split: "" %}
|
{%- assign articles = "" | split: "" %}
|
||||||
{%- assign articles = articles | push: "Volumetric tetris" %}
|
{%- assign articles = articles | push: "Volumetric tetris" %}
|
||||||
{%- capture article_brief %}
|
{%- capture article_brief %}
|
||||||
General educational game in the broad meaning of this word. When learning programming languages, it is
|
General educational game in the broad meaning of this word. In the process of learning programming languages,
|
||||||
recommended to write your own version first and then use it to demonstrate and test other software or
|
it is recommended to write your own version first and then use it for demonstrating and testing another
|
||||||
hardware. The three-dimensional interface is written in JavaScript Canvas — the logic of the game itself
|
software or hardware. The three-dimensional interface is written in JavaScript Canvas — the logic of the
|
||||||
is two-dimensional.
|
game itself is two-dimensional. Additional external libraries are not used.
|
||||||
{%- endcapture %}
|
{%- endcapture %}
|
||||||
{%- assign articles = articles | push: article_brief %}
|
{%- assign articles = articles | push: article_brief %}
|
||||||
{%- assign articles = articles | push: "Spinning spatial cross" %}
|
{%- assign articles = articles | push: "Spinning spatial cross" %}
|
||||||
{%- capture article_brief %}
|
{%- capture article_brief %}
|
||||||
We are writing an algorithm for rotating a three-dimensional figure by an angle around its center along
|
We are writing an algorithm for rotating a three-dimensional figure around its center along all three axes
|
||||||
all three axes at once. In the previous example, we rotated cube in space — now there are a lot of cubes,
|
at once. In the previous example, we rotated cube in space — in this example, there are a lot of cubes, the
|
||||||
the algorithm is almost the same and we use the same formulas. We draw two variants of the figure:
|
algorithm will be almost the same, and we will use the same formulas. For clarity, let's take two variants
|
||||||
*spatial cross* and *cross-cube* in two types of projections, consider the difference.
|
of a symmetrical volumetric figure in two types of projections — *spatial cross* and *cross-cube* — we
|
||||||
|
consider the difference between them.
|
||||||
{%- endcapture %}
|
{%- endcapture %}
|
||||||
{%- assign articles = articles | push: article_brief %}
|
{%- assign articles = articles | push: article_brief %}
|
||||||
{%- assign articles = articles | push: "Spinning cube in space" %}
|
{%- assign articles = articles | push: "Spinning cube in space" %}
|
||||||
|
@ -32,7 +33,7 @@ We consider the difference between parallel and perspective projection. Both are
|
||||||
for various purposes. In the previous example, we rotated square on plane — we pass into three-dimensional
|
for various purposes. In the previous example, we rotated square on plane — we pass into three-dimensional
|
||||||
space. Now, to display the rotation of a three-dimensional object on the screen plane, we first need to
|
space. Now, to display the rotation of a three-dimensional object on the screen plane, we first need to
|
||||||
create a *mathematical model* of a three-dimensional object, rotate it by an angle, draw a projection from
|
create a *mathematical model* of a three-dimensional object, rotate it by an angle, draw a projection from
|
||||||
it and display already the projection on the screen.
|
it and display already the projection on the screen. For clarity, we will use the cartesian coordinate system.
|
||||||
{%- endcapture %}
|
{%- endcapture %}
|
||||||
{%- assign articles = articles | push: article_brief %}
|
{%- assign articles = articles | push: article_brief %}
|
||||||
{%- assign articles = articles | push: "Spinning square on plane" %}
|
{%- assign articles = articles | push: "Spinning square on plane" %}
|
||||||
|
|
|
@ -111,7 +111,7 @@ function changeTv2(axis, caller) {
|
||||||
function changeDistance2(caller) {
|
function changeDistance2(caller) {
|
||||||
d2=caller.target.valueAsNumber;
|
d2=caller.target.valueAsNumber;
|
||||||
}
|
}
|
||||||
// показать центральную точку
|
// двигать центральную точку
|
||||||
function showCenter(caller) {
|
function showCenter(caller) {
|
||||||
tv2.show=!tv2.show;
|
tv2.show=!tv2.show;
|
||||||
}
|
}
|
||||||
|
@ -154,7 +154,7 @@ function refreshParams() {
|
||||||
document.getElementById('tv2Z').max = d2/2;
|
document.getElementById('tv2Z').max = d2/2;
|
||||||
document.getElementById('tv2Z').value = tv2.z;
|
document.getElementById('tv2Z').value = tv2.z;
|
||||||
document.getElementById('tv2Zo').value = tv2.z;
|
document.getElementById('tv2Zo').value = tv2.z;
|
||||||
document.getElementById('dist').max = d2*2;
|
document.getElementById('dist').max = d2max;
|
||||||
document.getElementById('dist').value = d2;
|
document.getElementById('dist').value = d2;
|
||||||
document.getElementById('oDist').value = d2;
|
document.getElementById('oDist').value = d2;
|
||||||
refreshDisabled();
|
refreshDisabled();
|
||||||
|
|
|
@ -44,7 +44,7 @@ let deg={}; deg.setDefault = function() {
|
||||||
};
|
};
|
||||||
deg.setDefault();
|
deg.setDefault();
|
||||||
// параллельная проекция: центр и экран наблюдателя
|
// параллельная проекция: центр и экран наблюдателя
|
||||||
let d1 = 600, tv1={}; tv1.reCalc = function() {
|
let d1, tv1 = {}; tv1.reCalc = function() {
|
||||||
this.x=columns*(size+gap)/2;
|
this.x=columns*(size+gap)/2;
|
||||||
this.y=(size+gap)*2;
|
this.y=(size+gap)*2;
|
||||||
this.z=(size+gap)*2;
|
this.z=(size+gap)*2;
|
||||||
|
@ -52,12 +52,12 @@ let d1 = 600, tv1={}; tv1.reCalc = function() {
|
||||||
}
|
}
|
||||||
tv1.reCalc();
|
tv1.reCalc();
|
||||||
// перспективная проекция: центр и экран наблюдателя
|
// перспективная проекция: центр и экран наблюдателя
|
||||||
let d2 = 600, tv2 = {}; tv2.reCalc = function() {
|
let d2, d2max, tv2 = {}; tv2.reCalc = function() {
|
||||||
this.x = columns*(size+gap)/2;
|
this.x = columns*(size+gap)/2;
|
||||||
this.y = rows*(size+gap)/2;
|
this.y = rows*(size+gap)/2;
|
||||||
this.z = (size+gap)*2;
|
this.z = (size+gap)*2;
|
||||||
this.show=false;
|
this.show=false;
|
||||||
d2 = Math.max(rows,columns)*(size+gap);
|
d2 = Math.max(rows,columns)*(size+gap); d2max = d2*2;
|
||||||
};
|
};
|
||||||
tv2.reCalc();
|
tv2.reCalc();
|
||||||
// стакан с игрой
|
// стакан с игрой
|
||||||
|
|
|
@ -34,7 +34,7 @@ alt="&x'=x_0+(x-x_0)cos\varphi-(y-y_0)sin\varphi,&\\&y'=y_0+(x-x_0)sin\varphi+(y
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<canvas id="canvas" width="300" height="300" style="border: 1px solid gray;">
|
<canvas id="canvas" width="300" height="300" style="border: 1px solid gray;">
|
||||||
<p>Ваш браузер не поддерживает Canvas</p>
|
<p>Холст для отображения результатов вычислений</p>
|
||||||
</canvas>
|
</canvas>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -42,7 +42,7 @@ alt="&x'=x_0+(x-x_0)cos\varphi-(y-y_0)sin\varphi,&\\&y'=y_0+(x-x_0)sin\varphi+(y
|
||||||
|
|
||||||
```html
|
```html
|
||||||
<canvas id="canvas" width="300" height="300" style="border: 1px solid gray;">
|
<canvas id="canvas" width="300" height="300" style="border: 1px solid gray;">
|
||||||
<p>Ваш браузер не поддерживает Canvas</p>
|
<p>Холст для отображения результатов вычислений</p>
|
||||||
</canvas>
|
</canvas>
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -115,7 +115,7 @@ document.addEventListener('DOMContentLoaded',()=>setInterval(repaint,50));
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<canvas id="canvas2" width="300" height="300" style="border: 1px solid gray;">
|
<canvas id="canvas2" width="300" height="300" style="border: 1px solid gray;">
|
||||||
<p>Ваш браузер не поддерживает Canvas</p>
|
<p>Холст для отображения результатов вычислений</p>
|
||||||
</canvas>
|
</canvas>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -123,7 +123,7 @@ document.addEventListener('DOMContentLoaded',()=>setInterval(repaint,50));
|
||||||
|
|
||||||
```html
|
```html
|
||||||
<canvas id="canvas2" width="300" height="300" style="border: 1px solid gray;">
|
<canvas id="canvas2" width="300" height="300" style="border: 1px solid gray;">
|
||||||
<p>Ваш браузер не поддерживает Canvas</p>
|
<p>Холст для отображения результатов вычислений</p>
|
||||||
</canvas>
|
</canvas>
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
---
|
---
|
||||||
title: Вращаем куб в пространстве
|
title: Вращаем куб в пространстве
|
||||||
description: Рассматриваем разницу между параллельной и перспективной проекцией. Обе широко используются на практике для различных целей. В предыдущем примере мы вращали...
|
description: Рассмотрим разницу между параллельной и перспективной проекцией. Обе широко используются на практике для различных целей. В предыдущем примере мы вращали...
|
||||||
sections: [Линейная перспектива,Матрица поворота,Экспериментальная модель]
|
sections: [Линейная перспектива,Матрица поворота,Экспериментальная модель]
|
||||||
tags: [javascript,онлайн,canvas,геометрия,графика,изображение,картинка,квадрат,куб]
|
tags: [javascript,онлайн,canvas,геометрия,графика,изображение,картинка,квадрат,куб,3д,трёхмерный]
|
||||||
scripts: [/js/classes-point-cube.js,/js/spinning-cube.js,/js/spinning-cube2.js]
|
scripts: [/js/classes-point-cube.js,/js/spinning-cube.js,/js/spinning-cube2.js]
|
||||||
styles: [/css/pomodoro1.css]
|
styles: [/css/pomodoro1.css]
|
||||||
canonical_url: /ru/2023/01/10/spinning-cube-in-space.html
|
canonical_url: /ru/2023/01/10/spinning-cube-in-space.html
|
||||||
|
@ -11,12 +11,12 @@ title_translated: Spinning cube in space
|
||||||
date: 2023.01.10
|
date: 2023.01.10
|
||||||
---
|
---
|
||||||
|
|
||||||
Рассматриваем разницу между параллельной и перспективной проекцией. Обе
|
Рассмотрим разницу между параллельной и перспективной проекцией. Обе широко
|
||||||
широко используются на практике для различных целей. В предыдущем примере мы
|
используются на практике для различных целей. В предыдущем примере мы
|
||||||
[вращали квадрат на плоскости]({{ '/ru/2023/01/05/spinning-square-on-plane.html' | relative_url }})
|
[вращали квадрат на плоскости]({{ '/ru/2023/01/05/spinning-square-on-plane.html' | relative_url }})
|
||||||
— переходим в трёхмерное пространство. Теперь, чтобы отобразить на плоскости экрана поворот трёхмерного
|
— переходим в трёхмерное пространство. Теперь, чтобы отобразить на плоскости экрана поворот трёхмерного
|
||||||
объекта, нужно сначала создать *математическую модель* трёхмерного объекта, повернуть её на угол, срисовать
|
объекта, нужно сначала создать *математическую модель* трёхмерного объекта, повернуть её на угол, срисовать
|
||||||
с неё проекцию и отобразить на экране уже проекцию.
|
с неё проекцию и отобразить на экране уже проекцию. Для наглядности будем использовать декартову систему координат.
|
||||||
|
|
||||||
Усложнённая модель, много кубиков: [Вращаем пространственный крест]({{ '/ru/2023/01/15/spinning-spatial-cross.html' | relative_url }}).
|
Усложнённая модель, много кубиков: [Вращаем пространственный крест]({{ '/ru/2023/01/15/spinning-spatial-cross.html' | relative_url }}).
|
||||||
|
|
||||||
|
@ -24,13 +24,13 @@ date: 2023.01.10
|
||||||
<div style="display: flex; flex-direction: column; padding-right: 8px;">
|
<div style="display: flex; flex-direction: column; padding-right: 8px;">
|
||||||
<span>Параллельная проекция</span>
|
<span>Параллельная проекция</span>
|
||||||
<canvas id="canvas1" width="300" height="300" style="border: 1px solid gray;">
|
<canvas id="canvas1" width="300" height="300" style="border: 1px solid gray;">
|
||||||
<p>Ваш браузер не поддерживает Canvas</p>
|
<p>Холст для отображения результатов вычислений</p>
|
||||||
</canvas>
|
</canvas>
|
||||||
</div>
|
</div>
|
||||||
<div style="display: flex; flex-direction: column;">
|
<div style="display: flex; flex-direction: column;">
|
||||||
<span>Перспективная проекция</span>
|
<span>Перспективная проекция</span>
|
||||||
<canvas id="canvas2" width="300" height="300" style="border: 1px solid gray;">
|
<canvas id="canvas2" width="300" height="300" style="border: 1px solid gray;">
|
||||||
<p>Ваш браузер не поддерживает Canvas</p>
|
<p>Холст для отображения результатов вычислений</p>
|
||||||
</canvas>
|
</canvas>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -47,11 +47,11 @@ date: 2023.01.10
|
||||||
в середине холста. Ось `X` направлена вправо, ось `Y` направлена вниз, ось `Z` направлена вдаль.
|
в середине холста. Ось `X` направлена вправо, ось `Y` направлена вниз, ось `Z` направлена вдаль.
|
||||||
Выполняется поворот последовательно по всем трём осям: сначала по оси `X`, затем по оси `Y` и затем
|
Выполняется поворот последовательно по всем трём осям: сначала по оси `X`, затем по оси `Y` и затем
|
||||||
по оси `Z`. Настройками модели можно управлять, например можно отключать лишнее вращение по осям и
|
по оси `Z`. Настройками модели можно управлять, например можно отключать лишнее вращение по осям и
|
||||||
изменять положение центра проекции на экране наблюдателя.
|
двигать центральную точку проекции на экране наблюдателя.
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<canvas id="canvas3" width="300" height="300" style="border: 1px solid gray;">
|
<canvas id="canvas3" width="300" height="300" style="border: 1px solid gray;">
|
||||||
<p>Ваш браузер не поддерживает Canvas</p>
|
<p>Холст для отображения результатов вычислений</p>
|
||||||
</canvas>
|
</canvas>
|
||||||
</div>
|
</div>
|
||||||
<form>
|
<form>
|
||||||
|
@ -91,7 +91,7 @@ date: 2023.01.10
|
||||||
<output name="result">300</output>
|
<output name="result">300</output>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<label for="center">Показать центральную точку:</label>
|
<label for="center">Двигать центральную точку:</label>
|
||||||
<input type="checkbox" id="center" name="center" oninput="showCenter(event)">
|
<input type="checkbox" id="center" name="center" oninput="showCenter(event)">
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
@ -151,8 +151,8 @@ alt="{(x-x_1)\over(y-y_1)}={(x_2-x_1)\over(y_2-y_1)}." %}
|
||||||
|
|
||||||
Сначала обходим вершины куба и поворачиваем их на угол относительно центральной точки. Затем обходим грани
|
Сначала обходим вершины куба и поворачиваем их на угол относительно центральной точки. Затем обходим грани
|
||||||
куба и получаем проекции входящих в них вершин. После этого сортируем проекции граней по удалённости. Затем
|
куба и получаем проекции входящих в них вершин. После этого сортируем проекции граней по удалённости. Затем
|
||||||
рисуем проекции на плоскости — соединяем точки линиями. Рисуем полупрозрачным цветом сперва дальние грани и
|
рисуем проекции на плоскости — соединяем точки линиями. Рисуем почти прозрачным цветом сперва дальние грани
|
||||||
поверх них ближние, чтобы сквозь ближние грани было видно дальние.
|
и поверх них ближние, чтобы сквозь ближние грани было видно дальние.
|
||||||
|
|
||||||
На каждом шаге отображения фигуры повторяем сортировку граней по удалённости, так как с изменением
|
На каждом шаге отображения фигуры повторяем сортировку граней по удалённости, так как с изменением
|
||||||
угла поворота, координаты смещаются, и ближние грани становятся дальними.
|
угла поворота, координаты смещаются, и ближние грани становятся дальними.
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
---
|
---
|
||||||
title: Вращаем пространственный крест
|
title: Вращаем пространственный крест
|
||||||
description: Пишем алгоритм для поворота объёмной фигуры на угол вокруг своего центра по всем трём осям сразу. В предыдущем примере мы вращали куб в пространстве...
|
description: Пишем алгоритм для поворота трёхмерной фигуры вокруг своего центра по всем трём осям сразу. В предыдущем примере мы вращали куб в пространстве — в этом...
|
||||||
sections: [Объёмные фигуры,Матрица поворота,Экспериментальная модель]
|
sections: [Объёмные фигуры,Матрица поворота,Экспериментальная модель]
|
||||||
tags: [javascript,онлайн,canvas,геометрия,матрица,графика,изображение,картинка,квадрат,куб]
|
tags: [javascript,онлайн,canvas,геометрия,матрица,графика,изображение,картинка,квадрат,куб,3д,трёхмерный]
|
||||||
scripts: [/js/classes-point-cube.js,/js/spinning-spatial-cross.js,/js/spinning-spatial-cross2.js]
|
scripts: [/js/classes-point-cube.js,/js/spinning-spatial-cross.js,/js/spinning-spatial-cross2.js]
|
||||||
styles: [/css/pomodoro1.css]
|
styles: [/css/pomodoro1.css]
|
||||||
canonical_url: /ru/2023/01/15/spinning-spatial-cross.html
|
canonical_url: /ru/2023/01/15/spinning-spatial-cross.html
|
||||||
|
@ -11,10 +11,11 @@ title_translated: Spinning spatial cross
|
||||||
date: 2023.01.15
|
date: 2023.01.15
|
||||||
---
|
---
|
||||||
|
|
||||||
Пишем алгоритм для поворота объёмной фигуры на угол вокруг своего центра по всем трём осям сразу. В предыдущем
|
Пишем алгоритм для поворота трёхмерной фигуры вокруг своего центра по всем трём осям сразу. В предыдущем
|
||||||
примере мы [вращали куб в пространстве]({{ '/ru/2023/01/10/spinning-cube-in-space.html' | relative_url }})
|
примере мы [вращали куб в пространстве]({{ '/ru/2023/01/10/spinning-cube-in-space.html' | relative_url }})
|
||||||
— теперь кубиков будет много, алгоритм будет почти такой же и формулы будем использовать те же. Рисуем два
|
— в этом примере кубиков будет много, алгоритм будет почти такой же, и формулы будем использовать те же. Для
|
||||||
варианта фигуры: *пространственный крест* и *крест-куб* в двух типах проекций, рассматриваем разницу.
|
наглядности возьмём два варианта симметричной объёмной фигуры в двух типах проекций — *пространственный крест*
|
||||||
|
и *крест-куб* — рассматриваем разницу между ними.
|
||||||
|
|
||||||
Тестирование экспериментального интерфейса: [Объёмный тетрис]({{ '/ru/2023/01/21/volumetric-tetris.html' | relative_url }}).
|
Тестирование экспериментального интерфейса: [Объёмный тетрис]({{ '/ru/2023/01/21/volumetric-tetris.html' | relative_url }}).
|
||||||
|
|
||||||
|
@ -24,13 +25,13 @@ date: 2023.01.15
|
||||||
<div style="display: flex; flex-direction: column; padding-right: 8px;">
|
<div style="display: flex; flex-direction: column; padding-right: 8px;">
|
||||||
<span>Параллельная проекция</span>
|
<span>Параллельная проекция</span>
|
||||||
<canvas id="canvas1" width="300" height="300" style="border: 1px solid gray;">
|
<canvas id="canvas1" width="300" height="300" style="border: 1px solid gray;">
|
||||||
<p>Ваш браузер не поддерживает Canvas</p>
|
<p>Холст для отображения результатов вычислений</p>
|
||||||
</canvas>
|
</canvas>
|
||||||
</div>
|
</div>
|
||||||
<div style="display: flex; flex-direction: column;">
|
<div style="display: flex; flex-direction: column;">
|
||||||
<span>Перспективная проекция</span>
|
<span>Перспективная проекция</span>
|
||||||
<canvas id="canvas2" width="300" height="300" style="border: 1px solid gray;">
|
<canvas id="canvas2" width="300" height="300" style="border: 1px solid gray;">
|
||||||
<p>Ваш браузер не поддерживает Canvas</p>
|
<p>Холст для отображения результатов вычислений</p>
|
||||||
</canvas>
|
</canvas>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -41,13 +42,13 @@ date: 2023.01.15
|
||||||
<div style="display: flex; flex-direction: column; padding-right: 8px;">
|
<div style="display: flex; flex-direction: column; padding-right: 8px;">
|
||||||
<span>Параллельная проекция</span>
|
<span>Параллельная проекция</span>
|
||||||
<canvas id="canvas3" width="300" height="300" style="border: 1px solid gray;">
|
<canvas id="canvas3" width="300" height="300" style="border: 1px solid gray;">
|
||||||
<p>Ваш браузер не поддерживает Canvas</p>
|
<p>Холст для отображения результатов вычислений</p>
|
||||||
</canvas>
|
</canvas>
|
||||||
</div>
|
</div>
|
||||||
<div style="display: flex; flex-direction: column;">
|
<div style="display: flex; flex-direction: column;">
|
||||||
<span>Перспективная проекция</span>
|
<span>Перспективная проекция</span>
|
||||||
<canvas id="canvas4" width="300" height="300" style="border: 1px solid gray;">
|
<canvas id="canvas4" width="300" height="300" style="border: 1px solid gray;">
|
||||||
<p>Ваш браузер не поддерживает Canvas</p>
|
<p>Холст для отображения результатов вычислений</p>
|
||||||
</canvas>
|
</canvas>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -60,11 +61,11 @@ date: 2023.01.15
|
||||||
|
|
||||||
Слегка усложнённая версия из предыдущего примера — теперь кубиков много. В дополнение к предыдущим настройкам
|
Слегка усложнённая версия из предыдущего примера — теперь кубиков много. В дополнение к предыдущим настройкам
|
||||||
можно поменять: вариант фигуры — *пространственный крест* или *крест-куб*, направление сортировки граней
|
можно поменять: вариант фигуры — *пространственный крест* или *крест-куб*, направление сортировки граней
|
||||||
— *линейная перспектива* или *обратная перспектива* и прозрачность стенок кубиков.
|
— *прямая перспектива* или *обратная перспектива* и прозрачность стенок кубиков.
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<canvas id="canvas5" width="300" height="300" style="border: 1px solid gray;">
|
<canvas id="canvas5" width="300" height="300" style="border: 1px solid gray;">
|
||||||
<p>Ваш браузер не поддерживает Canvas</p>
|
<p>Холст для отображения результатов вычислений</p>
|
||||||
</canvas>
|
</canvas>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
|
@ -105,7 +106,7 @@ date: 2023.01.15
|
||||||
<output name="result">300</output>
|
<output name="result">300</output>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<label for="center">Показать центральную точку:</label>
|
<label for="center">Двигать центральную точку:</label>
|
||||||
<input type="checkbox" id="center" name="center" oninput="showCenter(event)">
|
<input type="checkbox" id="center" name="center" oninput="showCenter(event)">
|
||||||
</div>
|
</div>
|
||||||
<span>Прозрачность кубиков:</span>
|
<span>Прозрачность кубиков:</span>
|
||||||
|
@ -123,10 +124,10 @@ date: 2023.01.15
|
||||||
<input type="radio" id="second" name="figure" value="second" checked>
|
<input type="radio" id="second" name="figure" value="second" checked>
|
||||||
<label for="second">Куб</label>
|
<label for="second">Куб</label>
|
||||||
</form>
|
</form>
|
||||||
<span>Перспективная проекция:</span>
|
<span>Линейная перспектива:</span>
|
||||||
<form oninput="changeOrder(event)">
|
<form oninput="changeOrder(event)">
|
||||||
<input type="radio" id="linear" name="order" value="linear" checked>
|
<input type="radio" id="linear" name="order" value="linear" checked>
|
||||||
<label for="linear">Линейная</label>
|
<label for="linear">Прямая</label>
|
||||||
<input type="radio" id="reverse" name="order" value="reverse">
|
<input type="radio" id="reverse" name="order" value="reverse">
|
||||||
<label for="reverse">Обратная</label>
|
<label for="reverse">Обратная</label>
|
||||||
</form>
|
</form>
|
||||||
|
@ -134,12 +135,13 @@ date: 2023.01.15
|
||||||
|
|
||||||
{% include heading.html text="Описание алгоритма" hash="algorithm-description" %}
|
{% include heading.html text="Описание алгоритма" hash="algorithm-description" %}
|
||||||
|
|
||||||
Подготавливаем матрицу из нулей и единиц, где единица означает кубик в определенном месте фигуры. Затем
|
Подготавливаем трёхмерную матрицу из нулей и единиц, где единица означает кубик в определенном месте фигуры.
|
||||||
обходим эту матрицу и заполняем массив кубиков с соответствующими координатами вершин. После этого запускаем
|
Затем обходим эту матрицу и заполняем массив кубиков с соответствующими координатами вершин. После этого
|
||||||
вращение по всем трём осям сразу. На каждом шаге обходим массив кубиков и получаем проекции их граней. Затем
|
запускаем вращение по всем трём осям сразу. На каждом шаге обходим массив кубиков и получаем проекции их
|
||||||
сортируем массив граней по удалённости от центра проекции, обходим этот массив и выкидываем из него одинаковые
|
граней. Затем сортируем массив граней по удалённости от центра проекции, обходим этот массив и выкидываем
|
||||||
пары — это есть смежные стенки между соседними кубиками внутри фигуры. После этого полупрозрачным цветом рисуем
|
из него одинаковые пары — это есть смежные стенки между соседними кубиками внутри фигуры. После этого
|
||||||
грани кубиков — сначала дальние и затем ближние, чтобы через ближние грани было видно дальние.
|
рисуем полупрозрачным цветом грани кубиков — сначала дальние, а затем ближние, чтобы через ближние грани
|
||||||
|
было видно дальние.
|
||||||
|
|
||||||
{% include heading.html text="Реализация на JavaScript" hash="implementation-in-javascript" %}
|
{% include heading.html text="Реализация на JavaScript" hash="implementation-in-javascript" %}
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
---
|
---
|
||||||
title: Объёмный тетрис
|
title: Объёмный тетрис
|
||||||
description: Общеобразовательная игра в широком смысле этого слова. При изучении языков программирования рекомендуется сначала написать свою версию и потом использовать...
|
description: Общеобразовательная игра в широком смысле этого слова. В процессе изучения языков программирования рекомендуется сначала написать свою версию и потом...
|
||||||
sections: [Логическая игра,Экспериментальный интерфейс]
|
sections: [Логическая игра,Экспериментальный интерфейс]
|
||||||
tags: [javascript,онлайн,canvas,игра,головоломка,геометрия,матрица,графика,квадрат,куб,3d,трёхмерный]
|
tags: [javascript,онлайн,canvas,игра,классика,головоломка,геометрия,матрица,графика,квадрат,куб,3д,трёхмерный]
|
||||||
scripts: [/js/classes-point-cube.js,/js/tetris-figures.js,/js/tetris-model.js,/js/tetris-controller.js,/js/tetris-view.js]
|
scripts: [/js/classes-point-cube.js,/js/tetris-figures.js,/js/tetris-model.js,/js/tetris-controller.js,/js/tetris-view.js]
|
||||||
styles: [/css/pomodoro1.css]
|
styles: [/css/pomodoro1.css]
|
||||||
canonical_url: /ru/2023/01/21/volumetric-tetris.html
|
canonical_url: /ru/2023/01/21/volumetric-tetris.html
|
||||||
|
@ -11,16 +11,17 @@ title_translated: Volumetric tetris
|
||||||
date: 2023.01.21
|
date: 2023.01.21
|
||||||
---
|
---
|
||||||
|
|
||||||
Общеобразовательная игра в широком смысле этого слова. При изучении языков программирования рекомендуется
|
Общеобразовательная игра в широком смысле этого слова. В процессе изучения языков программирования
|
||||||
сначала написать свою версию и потом использовать её для демонстрации и тестирования другого программного
|
рекомендуется сначала написать свою версию и потом использовать её для демонстрации и тестирования
|
||||||
обеспечения или оборудования. Трёхмерный интерфейс написан на JavaScript Canvas — логика самой игры двухмерная.
|
другого программного обеспечения или оборудования. Трёхмерный интерфейс написан на JavaScript Canvas
|
||||||
|
— логика самой игры двухмерная. Дополнительные внешние библиотеки не используются.
|
||||||
|
|
||||||
Описание алгоритма графики: [Вращаем куб в пространстве]({{ '/ru/2023/01/10/spinning-cube-in-space.html' | relative_url }}).
|
Описание алгоритма графики: [Вращаем куб в пространстве]({{ '/ru/2023/01/10/spinning-cube-in-space.html' | relative_url }}).
|
||||||
|
|
||||||
{% include heading.html text="Экспериментальный интерфейс" hash="experimental-interface" %}
|
{% include heading.html text="Экспериментальный интерфейс" hash="experimental-interface" %}
|
||||||
|
|
||||||
По умолчанию выключен — можно просто играть в тетрис. В дополнение к плоской версии добавлены два объёмных
|
По умолчанию выключен — можно просто играть в тетрис. В дополнение к двухмерной версии добавлены два объёмных
|
||||||
варианта: *параллельная проекция* и *перспективная проекция* — параметры для каждого из них можно изменять.
|
варианта — *параллельная проекция* и *перспективная проекция* — параметры для каждого из них можно изменять.
|
||||||
Для перспективной проекции: можно изменять положение экрана наблюдателя и удалённость источника проекции.
|
Для перспективной проекции: можно изменять положение экрана наблюдателя и удалённость источника проекции.
|
||||||
Наблюдатель смотрит в центр изображения, а центр проекции удалён на расстояние, сопоставимое с размерами
|
Наблюдатель смотрит в центр изображения, а центр проекции удалён на расстояние, сопоставимое с размерами
|
||||||
игрового поля. Для параллельной проекции: можно изменять вертикальное положение. Для обеих проекций: можно
|
игрового поля. Для параллельной проекции: можно изменять вертикальное положение. Для обеих проекций: можно
|
||||||
|
@ -28,24 +29,24 @@ date: 2023.01.21
|
||||||
точка поля. Для всех вариантов изображения: размер кубика — 32, размер квадратика — 30 и отступ — 2.
|
точка поля. Для всех вариантов изображения: размер кубика — 32, размер квадратика — 30 и отступ — 2.
|
||||||
Начало координат расположено в верхней левой точке, оси направлены: `X` вправо, `Y` вниз и `Z` вдаль.
|
Начало координат расположено в верхней левой точке, оси направлены: `X` вправо, `Y` вниз и `Z` вдаль.
|
||||||
|
|
||||||
*Пример использования:* начинаем игру, набираем какое-то количество фигур на поле, затем ставим игру на
|
<b>Тестирование:</b> начинаем игру, набираем некоторое количество фигур на поле, ставим игру на паузу,
|
||||||
паузу, и переключаемся между вариантами объёмного изображения, поворачиваем поле с фигурами, изменяем
|
а затем переключаем варианты объёмного изображения, поворачиваем поле с фигурами, изменяем прозрачность,
|
||||||
настройки и так далее.
|
двигаем центральную точку и так далее.
|
||||||
|
|
||||||
|
<b>Управление:</b> кнопки на клавиатуре со стрелками — вправо, влево, вверх, вниз и кнопка пауза `pause`.
|
||||||
|
|
||||||
{% include volumetric-tetris-ru.html -%}
|
{% include volumetric-tetris-ru.html -%}
|
||||||
|
|
||||||
{% include heading.html text="Игровой процесс" hash="gaming-process" %}
|
{% include heading.html text="Игровой процесс" hash="gaming-process" %}
|
||||||
|
|
||||||
Управление: кнопки на клавиатуре со стрелками — вправо, влево, вверх, вниз и кнопка пауза `pause`.
|
|
||||||
|
|
||||||
Игровые очки начисляются за полностью собранные строки из элементов фигур. Количество набранных очков зависит
|
Игровые очки начисляются за полностью собранные строки из элементов фигур. Количество набранных очков зависит
|
||||||
от количества собранных строк, по 10 очков за каждую строку, если в строке 10 кубиков, и кратно увеличивается,
|
от количества собранных строк, по 10 очков за каждую строку, если в строке 10 кубиков, и кратно увеличивается,
|
||||||
если одновременно собрано: 2 строки — в 3 раза, 3 строки — в 5 раз, 4 строки — в 10 раз.
|
если одновременно собрано: 2 строки — в 3 раза, 3 строки — в 5 раз, 4 строки — в 10 раз.
|
||||||
|
|
||||||
Особенность игры: собранные строки сначала моргают и после этого исчезают, при этом игровой процесс на это
|
<b>Особенность игры:</b> собранные строки сначала моргают и после этого исчезают — при
|
||||||
время не приостанавливается — текущая фигура продолжает падать.
|
этом игровой процесс на это время не останавливается — текущая фигура продолжает падать.
|
||||||
|
|
||||||
Уровень увеличивается при сборе 10 заполненных строк, то есть 100 очков, если в строке 10 кубиков. На каждом
|
Уровень увеличивается при сборе 10 заполненных строк, то есть 100 очков, если в строке 10 кубиков. На каждом
|
||||||
новом уровне, скорость фигур повышается и на 21 уровне достигает максимума. В режиме улитки скорость повышается
|
новом уровне скорость фигур увеличивается и на 21 уровне достигает максимума. В режиме улитки увеличение
|
||||||
в 5 раз медленнее и достигает максимума на 104 уровне. Текущая скорость отображается над игровым полем в виде
|
скорости становится медленнее в 5 раз, и скорость фигур достигает максимума на 104 уровне. Текущая скорость
|
||||||
индикатора `meter`.
|
отображается над игровым полем в виде индикатора `meter`.
|
||||||
|
|
|
@ -11,26 +11,27 @@ title_translated: Code with comments
|
||||||
{%- assign articles = "" | split: "" %}
|
{%- assign articles = "" | split: "" %}
|
||||||
{%- assign articles = articles | push: "Объёмный тетрис" %}
|
{%- assign articles = articles | push: "Объёмный тетрис" %}
|
||||||
{%- capture article_brief %}
|
{%- capture article_brief %}
|
||||||
Общеобразовательная игра в широком смысле этого слова. При изучении языков программирования рекомендуется
|
Общеобразовательная игра в широком смысле этого слова. В процессе изучения языков программирования
|
||||||
сначала написать свою версию и потом использовать её для демонстрации и тестирования другого программного
|
рекомендуется сначала написать свою версию и потом использовать её для демонстрации и тестирования
|
||||||
обеспечения или оборудования. Трёхмерный интерфейс написан на JavaScript Canvas — логика самой игры двухмерная.
|
другого программного обеспечения или оборудования. Трёхмерный интерфейс написан на JavaScript Canvas
|
||||||
|
— логика самой игры двухмерная. Дополнительные внешние библиотеки не используются.
|
||||||
{%- endcapture %}
|
{%- endcapture %}
|
||||||
{%- assign articles = articles | push: article_brief %}
|
{%- assign articles = articles | push: article_brief %}
|
||||||
{%- assign articles = articles | push: "Вращаем пространственный крест" %}
|
{%- assign articles = articles | push: "Вращаем пространственный крест" %}
|
||||||
{%- capture article_brief %}
|
{%- capture article_brief %}
|
||||||
Пишем алгоритм для поворота объёмной фигуры на угол вокруг своего центра по всем трём осям сразу. В
|
Пишем алгоритм для поворота трёхмерной фигуры вокруг своего центра по всем трём осям сразу. В предыдущем
|
||||||
предыдущем примере мы вращали куб в пространстве — теперь кубиков будет много, алгоритм будет почти
|
примере мы вращали куб в пространстве — в этом примере кубиков будет много, алгоритм будет почти такой
|
||||||
такой же и формулы будем использовать те же. Рисуем два варианта фигуры: *пространственный крест* и
|
же, и формулы будем использовать те же. Для наглядности возьмём два варианта симметричной объёмной фигуры
|
||||||
*крест-куб* в двух типах проекций, рассматриваем разницу.
|
в двух типах проекций — *пространственный крест* и *крест-куб* — рассматриваем разницу между ними.
|
||||||
{%- endcapture %}
|
{%- endcapture %}
|
||||||
{%- assign articles = articles | push: article_brief %}
|
{%- assign articles = articles | push: article_brief %}
|
||||||
{%- assign articles = articles | push: "Вращаем куб в пространстве" %}
|
{%- assign articles = articles | push: "Вращаем куб в пространстве" %}
|
||||||
{%- capture article_brief %}
|
{%- capture article_brief %}
|
||||||
Рассматриваем разницу между параллельной и перспективной проекцией. Обе широко используются на практике
|
Рассмотрим разницу между параллельной и перспективной проекцией. Обе широко используются на практике
|
||||||
для различных целей. В предыдущем примере мы вращали квадрат на плоскости — переходим в трёхмерное
|
для различных целей. В предыдущем примере мы вращали квадрат на плоскости — переходим в трёхмерное
|
||||||
пространство. Теперь, чтобы отобразить на плоскости экрана поворот трёхмерного объекта, нужно сначала
|
пространство. Теперь, чтобы отобразить на плоскости экрана поворот трёхмерного объекта, нужно сначала
|
||||||
создать *математическую модель* трёхмерного объекта, повернуть её на угол, срисовать с неё проекцию и
|
создать *математическую модель* трёхмерного объекта, повернуть её на угол, срисовать с неё проекцию
|
||||||
отобразить на экране уже проекцию.
|
и отобразить на экране уже проекцию. Для наглядности будем использовать декартову систему координат.
|
||||||
{%- endcapture %}
|
{%- endcapture %}
|
||||||
{%- assign articles = articles | push: article_brief %}
|
{%- assign articles = articles | push: article_brief %}
|
||||||
{%- assign articles = articles | push: "Вращаем квадрат на плоскости" %}
|
{%- assign articles = articles | push: "Вращаем квадрат на плоскости" %}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
echo "Подготовка архива для последующего развёртывания."
|
echo "Создание архива для последующего развёртывания."
|
||||||
cd _site || exit
|
cd _site || exit
|
||||||
rm -rf ../pomodoro1.zip
|
rm -rf ../pomodoro1.zip
|
||||||
7z a ../pomodoro1.zip ./*
|
7z a ../pomodoro1.zip . | grep -E '\S'
|
||||||
|
|
2
serve.sh
2
serve.sh
|
@ -1,4 +1,4 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
echo "Локальное развёртывание для проверки корректности сборки."
|
echo "Локальное развёртывание для проверки корректности сборки."
|
||||||
jekyll serve --skip-initial-build --disable-disk-cache --host localhost
|
jekyll serve --skip-initial-build --no-watch --disable-disk-cache --host localhost
|
||||||
echo "Адрес сервера: http://localhost:4000"
|
echo "Адрес сервера: http://localhost:4000"
|
||||||
|
|
Loading…
Add table
Reference in a new issue