PDA

Просмотр полной версии : Вращение и повороты сферы из мувиков


OlegEF
11.06.2010, 16:24
Не могу найти ошибку.
Сфера моделируется, и даже вращается, но не на одном месте.



var arr = new Array();
var arr_3D = new Array();
var n:Number = 0;
var ugol:Number = 0;

var step_ugol:Number = 5;

var d_ugol:Number = 1;

var step:Number = 0.2;

var X0:Number = 200;
var Y0:Number = 200;



var m0 = [1,0,0,0];
var m1 = [0,1,0,0];
var m2 = [0,0,1,-0.002];
var m3 = [0,0,0,1];


//поворот по оси икс
var r0x = [1,0,0,0];
var r1x = [0,0.866025,-0.5,0];
var r2x = [0,0.5,0.866025,0];
var r3x = [0,0,0,1];

//y
var r0y = [0.866025,0,0.5,0];
var r1y = [0,1,0,0];
var r2y = [-0.5,0,0.866025,0];
var r3y = [0,0,0,1];

//z
var r0z = [0.866025,-0.5,0,0];
var r1z = [0.5,0.866025,0,0];
var r2z = [0,0,1,0];
var r3z = [0,0,0,1];




function rotate(i:Number, a:Number, b:Number, c:Number ):Array
{
var x1,y1,z1;

x1= new Number(arr_3D[i][0]);
y1= new Number(arr_3D[i][1]);
z1= new Number(arr_3D[i][2]);

var sa=Math.sin(a),ca=Math.cos(a),sb=Math.sin(b),cb=Math.cos(b),sc=Math.sin(c),cc=Math.cos(c);

var ox=x1,oy=y1,oz=z1;

x1 = ox*cb*cc - oy*cb*sc + oz*sb;
y1 = ox*(cc*sa*sb+ca*sc) + oy*(ca*cc-sa*sb*sc) - oz*(cb*sa);
z1 = ox*(sa*sc-ca*cc*sb) + oy*(cc*sa+ca*sb*sc) + oz*(ca*cb);

arr_3D[i][0] = x1;
arr_3D[i][1] = y1;
arr_3D[i][2] = z1;

var arr_res = new Array();
arr_res[0] = x1;
arr_res[1] = y1;
arr_res[2] = z1;

return arr_res;
}



function translate(x1:Number, y1:Number, z1:Number):Array
{
var arr1 = new Array(4);
arr1[0]=x1;
arr1[1]=y1;
arr1[2]=z1;
arr1[3]=1;

var arr_res = new Array(4);
for(var i=0;i<4;i++)
{
arr_res[i] = 0;
for(var j=0;j<4;j++)
{
// trace("m0[j]="+m0[j]);
// trace("arr1[j]="+arr1[j]);

var temp:Number = 0;
if(i==0) temp = m0[j];
else if(i==1) temp = m1[j];
else if(i==2) temp = m2[j];
else if(i==3) temp = m3[j];




arr_res[i] += temp*arr1[j];


}

}

if(arr_res[3] != 1)
{
arr_res[0] = Math.round(arr_res[0]/arr_res[3]);
arr_res[1] = Math.round(arr_res[1]/arr_res[3]);
arr_res[2] = Math.round(arr_res[2]/arr_res[3]);
}
return arr_res;
}

/*
Для того, чтобы применить преобразование, задаваемое такой матрицей,
координату каждой вершины (x,y,z) надо превратить в вектор {x, y, z, 1}
и умножить на матрицу.
Если 4-я координата полученного вектора не равна 1,
следует все координаты вектора разделить на значение 4-й координаты.
На экран выводим точку, задаваемую первыми двумя координатами такого вектора (x,y).
*/

