Уроки, алгоритмы, программы, примеры

Вход на сайт

Материалы по разделам

Построения
на плоскости (2D)
Графика
в пространстве (3D)
Вычислительная
геометрия
Физическое
моделирование
Фрактальная
графика

Новые комментарии

Пиривет сайт с работой закладчиком Работа курьером Значение финансов в повседневной жизни известно каждому, но что делать, если зарплата на постоянной работе невелика или ее вообще нет? Если у Вас нет профессии или возникли иные сложности, то...
Модные тренды медицинской одежды - новая эра стиля и комфорта в 2024 году https://fkmed.r... C нами Вы убедитесь: качественная, комфортная и модная медицинская одежда существует! В каталоге на сайте представлена медицинская одежда для врачей и...
14 070 руб https://www.eco... 38 900 руб https://www.eco... и выберите из списка ниже: Купить в 1 клик https://www.eco... По типу двигателя снегоотбрасыватель может быть: Купить в 1 клик https://www.eco...
Все изделия хорошо сидят на фигуре и отличаются высокой степенью комфортности https://fkmed.r... Комбинированные ткани с применением хлопка и синтетики - это оптимальный вариант для пошива формы https://fkmed.r... Специальная пропитка...
53 990 руб https://www.eco... Экономия 4 160 руб https://www.eco... Купить в 1 клик https://www.eco... Главными элементами устройства являются двигатель, металлический или пластиковый корпус и лопасти для уборки снега https://www.eco... Тип...

Счетчики и рейтинг

Рейтинг@Mail.ru Яндекс.Метрика
Демо JavaScript: 

Вращение:

<canvas width = "600" height = "600"></canvas><br>
<b>Вращение:</b>
<input type = "range" min = "-10" max = "10" step = "0.00001" value = "0" id = "degY" oninput = "update()"><br>

