Кубик Маврика
Вчера был на редкость плодотворный день, я таки дописал свой кубик. напомню что сначала я не мог даже квадрат на плоскости развернуть. Но терпение и труд все перетрут, наверное ;)
Вторая редакция кубика не имеет ничего общего с первой. Все полностью переделано. Теперь вместо того чтобы высчитывать углы наклонов и поворотов рёбер от угла поворота куба, я решил сделать так, как делается в нормальнйо трехмерной графике. Нарисовать сцену, положить в координаты [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>
но это не конец, в следующей версии планируется натяжка текстур на грани и добавление света, или раскраска сторон с добавлением полупрозрачности, я еще не решил что буду делать.
Свежие комментарии