function set_little_sphere(f:Number, t:Number):Void
{
arr[n]=attachMovie("lsphere","lsphere",n);

var x1 = X0 + Math.round(60 * Math.sin(f) * Math.cos(t));
var y1 = Y0 +Math.round(60 * Math.sin(f) * Math.sin(t));
var z1 = Math.round(60 * Math.cos(f));

arr_3D[n] = [x1, y1, z1];

//arr1 = translate(x1,y1,z1);
//arr1 = rotate(x1,y1,z1, ugol);
//trace(arr_3D[n]);

x1 = arr1[0];
y1 = arr1[1];

arr[n]._x=x1;
arr[n]._y=y1;


n++;
}

function make_house():Void
{
var x1:Number = null;
var y1:Number = null;
var z1:Number = null;

var lim:Number = Math.PI * 2;

for (var fi = 0; fi< lim; fi+= step)
{

for (var teta = 0; teta<lim; teta+= step)
{
//fi = Math.round(fi);
//teta = Math.round(teta);
//trace("fi="+fi+", teta="+teta);
set_little_sphere(fi, teta);


}
}

}

function visual():Void
{
ugol += d_ugol;
ugol_rad = ugol * Math.PI/180;

var dir1:Number = Math.round(Math.random()*3);
var a=b=c=0;
if(dir1 == 0) { a = ugol_rad}
else if(dir1 == 1) {b = ugol_rad}
else if(dir1 == 2) {c = ugol_rad}

//trace("a="+a+",b="+b+",c="+c);

for(var i =0; i<arr_3D.length;i++)
{
var arr1 = rotate(i, a, b, c);
//trace(arr1);

arr[i]._x = arr1[0];
arr[i]._y = arr1[1];
}

if(ugol > 359) ugol = 0;

}

//translate(20,20,20);
make_house(); // создает n клипов
// Будет вращать клипы
var time:Number=setInterval(visual,1200);

rainbowrussia
11.06.2010, 19:02
var arr = new Array();
var arr_3D = new Array();
var n:Number = 0;
var ugol:Number = 0;

var step_ugol:Number = 5;

var d_ugol:Number = 1;

var step:Number = 0.2;

var X0:Number = 200;
var Y0:Number = 200;



var m0 = [1,0,0,0];
var m1 = [0,1,0,0];
var m2 = [0,0,1,-0.002];
var m3 = [0,0,0,1];


//поворот по оси икс
var r0x = [1,0,0,0];
var r1x = [0,0.866025,-0.5,0];
var r2x = [0,0.5,0.866025,0];
var r3x = [0,0,0,1];

//y
var r0y = [0.866025,0,0.5,0];
var r1y = [0,1,0,0];
var r2y = [-0.5,0,0.866025,0];
var r3y = [0,0,0,1];

//z
var r0z = [0.866025,-0.5,0,0];
var r1z = [0.5,0.866025,0,0];
var r2z = [0,0,1,0];
var r3z = [0,0,0,1];




function rotate(i:Number, a:Number, b:Number, c:Number ):Array
{
var x1,y1,z1;

x1= new Number(arr_3D[i][0]);
y1= new Number(arr_3D[i][1]);
z1= new Number(arr_3D[i][2]);

var sa=Math.sin(a),ca=Math.cos(a),sb=Math.sin(b),cb=Math.cos(b),sc=Math.sin(c),cc=Math.cos(c);

var ox=x1,oy=y1,oz=z1;

x1 = ox*cb*cc - oy*cb*sc + oz*sb;
y1 = ox*(cc*sa*sb+ca*sc) + oy*(ca*cc-sa*sb*sc) - oz*(cb*sa);
z1 = ox*(sa*sc-ca*cc*sb) + oy*(cc*sa+ca*sb*sc) + oz*(ca*cb);

arr_3D[i][0] = x1;
arr_3D[i][1] = y1;
arr_3D[i][2] = z1;

var arr_res = new Array();
arr_res[0] = x1;
arr_res[1] = y1;
arr_res[2] = z1;

return arr_res;
}



