Кубик Маврика

Вчера был на редкость плодотворный день, я таки дописал свой кубик. напомню что сначала я не мог даже квадрат на плоскости развернуть. Но терпение и труд все перетрут, наверное ;)

Вторая редакция кубика не имеет ничего общего с первой. Все полностью переделано. Теперь вместо того чтобы высчитывать углы наклонов и поворотов рёбер от угла поворота куба, я решил сделать так, как делается в нормальнйо трехмерной графике. Нарисовать сцену, положить в координаты [0,0,0] центр куба, по векторам высчитать вершины и нарисовать между ними линии. Что собственно с успехом и реализовал.

теперь как видите ничего нигде не точит и все прекрасно отображается. пришлось конешно пошаманить, прописать все углы, ребра и векторы но зато теперь все идеально. Куб можно изменять в размерах, отдалять и приближать «камеру», красить в произвольный цвет и все это при помощи настроек.

По просьбе Adw0rd’a выкладываю сырцы которые все это генерируют:


Cube = function(options){
	this.init(options);
}

Cube.prototype = {
	
	color : "#000000", // цвет граней
	plot : null, // 2d context
	size : 10, // размер куба
	focalLens : 0, // расстояние от центра куба до камеры
	theta : [0,0], // углы поворотов по осям в радианах
	V2d : [[],[]], // вектора в двухмерной проекции
	
	T : [], // Translation vector
	E : [[],[]], // Edges
	R : [[],[],[]], // Rotation matrix
	V : [[],[],[]], // Vertices

	init : function(options){
		
		for (var i in options)
			this[i] = options[i];
			
		if(!this.focalLens)
			this.focalLens = this.plot.canvas.width;
			
		var self = this;
		document.onmousemove = function(event){
			self.theta = [event.clientX / 100, event.clientY / 100];
			self.draw();
		}			
			
		this.createScene();
		this.draw();
	},
	
	createScene : function (){
		var s = this.size;
		
		this.V = [
			[-s, s, s,-s,-s, s, s,-s],
			[-s,-s, s, s,-s,-s, s, s],
			[-s,-s,-s,-s, s, s, s, s],
		];
		
		this.E = [
			[0,1,2,3,4,5,6,7,0,1,2,3],
			[1,2,3,0,5,6,7,4,4,5,6,7],
		];
		
		this.R = [
			[1,0,0],
			[0,1,0],
			[0,0,1],
		];
		
		this.T = [0,0,0];
	},

	updVertices : function (){
		var x, y, z;
		
		for(var i=0;i<8;i++){
			x=this.R[0][0]*this.V[0][i]+this.R[0][1]*this.V[1][i]+this.R[0][2]*this.V[2][i]+this.T[0];
			y=this.R[1][0]*this.V[0][i]+this.R[1][1]*this.V[1][i]+this.R[1][2]*this.V[2][i]+this.T[1];
			z=this.R[2][0]*this.V[0][i]+this.R[2][1]*this.V[1][i]+this.R[2][2]*this.V[2][i]+this.T[2];

			this.V2d[0][i]=this.plot.canvas.width/2+x*this.focalLens/z;
			this.V2d[1][i]=this.plot.canvas.height/2+y*this.focalLens/z;
		}
	},


	setTransformation : function (x, y, z, anglex, angley){
		var 
		sx = Math.sin(anglex),
		cx = Math.cos(anglex),
		sy = Math.sin(angley),
		cy = Math.cos(angley);
		
		this.R = [
			[ cx   , 0 ,  sx],
			[ sx*sy, cy, -cx*sy],
			[-sx*cy, sy,  cx*cy],
		];
		this.T = [x,y,z];
	},

	drawModel : function (){
		this.plot.beginPath();
		this.plot.strokeStyle=this.color;
		for(var i=0;i<12;i++){
			this.plot.moveTo(this.V2d[0][this.E[0][i]],this.V2d[1][this.E[0][i]]);
			this.plot.lineTo(this.V2d[0][this.E[1][i]],this.V2d[1][this.E[1][i]]);
			this.plot.stroke();
		}
	},
	
	drawCells : function(){
		this.plot.fillStyle="black";
		for(var i=100,l=this.plot.canvas.width;i<l;i+=100){
			this.plot.fillRect(0,i,l,1);
			this.plot.fillRect(i,0,1,l);
		}
	
	},

	draw : function (){
		var self = this;

		this.plot.clearRect(0,0,this.plot.canvas.width,this.plot.canvas.height);
		this.setTransformation(0.0, 0.0, 40.0, this.theta[0], this.theta[1]);
		this.updVertices();
		this.drawCells();
		this.drawModel();
	},
}


window.onload=function(){
	var plot = document.getElementById("cube").getContext("2d"),
	
	cube = new Cube({plot:plot,color:"#00FF00",size:10});
}

И еще три строчки HTML:


<script type="text/javascript" src="/content/source/cube-0.2.js"></script>
<script type="text/javascript" src="/content/source/excanvas.js"></script>
<div style="text-align:center;"><canvas  id="cube" width="500" height="500"/></div>

но это не конец, в следующей версии планируется натяжка текстур на грани и добавление света, или раскраска сторон с добавлением полупрозрачности, я еще не решил что буду делать.

7 Комментарии “Кубик Маврика

  1. Роскошно! Нет, правда здорово — доводи до продакшена скрипт … и что дальше — не знаю, но все равно здорово!

  2. Классно, продолжай!
    Где сорцы, что за блог программиста и без сорцов?

  3. блин мне письма перестали приходить о новых каментах(((

    сырцы щас будут :)

    а дальше игрушки писать ;)

  4. >блин мне письма перестали приходить о новых каментах(((
    дудохостинг?)

    >а дальше игрушки писать ;)
    я дуду предлагал кое что, ща в скайпе расскажу

Комментарии закрыты