2023-12-17 07:55:25 +03:00
|
|
|
// © Головин Г.Г., Экспериментальная модель, 2023
|
|
|
|
'use strict';
|
|
|
|
let d5=300,tv5={x:150,y:150,z:125},show=false;
|
|
|
|
let deg2={x:1,y:1,z:1};
|
|
|
|
let sortOrder=true,alpha=20,first=false;
|
|
|
|
// обработчики событий в форме
|
|
|
|
function changeAxis(val,caller) {
|
|
|
|
deg2[val]=0+caller.target.checked;
|
|
|
|
}
|
|
|
|
function changeDistance(caller) {
|
|
|
|
d5=caller.target.valueAsNumber;
|
|
|
|
}
|
|
|
|
function changeTv(val,caller) {
|
|
|
|
tv5[val]=caller.target.valueAsNumber;
|
|
|
|
}
|
|
|
|
function showCenter(caller) {
|
|
|
|
show=caller.target.checked;
|
|
|
|
}
|
|
|
|
function changeFigure(caller) {
|
|
|
|
if (caller.target.value=="first") first=true;
|
|
|
|
if (caller.target.value=="second") first=false;
|
|
|
|
}
|
|
|
|
function changeOrder(caller) {
|
|
|
|
if (caller.target.value=="linear") sortOrder=true;
|
|
|
|
if (caller.target.value=="reverse") sortOrder=false;
|
|
|
|
}
|
|
|
|
function changeAlpha(caller) {
|
|
|
|
alpha=caller.target.valueAsNumber;
|
|
|
|
}
|
|
|
|
const canvas5 = document.getElementById('canvas5');
|
|
|
|
// перетаскивание центральной точки мышью
|
|
|
|
let msBtnPressed = false;
|
|
|
|
canvas5.onmouseup = ()=> msBtnPressed=false;
|
|
|
|
canvas5.onmousedown = (caller)=> {
|
|
|
|
msBtnPressed=true;
|
|
|
|
canvas5.onmousemove(caller);
|
|
|
|
}
|
|
|
|
canvas5.onmousemove = (caller)=> {
|
|
|
|
if (msBtnPressed && show) {
|
|
|
|
tv5.x=caller.offsetX;
|
|
|
|
tv5.y=caller.offsetY;
|
|
|
|
document.getElementById('rangeX').value=caller.offsetX;
|
|
|
|
document.getElementById('resultX').value=caller.offsetX;
|
|
|
|
document.getElementById('rangeY').value=caller.offsetY;
|
|
|
|
document.getElementById('resultY').value=caller.offsetY;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// массивы для кубиков
|
|
|
|
const cubes5a = [], cubes5b = [];
|
|
|
|
// обходим матрицы, заполняем массивы кубиками
|
|
|
|
for (let x=0; x<row; x++)
|
|
|
|
for (let y=0; y<row; y++)
|
|
|
|
for (let z=0; z<row; z++) {
|
|
|
|
if (shape1[x][y][z]==1)
|
|
|
|
cubes5a.push(new Cube(x*size+gap,y*size+gap,z*size+gap,size));
|
|
|
|
if (shape2[x][y][z]==1)
|
|
|
|
cubes5b.push(new Cube(x*size+gap,y*size+gap,z*size+gap,size));
|
|
|
|
}
|
|
|
|
// поворот фигуры и обновление изображения
|
|
|
|
function repaint5() {
|
|
|
|
if (first) // пространственный крест
|
|
|
|
processFigure5(cubes5a,canvas5);
|
|
|
|
else // крест-куб
|
|
|
|
processFigure5(cubes5b,canvas5);
|
|
|
|
}
|
|
|
|
// поворачиваем фигуру и получаем проекции
|
|
|
|
function processFigure5(cubes,canvas) {
|
|
|
|
// массив проекций граней кубиков
|
|
|
|
let proj = [];
|
|
|
|
// поворачиваем кубики и получаем проекции
|
|
|
|
for (let cube of cubes) {
|
|
|
|
cube.rotate(deg2, t0);
|
|
|
|
proj = proj.concat(cube.projection('perspective',tv5,d5));
|
|
|
|
}
|
|
|
|
// смежные стенки между соседними кубиками не рисуем
|
|
|
|
noAdjacent(proj);
|
|
|
|
// сортируем грани по удалённости
|
|
|
|
proj.sort((a,b)=>b.dist-a.dist);
|
|
|
|
// сортировка в обратном порядке
|
|
|
|
if (!sortOrder) proj.reverse();
|
|
|
|
// рисуем перспективную проекцию
|
|
|
|
drawFigure(canvas, proj, (100-alpha)/100);
|
|
|
|
// центральная точка перспективной проекции
|
|
|
|
if (show) centerPoint(canvas);
|
|
|
|
}
|
|
|
|
// центральная точка перспективной проекции
|
|
|
|
function centerPoint(canvas) {
|
|
|
|
const context = canvas.getContext('2d');
|
|
|
|
context.beginPath();
|
|
|
|
context.lineWidth = 3.2;
|
|
|
|
context.strokeStyle = '#66bb6a';
|
|
|
|
context.arc(tv5.x, tv5.y, 6.5, 0, 2*Math.PI);
|
|
|
|
context.stroke();
|
|
|
|
}
|
2023-12-17 08:08:38 +03:00
|
|
|
// после загрузки страницы, задаём частоту обновления изображения 20 Гц
|
2023-12-17 07:55:25 +03:00
|
|
|
document.addEventListener('DOMContentLoaded',()=>setInterval(repaint5,50));
|