function translate(x1:Number, y1:Number, z1:Number):Array
{
var arr1 = new Array(4);
arr1[0]=x1;
arr1[1]=y1;
arr1[2]=z1;
arr1[3]=1;

var arr_res = new Array(4);
for(var i=0;i<4;i++)
{
arr_res[i] = 0;
for(var j=0;j<4;j++)
{
// trace("m0[j]="+m0[j]);
// trace("arr1[j]="+arr1[j]);

var temp:Number = 0;
if(i==0) temp = m0[j];
else if(i==1) temp = m1[j];
else if(i==2) temp = m2[j];
else if(i==3) temp = m3[j];




arr_res[i] += temp*arr1[j];


}

}

if(arr_res[3] != 1)
{
arr_res[0] = Math.round(arr_res[0]/arr_res[3]);
arr_res[1] = Math.round(arr_res[1]/arr_res[3]);
arr_res[2] = Math.round(arr_res[2]/arr_res[3]);
}
return arr_res;
}

/*
Для того, чтобы применить преобразование, задаваемое такой матрицей,
координату каждой вершины (x,y,z) надо превратить в вектор {x, y, z, 1}
и умножить на матрицу.
Если 4-я координата полученного вектора не равна 1,
следует все координаты вектора разделить на значение 4-й координаты.
На экран выводим точку, задаваемую первыми двумя координатами такого вектора (x,y).
*/

function set_little_sphere(f:Number, t:Number):Void
{
arr[n]=attachMovie("lsphere","lsphere",n);

var x1 = Math.round(60 * Math.sin(f) * Math.cos(t));
var y1 = Math.round(60 * Math.sin(f) * Math.sin(t));
var z1 = Math.round(60 * Math.cos(f));

arr_3D[n] = [x1, y1, z1];

//arr1 = translate(x1,y1,z1);
//arr1 = rotate(x1,y1,z1, ugol);
//trace(arr_3D[n]);

x1 = arr1[0];
y1 = arr1[1];

arr[n]._x=x1;
arr[n]._y=y1;


n++;
}

function make_house():Void
{
var x1:Number = null;
var y1:Number = null;
var z1:Number = null;

var lim:Number = Math.PI * 2;

for (var fi = 0; fi< lim; fi+= step)
{

for (var teta = 0; teta<lim; teta+= step)
{
//fi = Math.round(fi);
//teta = Math.round(teta);
//trace("fi="+fi+", teta="+teta);
set_little_sphere(fi, teta);


}
}

}

function visual():Void
{
ugol += d_ugol;
ugol_rad = ugol * Math.PI/180;

var dir1:Number = Math.round(Math.random()*3);
var a=b=c=0;
if(dir1 == 0) { a = ugol_rad}
else if(dir1 == 1) {b = ugol_rad}
else if(dir1 == 2) {c = ugol_rad}

//trace("a="+a+",b="+b+",c="+c);

for(var i =0; i<arr_3D.length;i++)
{
var arr1 = rotate(i, a, b, c);
//trace(arr1);

arr[i]._x = X0 + arr1[0];
arr[i]._y = Y0 + arr1[1];
}

if(ugol > 359) ugol = 0;

}

//translate(20,20,20);
make_house(); // создает n клипов
// Будет вращать клипы
var time:Number=setInterval(visual,1200);


Добавлять X0 и Y0 нужно не в процедуре инициализации трехмерных координат точек, а в момент позиционирования точек на экране. В противном случае вы получаете еще и поворот относительно [0,0] сцены.

OlegEF
11.06.2010, 22:46
Ура! Заработало. Спасибо. Теперь буду оптимизировать.
Хочу на каждый мувик подвесить ссылку или тег чтобы было объемное облако тегов.

rainbowrussia
11.06.2010, 22:54
Такое распределение точек не подойдет для облака тэгов, для облака нужно более-менее равномерное распределение точек по поверхности.

OlegEF
12.06.2010, 07:03
Работаю над этим