我有下面的代码,其中我试图设置相对于我定义的偏移量的块变换的动画。 但是,这不是一个平滑的转换,而是让这个非常奇怪的行为,它似乎是复制到三胞胎,然后加倍,然后回到三连,然后再回到单身。
我知道这是一种视错觉,但我很好奇为什么我没有在定义的点周围获得逐渐旋转的预期行为,而是获得这种推动效果。
我是2d / 3d操作的新手,我不明白它的所有数学,但我想学习它,这就是为什么我写这个,以掌握实际发生的数字与哪些数字
我正在寻找解释为什么会出现这种情况,因为它并不是我所期待的......
回顾一下:随着学位的增加,我期待逐渐轮换,而不是我在整个地方动画。我做错了什么?
function BlockPos(x,y,z) {
this.x = x;
this.y = y;
this.z = z;
}
BlockPos.prototype.getX = function() {
return this.x;
}
BlockPos.prototype.getZ = function() {
return this.z;
}
BlockPos.prototype.getY = function() {
return this.y;
}
BlockPos.prototype.setX = function(x) {
this.x = x;
}
BlockPos.prototype.setZ = function(z) {
this.z = z;
}
BlockPos.prototype.setY = function(y) {
this.y = y;
}
function Block(color,blockpos) {
this.color = color;
this.blockpos = blockpos;
}
Block.prototype.getBlock = function() {
return '<div style="display:inline-block;width:38px;height:38px;position:absolute;left:'+(this.blockpos.getX()*40)+'px;top:'+(this.blockpos.getZ()*40)+'px;border:1px solid gray;background-color:'+this.color+'"></div>';
}
arr = [
new Block('green',new BlockPos(1,1,1)),
new Block('green',new BlockPos(1,1,2)),
new Block('green',new BlockPos(1,1,3)),
new Block('red',new BlockPos(2,1,1)),
new Block('red',new BlockPos(3,1,1)),
new Block('red',new BlockPos(4,1,1)),
new Block('red',new BlockPos(5,1,1))
];
html = '';
center = new BlockPos(0,1,0);
function rotateAroundPoint(pos, center,angle) {
//POINT rotate_point(float cx,float cy,float angle,POINT p)
var s = Math.sin(angle);
var c = Math.cos(angle);
var p = new BlockPos(pos.getX(),pos.getY(),pos.getZ());
// translate point back to origin:
p.x -= center.getX();
p.z -= center.getZ();
// rotate point
var xnew = p.x * c - p.z * s;
var znew = p.x * s + p.z * c;
// translate point back:
p.x = xnew + center.getX();
p.z = znew + center.getZ();
return p;
}
function degreesToRadians(degrees) {
return degrees * 3.14159265358979323846264338327950288 /180
}
function rotate(arr,center,degrees) {
for(var c=0;c<arr.length;c++) {
pos = rotateAroundPoint(arr[c].blockpos,center,degreesToRadians(degrees));
arr[c].blockpos.setX(pos.getX());
arr[c].blockpos.setZ(pos.getZ());
}
return arr;
}
var rotation = 0;
window.setInterval(function() {
rotation+=1;
if(rotation >= 360) rotation = 0;
var html = rotation+' degrees<BR/>';
arr = rotate(arr,center,rotation);
for(c=0;c<arr.length;c++) {
html += arr[c].getBlock();
}
$('#foo').html(html);
},50);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div style="position:relative;top:200px;left:200px;background-color:yellow;width:500px;height:500px;" id="foo">
</div>
答案 0 :(得分:1)
问题的核心在于:
arr = rotate(arr,center,rotation);
您可以在已轮换的arr
上指定轮播,并且不要在轮换功能中考虑 delta 时间。相反,你将(已经旋转的)arr
旋转了经过的总时间 - 这会产生加速/积累的东西。
考虑相同的代码,增量时间为1
。
function BlockPos(x,y,z) {
this.x = x;
this.y = y;
this.z = z;
}
BlockPos.prototype.getX = function() {
return this.x;
}
BlockPos.prototype.getZ = function() {
return this.z;
}
BlockPos.prototype.getY = function() {
return this.y;
}
BlockPos.prototype.setX = function(x) {
this.x = x;
}
BlockPos.prototype.setZ = function(z) {
this.z = z;
}
BlockPos.prototype.setY = function(y) {
this.y = y;
}
function Block(color,blockpos) {
this.color = color;
this.blockpos = blockpos;
}
Block.prototype.getBlock = function() {
return '<div style="display:inline-block;width:38px;height:38px;position:absolute;left:'+(this.blockpos.getX()*40)+'px;top:'+(this.blockpos.getZ()*40)+'px;border:1px solid gray;background-color:'+this.color+'"></div>';
}
arr = [
new Block('green',new BlockPos(1,1,1)),
new Block('green',new BlockPos(1,1,2)),
new Block('green',new BlockPos(1,1,3)),
new Block('red',new BlockPos(2,1,1)),
new Block('red',new BlockPos(3,1,1)),
new Block('red',new BlockPos(4,1,1)),
new Block('red',new BlockPos(5,1,1))
];
html = '';
center = new BlockPos(0,1,0);
function rotateAroundPoint(pos, center,angle) {
//POINT rotate_point(float cx,float cy,float angle,POINT p)
var s = Math.sin(angle);
var c = Math.cos(angle);
var p = new BlockPos(pos.getX(),pos.getY(),pos.getZ());
// translate point back to origin:
p.x -= center.getX();
p.z -= center.getZ();
// rotate point
var xnew = p.x * c - p.z * s;
var znew = p.x * s + p.z * c;
// translate point back:
p.x = xnew + center.getX();
p.z = znew + center.getZ();
return p;
}
function degreesToRadians(degrees) {
return degrees * 3.14159265358979323846264338327950288 /180
}
function rotate(arr,center,degrees) {
for(var c=0;c<arr.length;c++) {
pos = rotateAroundPoint(arr[c].blockpos,center,degreesToRadians(degrees));
arr[c].blockpos.setX(pos.getX());
arr[c].blockpos.setZ(pos.getZ());
}
return arr;
}
var rotation = 0;
window.setInterval(function() {
rotation+=1;
if(rotation >= 360) rotation = 0;
var html = rotation+' degrees<BR/>';
arr = rotate(arr,center,1);
for(c=0;c<arr.length;c++) {
html += arr[c].getBlock();
}
$('#foo').html(html);
},50);
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div style="position:relative;top:200px;left:200px;background-color:yellow;width:500px;height:500px;" id="foo">
</div>
&#13;
答案 1 :(得分:-1)
就像你说的那样,这是一种视错觉。由于旋转速度如此之快,正方形在每个帧之间移动四分之一甚至三分之一的旋转,因此对于您的眼睛来说,它看起来像是对象的多个副本,因为它只是“跳”到它的新位置。你的代码没有任何问题,它只是我们的眼睛处理运动的方式。你甚至可以通过观看粉丝在现实生活中看到这一点。在某些速度下,您会看到刀片缓慢移动甚至向后移动。