【问题标题】:Rotate around a changing origin - Javascript围绕不断变化的原点旋转 - Javascript
【发布时间】:2015-08-15 08:05:01
【问题描述】:

所以我有一个围绕原点旋转的对象。一旦我旋转然后更改原点。我的对象似乎跳了位置。跳跃后它旋转良好......需要帮助找到模式/为什么它会跳跃以及我需要做些什么来阻止它。

这是轮换代码:

adjustMapTransform = function (_x, _y) {

    var x = _x + (map.width/2);
    var y = _y + (map.height/2);   


    //apply scale here 
    var originPoint = {
        x:originXInt,
        y:originYInt
    };

    var mapOrigin = {
        x:map.x + (map.width/2),
        y:map.y + (map.height/2)
    };    

    //at scale 1
    var difference = {
        x:mapOrigin.x - originPoint.x,
        y:mapOrigin.y - originPoint.y
    };

    x += (difference.x * scale) - difference.x;
    y += (difference.y * scale) - difference.y;

    var viewportMapCentre = {
        x: originXInt,
        y: originYInt
    }

    var rotatedPoint = {};
    var angle = (rotation) * Math.PI / 180.0;
    var s = Math.sin(angle);
    var c = Math.cos(angle);

    // translate point back to origin:
    x -= viewportMapCentre.x;
    y -= viewportMapCentre.y;

    // rotate point
    var xnew = x * c - y * s;
    var ynew = x * s + y * c;

  // translate point back:
    x = xnew + viewportMapCentre.x -  (map.width/2);
    y = ynew + viewportMapCentre.y - (map.height/2);  

    var coords = {
        x:x,
        y:y
    };

    return coords;
}

这里还有一个 JS Fiddle 项目,您可以在其中玩耍,让您更好地了解正在发生的事情。

EDITED LINK - 摆脱了 originY 错误和缩放错误 https://jsfiddle.net/fionoble/6k8sfkdL/13/

谢谢!

【问题讨论】:

  • 不仅移动 y 原点在 x 移动之前无效
  • scale 也不起作用,因为我认为它应该,例如,如果您缩放更改原点然后缩放它不会将新大小添加到前一个大小,而是重新缩放,就好像我将地图居中一样设置原点然后缩放,而不是我缩放更改原点然后再次缩放。
  • 谢谢@MuhammadUmer。我用 originY 错误修复编辑了 JSFiddle
  • 好像我需要反向旋转原点
  • jsfiddle.net/xerxesnoble/yt7dbj03 我更新了您的代码,以便地图围绕不断变化的原点旋转/缩放。事实上,您的代码按原样工作。我只是在 displayLoop 的每个“步骤”上更新原点,而不是 oninput。但是,这表明您的问题出在其他地方:变化的原点实际上转换了 #mapContainer 内的地图 x/y 位置。

标签: javascript math rotation


【解决方案1】:

旋转方向是您为旋转矩阵中的元素选择的符号的结果。 [这是二维旋转的罗德里格斯公式]。因此,要向相反方向旋转,只需减去您的 y 余弦项而不是您的 y 正弦项。

您也可以尝试查看数据的不同潜在表示形式。

如果您使用点之间的线的对称表示,您可以避免移动,而是简单地转换您的坐标。

将您的原点 [相对于您的旋转] c_0 作为对称形式的恒定偏移量。

你有一个相对于 c_0 的点 p:

    var A = (p.x - c_0.x);
    var B = (p.y - c_0.y);

 //This is the symmetric form.   
 (p.x - c_0.x)/A = (p.y - c_0.y)/B

这在坐标变化下和线上的任何点都是正确的(它也负责缩放/扩张)。

那么在旋转坐标改变之后,你有[注意这个旋转有相反的意义,和你的不一样]。

  //This is the symmetric form of the line incident on your rotated point
  //and on the center of its rotation
  ((p.x - c_0.x) * c + (p.y - c_0.y) * s)/A = ((p.x - c_0.x) * s - (p.y - c_0.y) * c)/B 

所以,相乘得到

  (pn.x - c_0.x) * B * c + (pn.y - c_0.y) * B * s = (pn.x - c_0.x) * A * s - (pn.y - c_0.y) * A * c

重排给了

  (pn.x - c_0.x) * (B * c - A * s) = - (pn.y - c_0.y) * (B * s + A * c)

 pn.y = -(pn.x - c_0.x) * (B * c - A * s) /  (B * s + A * c) + c_0.y;

适用于任何缩放。

【讨论】:

  • 比较语句是否旨在检查值是否正确?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-12-31
  • 1970-01-01
  • 2019-08-30
  • 2018-08-03
相关资源
最近更新 更多