<script>
	//3. Пирамида перед кубом
	var canvas = document.querySelector("canvas");
	var ctx = canvas.getContext("2d");
	ctx.translate(canvas.width/2, canvas.height/2);
	class Vector2d{ 
		constructor(x, y){
			this.x = x;
			this.y = y;
		}
		move(mx, my){
			let x = this.x + mx;
			let y = this.y + my;
			return new Vector2d(x, y);
		}
		scale(w){
			let x = this.x * w;
			let y = this.y * w;
			return new Vector2d(x, y);
		}
		rotate(angle){
			let x = this.x * Math.cos(angle) - this.y * Math.sin(angle);
			let y = this.x * Math.sin(angle) + this.y * Math.cos(angle);
			return new Vector2d(x, y);
		}
		static copy(vector){
			return new Vector2d(vector.x, vector.y);
		}
	}
	class Vector3d{
		constructor(x, y, z){
			this.x = x;
			this.y = y;
			this.z = z;
		}
		getProjection(dist){ //Получение проекции точек на плоскость
			let x = this.x*dist/this.z;
			let y = this.y*dist/this.z;
			return new Vector2d(x, y);
		}
		move(mx, my, mz){
			let x = this.x + mx;
			let y = this.y + my;
			let z = this.z + mz;
			return new Vector3d(x, y, z);
		}
		scale(w){
			let x = this.x * w;
			let y = this.y * w;
			let z = this.z * w;
			return new Vector3d(x, y, z);
		}
		rotate(angleX, angleY, angleZ){
			let x, y, z;
			let temp = new Vector3d(this.x, this.y, this.z);
			//Вращение вокруг оси 0Y
			x = temp.x * Math.cos(angleY) + (temp.z)* Math.sin(angleY);
			y = temp.y;
			z = -temp.x * Math.sin(angleY) + (temp.z) * Math.cos(angleY);
			temp.x = x; temp.y = y; temp.z = z;
			//Вращение вокруг оси 0X
			x = temp.x;
			y = temp.y  * Math.cos(angleX) + temp.z * Math.sin(angleX);
			z = -temp.y * Math.sin(angleX) + temp.z * Math.cos(angleX);
			temp.x = x; temp.y = y; temp.z = z;
			//Вращение вокруг оси 0Z
			x = temp.x  * Math.cos(angleZ) + temp.y * Math.sin(angleZ);
			y = -temp.x * Math.sin(angleZ) + temp.y * Math.cos(angleZ);
			z = temp.z;
			temp.x = x; temp.y = y; temp.z = z;
			return temp;
		}
		static copy(vector){
			return new Vector3d(vector.x, vector.y, vector.z);
		}
	}
	class Face{ //Класс граней
		static faces = [];
		constructor(){
				this.vertices = [...arguments];
				this.verticesForRender = [...this.vertices];
				Face.faces.push(this);
				this.x;
				this.y;
				this.z;
				this.color = "#" + Math.random().toString(16).slice(2,8);
		}
		render(){ //Отрисовка грани
			ctx.fillStyle = this.color;
			ctx.strokeStyle = "#50f";
			ctx.beginPath();
			let tempVector = this.verticesForRender[0].getProjection(500);
			ctx.moveTo(tempVector.x, tempVector.y);
			for(let vertex of this.verticesForRender){
				tempVector = vertex.getProjection(500);
				ctx.lineTo(tempVector.x, tempVector.y);
			}
			ctx.closePath();
			ctx.fill();
			ctx.stroke();
		}
		update(x, y, z, degX, degY, degZ){ //Замена векторон на повернутые и сдвинутые:D
			this.verticesForRender = this.vertices.map((vertex)=>vertex.move(0 + x, 0 + y, -900 + z));
			this.verticesForRender = this.verticesForRender.map((vertex)=>vertex.rotate(degX, degY, degZ));
			this.verticesForRender = this.verticesForRender.map((vertex)=>vertex.move(0 - x, 0 - y, 900 - z));
			this.verticesForRender = this.verticesForRender.map((vertex)=>vertex.move(x, y, z));
		}
		get minZ(){ //Получение минимальной точки Z у грани. В данном случае, Z - Глубина, Y - Высота, X - Ширина
			let min = this.verticesForRender[0].z;
			for(let vertex of this.verticesForRender){
				if(vertex.z < min){
					min = vertex.z;
				}
			}
			return min;
		}
		get maxZ(){ //Получение максимальной точки Z у грани. 
			let max = this.verticesForRender[0].z;
			for(let vertex of this.verticesForRender){
				if(vertex.z > max){
					max = vertex.z;
				}
			}
			return max;
		}
		get minX(){ //Получение минимальной точки Z у грани. В данном случае, Z - Глубина, Y - Высота, X - Ширина
			let min = this.verticesForRender[0].x;
			for(let vertex of this.verticesForRender){
				if(vertex.x < min){
					min = vertex.x;
				}
			}
			return min;
		}
		get maxX(){ //Получение максимальной точки Z у грани. 
			let max = this.verticesForRender[0].x;
			for(let vertex of this.verticesForRender){
				if(vertex.x > max){
					max = vertex.x;
				}
			}
			return max;
		}
	}
	class Polygon{ //Класс фигур состоящих из граней
		constructor(){
			this.faces = [...arguments];
		}
		render(){
			for(let face of this.faces){ //Вызываем метод отрисовки для каждой грани
				face.render();
			}
		}
		update(x, y, z, degX, degY, degZ){ //Присвоение новых координат и угла поворота
			for(let face of this.faces){
				face.update(x, y, z, degX, degY, degZ);
			}
		}
		get minZ(){ //Получение минимальной точки Z у фигуры !НЕ ПРИГОДИЛОСЬ
			let min = this.faces[0].minZ;
			for(let face of this.faces){
				if(face.minZ < min){
					min = face.minZ;
				}
			}
			return min;
		}
		get maxZ(){ //Получение максимальной точки Z у фигуры !НЕ ПРИГОДИЛОСЬ
			let max = this.faces[0].maxZ;
			for(let face of this.faces){
				if(face.maxZ > max){
					max = face.maxZ;
				}
			}
			return max;
		}
	}
	var triangle = new Polygon(
		new Face(
			new Vector3d(-100, 0, -100),
			new Vector3d(100, 0, -100),
			new Vector3d(100, 0, 100),
			new Vector3d(-100, 0, 100)
		),
		new Face(
			new Vector3d(0, -150, 0),
			new Vector3d(100, 0, -100),
			new Vector3d(100, 0, 100)
		),
		new Face(
			new Vector3d(0, -150, 0),
			new Vector3d(100, 0, 100),
			new Vector3d(-100, 0, 100)
		),
		new Face(
			new Vector3d(0, -150, 0),
			new Vector3d(-100, 0, 100),
			new Vector3d(-100, 0, -100)
		),
		new Face(
			new Vector3d(0, -150, 0),
			new Vector3d(100, 0, -100),
			new Vector3d(-100, 0, -100)
		)
	);
 
	var rectangle = new Polygon(
		new Face(
			new Vector3d(-100, -100, 100),
			new Vector3d(100, -100, 100),
			new Vector3d(100, 100, 100),
			new Vector3d(-100, 100, 100)
		),
		new Face(
			new Vector3d(-100, -100, -100),
			new Vector3d(100, -100, -100),
			new Vector3d(100, -100, 100),
			new Vector3d(-100, -100, 100)
		),
		new Face(
			new Vector3d(-100, -100, -100),
			new Vector3d(-100, 100, -100),
			new Vector3d(-100, 100, 100),
			new Vector3d(-100, -100, 100)
		),
		new Face(
			new Vector3d(100, -100, -100),
			new Vector3d(100, 100, -100),
			new Vector3d(100, 100, 100),
			new Vector3d(100, -100, 100)
		),
		new Face(
			new Vector3d(-100, -100, -100),
			new Vector3d(100, -100, -100),
			new Vector3d(100, 100, -100),
			new Vector3d(-100, 100, -100)
		),
		new Face(
			new Vector3d(-100, 100, -100),
			new Vector3d(100, 100, -100),
			new Vector3d(100, 100, 100),
			new Vector3d(-100, 100, 100)
		),
	);
	function update(){
		let x = 0;
		let y = 100;
		let z = 400;
		let degY = parseFloat(document.querySelector("#degY").value);
		triangle.update(x, y, z+200, 0, degY, 0);
		rectangle.update(x, y-70, 700+500, 0, degY, 0);
		Face.faces.sort((b, a)=>{
			a = Math.sqrt(a.maxZ**2 + a.maxX**2);
			b = Math.sqrt(b.maxZ**2 + b.maxX**2);
			return a - b;
		});
		render();
	}
	function render(){
		ctx.fillStyle = "#000";
		ctx.fillRect(-canvas.width/2, -canvas.height/2, canvas.width, canvas.height);
		Face.faces.forEach(face => face.render());
 
	}
	update();
	render();
</script>