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

时间:2013-04-29 20:33:58

标签: javascript html5 css3 math raphael

我使用Raphael JS构建了一个由三个元素组成的简单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”代表translate(x,y),r代表旋转。这些值由Raphael自动计算。 当遵循直线路径时,这一切都会解决,但是一旦curCar旋转,轮胎的计算就会失败。

一个例子:

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

我的主要问题是:

考虑到旋转,如何计算正确的X / Y位置? 必须有一个共同的数学公式来做这件事。

2 个答案:

答案 0 :(得分:1)

让我们暂时把整辆车翻译出来。你想要旋转汽车及其轮胎。对于每个轮胎,您可以通过将旋转矩阵应用到其旧中心来找到其新中心。

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。可以简单地将整车的翻译添加到该结果中。

答案 1 :(得分:1)

车轮应该转换为w.r.t.汽车(车身)的旋转中心。需要注意的是,旋转中心可以是任何地方。车。为简单起见,以下代码假定旋转中心与汽车中心重合。

最后,如果翻译和轮换符合执行顺序,Raphael可以处理数学变换。

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");

希望这有帮助。