如果你转到以下链接,你会看到一个非常酷的Javascript模拟,它根据你的鼠标位置旋转。
模拟:here.
如果您查看立方体旋转脚本的来源,您将看到:
<script type="text/javascript">
/* I wrote this script in a few minutes just for fun. It's not made to win any
competition. */
var dimension = 1, a = 0, b = 0, i = 27;
while (i--) document.write('<b id="l' + i + '">+</b>');
function f()
{
i = 0;
for (x = -dimension; x <= dimension; x += dimension)
for (y = -dimension; y <= dimension; y += dimension)
for (z = -dimension; z <= dimension; z += dimension)
{
u = x;
v = y;
w = z;
u2 = u * Math.cos(a) - v * Math.sin(a);
v2 = u * Math.sin(a) + v * Math.cos(a);
w2 = w;
u = u2; v = v2; w = w2;
u2 = u;
v2 = v * Math.cos(b) - w * Math.sin(b);
w2 = v * Math.sin(b) + w * Math.cos(b);
u = u2; v = v2; w = w2;
var c = Math.round((w + 2) * 70);
if (c < 0) c = 0;
if (c > 255) c = 255;
s = document.getElementById('l' + i).style;
s.left = 300 + u * (w + 2) * 50;
s.top = 300 + v * (w + 2) * 50;
s.color = 'rgb(' + c + ', ' + c + ', 0)';
s.fontSize = (w + 2) * 16 + 'px';
/* The Digg users missed depth sort, so here it is. */
s.zIndex = Math.round((w + 2) * 10);
i++;
}
}
/* Using a timer instead of the onmousemove handler wastes CPU time but makes
the animation much smoother. */
setInterval('f()', 17);
</script>
我已多次查看过了,我仍然不明白如何计算立方体的点数。这是使用“Euler Rotations”吗?我遇到的一个大问题是使用单字母变量名对我没什么意义。
具备必备数学知识的人是否有助于解释在此模拟中旋转立方体后数学如何工作?我想做类似的事情,但在计算积分位置时,我有点失落。
答案 0 :(得分:7)
您忘记提到的重要事项是全局a和b在body标签中设置:
<body onmousemove="a = event.clientX / 99; b = event.clientY / 99;"
变量列表:
他使用与欧拉角相似的方法,但他只使用两个轴,因此没有使用欧拉角的隐含限制。
有关三维旋转的更多信息,请查看维基百科:
http://en.wikipedia.org/wiki/Rotation_matrix#Dimension_three
另请注意,他的投影不是真正的3D:他没有按z坐标划分投影到二维空间。所以深度是“扭曲的”(很难解释,但如果你连接十字架,它们将不会形成一个立方体,而是一个扭曲的立方体)。在真正的二维投影中,直线将再次形成直线。
正确的透视投影看看这篇文章(不要被矩阵的东西搞糊涂了......只是图表和简单的拦截定理就是你所需要的):
http://en.wikipedia.org/wiki/Perspective_projection#Perspective_projection
x' = x * (eye_dist / eye_dist + z)
y' = y * (eye_dist / eye_dist + z)
对于这种简单的方法,没关系,严重的3d将适用于齐次坐标。
答案 1 :(得分:2)
想法是使用标准旋转矩阵。在2D中,这是:
-- -- -- -- -- --
| x_new | | cos(a) -sin(a) | | x_old |
| | = | | | |
| y_new | | sin(a) cos(a) | | y_old |
--- -- -- -- -- --
a
是您旋转的角度。
我们的想法是,您正在使用此transformatoin将每个点转换为新点。为了更好地了解这一点,考虑一个单位圆(我不知道如何使用ASCII艺术绘制),并问自己如何将点(0,1)移动到(sqrt(2)/2,sqrt(2)/2)
(45学位轮换)。
x_new = x_old * cos(45) - y_old * sin(45) = 1 * sqrt(2)/2 - 0 * sqrt(2)/2 = sqrt(2)/2
y_new = x_old * sin(45) + y_old * cos(45) = 1 * sqrt(2)/2 + 0 * sqrt(2)/2 = sqrt(2)/2
现在将其转换为(1,0)
,另一个45度旋转:
x_new = x_old * cos(45) - y_old * sin(45) = sqrt(2)/2 * sqrt(2)/2 - sqrt(2)/2 * sqrt(2)/2 = 0
y_new = x_old * sin(45) + y_old * cos(45) = sqrt(2)/2 * sqrt(2)/2 + sqrt(2)/2 * sqrt(2)/2 = 1
将其扩展为3D非常简单,您只需使用另一个多重操作来沿XZ平面旋转。