旋转一组对象坐标 [英] Rotate a set of object coordinates

查看:128
本文介绍了旋转一组对象坐标的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一堆对象(ActiveRecord),它们具有相对于HTML5 canvas元素的x和y坐标。我需要以不同的度数(以90度递增)旋转它们的集合,然后再次存储它们以进行一次数据迁移。

这些对象都是相对的到一个画布元素,所以坐标从(0,0)开始,如果可能,我希望他们留在那个象限(右下角)。我假设我需要围绕(0,0)进行旋转,然后向下翻译右键。



有没有一种方法可以编写一个块这个?任何帮助表示赞赏。



更新:进行了一些修改,以便在出现一些问题后更清楚。 $ b

感谢。

解决方案


  1. 旋转点 P 围绕原点的 R 度:

    P2.x = Px * cos( R ) - Py * sin( R

    P2.y = Px * sin( R )+ Py * cos( R

    [引文]

  2. 想要围绕象限中心的任意一点旋转,如果你的象限是200x100单位宽度,你想围绕< 100,50>



    要围绕除原点以外的位置 C 旋转点 P 你想先把位置翻译成原点,然后绕着原点旋转然后转回C.换句话说,

    P2 = P - C

    P3 =旋转( P2

    P4 = P3 + C



    你可以在 http://phrogz.net/SVG/rotations.xhtml - 单击以设置旋转中心或更改旋转量,并在转换为原点的点组上设置变换,旋转,然后再次翻译。 在Ruby中的任意点附近使用c> x 和 y 属性,您可以使用如下代码:

      Point = Struct.new(:x,:y)do 
    def self.to_proc
    lambda {| x | self.new * x}
    end

    def rotate(degrees,origin = Point.new(0,0))
    radians = degrees * Math :: PI / 180
    x2 = x-origin.x; y2 = y-origin.y
    cos = Math.cos(弧度); sin = Math.sin(弧度)
    self.class.new(
    x2 * cos - y2 * sin + origin.x,
    x2 * sin + y2 * cos + origin.y

    结束

    def检查
    <%1f,%。1f> %[x,y]
    end
    end

    points = [[0,0],[1,2],[3,4],[5,6] ] .map(&Point)
    p points
    #=> [<0.0,0.0>,<1.0,2.0>,<3.0,4.0>,<5.0,6.0>]

    p points.map {| p | p.rotate(90)}
    #=> [<0.0,0.0>,<-2.0,1.0>,<-4.0,3.0>,<-6.0,5.0>]

    p points.map {| p | p.rotate(90,Point.new(3,4))}
    #=> [<7.0,1.0>,<5.0,2.0>,< 3.0,4.0>,< 1.0,6.0>]


    I have a bunch of objects (ActiveRecord) that have x and y coordinates relative to a HTML5 canvas element. I need to rotate sets of them by different number of degrees (in 90 degrees increments) and then store them again for a one time data migration.

    These objects are all relative to a canvas element so the coordinates start at (0,0) and I would like them to stay in that quadrant (bottom right), if possible. I assume that I need to do a rotation around (0,0) and then a translation down and right.

    Is there a way I can write a block that will do this? Any help is appreciated.

    Update: did some edits to make it clearer after some questions.

    Thanks.

    解决方案

    1. To rotate a point P an amount of R degrees around the origin:
      P2.x = P.x * cos(R) - P.y * sin(R)
      P2.y = P.x * sin(R) + P.y * cos(R)
      [citation]

    2. You probably want to rotate about an arbitrary point in the center of the quadrant you are keeping the objects in. If your quadrant is 200x100 units wide, you'd want to rotate around the point <100,50>.

      To rotate a point P around a location C other than the origin, you want to first translate the location to the origin, then rotate around the origin, and then translate back to C. In other words,
      P2 = P - C
      P3 = rotate(P2)
      P4 = P3 + C

      You can see this in action at http://phrogz.net/SVG/rotations.xhtml - click to set the rotation center, or change the rotation amount, and a transform is set on the group of points that translates to the origin, rotates, and then translates back again.

    Put it all together, and to rotate a point with x and y attributes around an arbitrary point in Ruby, you'd use code like this:

    Point = Struct.new(:x,:y) do
      def self.to_proc
        lambda{ |x| self.new *x }
      end
    
      def rotate( degrees, origin=Point.new(0,0) )
        radians = degrees * Math::PI/180
        x2 = x-origin.x; y2 = y-origin.y
        cos = Math.cos(radians); sin = Math.sin(radians)
        self.class.new(
          x2*cos - y2*sin + origin.x, 
          x2*sin + y2*cos + origin.y 
        )
      end
    
      def inspect
        "<%.1f,%.1f>" % [x,y]
      end
    end
    
    points = [ [0,0], [1,2], [3,4], [5,6] ].map(&Point)
    p points
    #=> [<0.0,0.0>, <1.0,2.0>, <3.0,4.0>, <5.0,6.0>]
    
    p points.map{ |p| p.rotate(90) }
    #=> [<0.0,0.0>, <-2.0,1.0>, <-4.0,3.0>, <-6.0,5.0>]
    
    p points.map{ |p| p.rotate(90,Point.new(3,4)) }
    #=> [<7.0,1.0>, <5.0,2.0>, <3.0,4.0>, <1.0,6.0>]
    

    这篇关于旋转一组对象坐标的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