围绕画布中的某个点旋转矩形

时间:2013-12-03 14:02:14

标签: javascript html5 math html5-canvas

我试图围绕其父矩形的中心旋转一个矩形。孩子与父母边界的距离必须始终保持不变。我几乎成功了,但我的方法似乎有一个小错误。我似乎无法找到问题。

示例:

http://jsfiddle.net/FJ789/3/

我正在使用以下公式围绕轴心点旋转。

var rotateAroundPoint = function(point, pivotPoint, sin, cos)
{
    position =
    {
        x : cos * (point.x - pivotPoint.x) - sin * (point.y - pivotPoint.y) + pivotPoint.x
    ,   y : sin * (point.x - pivotPoint.x) + cos * (point.y - pivotPoint.y) + pivotPoint.y
    };

    return position;
}

2 个答案:

答案 0 :(得分:1)

转换(平移和旋转)时不必计算边界框,因为这些转换实际上会旋转整个画布(而不仅仅是新绘制的元素)

这意味着您可以转换画布,然后正常绘制新元素。

例如,即使在context.translate和context.rotate之后,此代码也会将父级和子级相对于彼此绘制在相同的位置:

ctx.fillRect(0,0,100,50);   // parent
ctx.fillRect(10,10,30,20);  // child

演示:http://jsfiddle.net/m1erickson/WQ4tU/

在每个动画帧中:

  • 清除画布
  • 保存上下文状态
  • 转换为旋转中心点
  • 旋转画布
  • 绘制父子rects(通过将x / y偏移其宽度/高度的一半来允许先前的contect.translate)
  • 将上下文恢复为原始状态(未翻译和未翻转)

这是代码:

ctx.clearRect(0,0,canvas.width,canvas.height);
ctx.save();

// translate to the rotation centerpoint

ctx.translate(150,150);

// rotate

ctx.rotate(radianAngle);

// draw parent rect
// allow for previous ctx.translate by offsetting x/y by half width/height

ctx.fillStyle="green";
ctx.fillRect(-50,-30,100,60);

// draw child rect
// allow for previous ctx.translate by offsetting x/y by half width/height

ctx.fillStyle="red";
ctx.fillRect(-45,-25,30,20);

// restore the original context state

ctx.restore();

答案 1 :(得分:1)

enter image description here

Manipulate[
 Module[{opt}, opt = {SphericalRegion -> True, Axes -> False, Boxed -> False, 
    ViewVertical -> {0, 0, 1}, ViewPoint -> {.8, 1, .7}, 
    PlotRange -> {{-4, 4}, {-4.5, 4.5 }, {-1.5, 1.5}}, ImageSize -> 200, ImageMargins -> 1};

  theta = Mod[theta + .1, 2 Pi]; t;
  Grid[{
    {Graphics3D[{Rotate[{Cuboid[{3, -3, 0}, {-3, 3, .2}], 
         Rotate[{{Gray, Cuboid[{.5, -.5, .2}, {-.5, .5, .25}]}}, 
          2 theta, {0, 0, 1}, {0, 0, 1}]}, .5 theta, {0, 0, 1}, {0, 0,1}]}, opt],
     Graphics3D[{Rotate[{Cuboid[{3, -3, 0}, {-3, 3, .2}], 
        {Gray,Cuboid[{2.5, -2.5, .2}, {2, -2, .35}]}},2 theta,{0, 0, 1},{0, 0, 1}]},opt]},
    {Graphics3D[{Rotate[{Cuboid[{3, -3, 0}, {-3, 3, .2}], 
         Rotate[{Cuboid[{1.5, -1.5, .2}, {-1.5, 1.5, .35}], 
           Rotate[{Gray, Cuboid[{.75, -.75, .35}, {-.75, .75, .55}]},3 theta, 
           {0, 0, 1}, {0, 0, 1}]}, 
          2 theta, {0, 0, 1}, {0, 0, 1}]}, .5 theta, {0, 0, 1}, {0, 0,1}]}, opt],
     Graphics3D[{Rotate[{Cuboid[{3, -3, 0}, {-3, 3, .2}], 
         Rotate[{Cuboid[{1.5, -1.5, .2}, {-1.5, 1.5, .35}], 
           Rotate[{{Gray, Cuboid[{.75, -.75, .35}, {-.75, .75, .55}]},
              Rotate[{{Red,Cuboid[{.45, -.45, .55}, {-.45, .45, .75}]}},4 theta, 
             {0, 0, 1}, {0, 0, 1}]}, 
            3 theta, {0, 0, 1}, {0, 0, 1}]}, 
          2 theta, {0, 0, 1}, {0, 0, 1}]}, .5 theta, {0, 0, 1}, {0, 0, 1}]}, opt]}}]],
 {{t, 0, "run"}, 0, 100, .01},
 {{theta, 0}, None},
 {{a, 0}, None},
 TrackedSymbols :> {t}
 ]