Javascript 根据对象,在翻译对象时考虑旋转。

Javascript 根据对象,在翻译对象时考虑旋转。,javascript,html,css,math,raphael,Javascript,Html,Css,Math,Raphael,我制作了一个简单的2D汽车,由三个元素组成,使用。为此,我将身体作为一个图像和两个轮胎。我分离元素是因为我希望轮胎在动画中旋转 var curCar = raphael.image("car.png", /* x */ 0, /* y */ 0, /* width */ 120, /* height*/ 82) var tires = raphael.set(); tires.push( raphael.image("tire.png", 2, 50, 32, 32), raph

我制作了一个简单的2D汽车,由三个元素组成,使用。为此,我将身体作为一个图像和两个轮胎。我分离元素是因为我希望轮胎在动画中旋转

var curCar = raphael.image("car.png", /* x */ 0, /* y */ 0, /* width */ 120, /* height*/ 82)
var tires = raphael.set();
tires.push(
    raphael.image("tire.png", 2, 50, 32, 32),
    raphael.image("tire.png", 84, 50, 32, 32)
);
如您所见,轮胎位于汽车的“底部”,并且已经向右对齐。 现在,curCar使用Raphael.animate跟随一条路径,这很好。对于动画的每次更新,我都会将轮胎平移到curCar的位置。有点像这样:

function animationUpdate (pos) {
    curCar.transform("t" + [pos.x, pos.y] +" r"+ pos.alpha);
    tires.transform("t" + [pos.x, pos.y ]);
};
“t”代表平移(x,y),r代表旋转。这些值由Raphael自动计算。 当沿着直线行驶时,这一切都能解决,但一旦curCar旋转,轮胎的计算就会失败

例如:

curCar位于x:100/y:200位置,并旋转10°。 轮胎转换为x:102/y:150和x:184/y:250。因此,curCar旋转10°,轮胎不合适

我的主要问题是:

考虑到旋转,如何计算正确的X/Y位置?
必须有一个通用的数学公式来实现这一点。

暂时不考虑整个汽车的平移。你想转动汽车和轮胎。对于每个轮胎,可以通过将旋转矩阵应用于其旧中心来找到其新中心

x'=x∙cosα− Y∙sinα
y'=x∙sinα+y∙cosα

我假设Raphaël使用左上角作为图像的位置。如果是这样,那么您的原始中心将是(2+32/2,50+32/2)=(18,66)和(84+32/2,50+32/2)=(100,66)。因此,对于上述公式,这些将是
(x,y)
。得到的位置将再次成为中心位置,因此必须从所有坐标中减去16。整个汽车的平移可以简单地添加到该结果中。

车轮应通过汽车(车身)的旋转中心进行变换。需要注意的是,旋转中心可以位于车辆的任何位置。为简单起见,以下代码假定旋转中心与汽车中心重合

最后,如果平移和旋转的顺序正确,拉斐尔可以处理数学变换

var paper = Raphael.paper(0, 0, 500, 400);
    // tire width
var tw = 10,
    thw = tw * 0.5,
    // car width
    cw = 100,
    chw = cw * 0.5,
    // car height
    ch = 50,
    chh = ch * 0.5,
    // x of tire 1 w.r.t. car
    t1xc = -chw - thw,
    // x of tire 2 w.r.t. car
    t2xc = -chw - thw,
    // y of tire 1 w.r.t. car
    t1yc = -chh - thw,
    // y of tire 2 w.r.t. car
    t2yc = chh - thw;

var car = paper.rect(20, 20, cw, ch),
    // car center
    cx = car.attr('x') + chw,
    cy = car.attr('y') + chh,
    // tire 1
    t1 = paper.rect(cx + t1xc, cy + t1yc, tw, tw),
    // tire 2
    t2 = paper.rect(cx + t2xc, cy + t2yc, tw, tw);
// Translate by 100, 100 and rotate by 30 deg
car.transform("...t100,100r30");
// car center post transformation
cx = car.attr('x') + chw;
cy = car.attr('y') + chh;
// Transform tires, with rotation w.r.t. car center 
/* Edited - To add wheel rotation about axle (25 deg) */
t1.transform("...t100,100r30," + [cx, cy] + "r25");
t2.transform("...t100,100r30," + [cx, cy] + "r25");

希望这有帮助。

螺钉和刻度都是“s”有线代码!这可能有点奇怪,但是使用Element.transform(tStr)methodthx进行转换非常容易!我在一个例子中应用了这个公式,你可以在这里看到:拉斐尔总是使用对象的中间作为旋转点。测试时,它会给我输出奇怪的负数。@DavidSkx:Raphaël似乎用度表示角度,而标准的JavaScript数学要求弧度。因此,只需编写
alpha*Math.PI/180
即可。感谢您的代码,它非常有效。但是,如果已经应用了旋转来定位,我怎么能仍然为轮胎设置动画呢?@DavidSkx,我对要求有点不确定。您代码中的animationUpdate函数可以更改为接受3个重要参数,即。changeInX、changeInY和changeingle。使用params和我代码中的实现代码将使汽车和车轮按照需要进行动画制作。或者您想绕轴旋转车轮?@DavidSkx您可以添加另一个旋转因子,这次将对象中心作为旋转中心。请参阅添加的零件“r25”,它实际上将车轮绕其自身中心旋转25度。这与定位无关。t1.变换(“…T100100R30,+[cx,cy]+“r25”)@DavidSkx很高兴在这里看到拉斐尔·阿皮的力量t1.变换(“…T100100R30,+[cx,cy]+“r25”);他工作得很好。我从来都不知道你可以应用多重旋转。太棒了。raphael绝对是现代浏览器中的动画素材。我在IE8中使用了它,尽管动画非常复杂。