代码之家  ›  专栏  ›  技术社区  ›  Andy E

给定一个角度和尺寸,沿着矩形的周长找到一个坐标。

  •  2
  • Andy E  · 技术社区  · 15 年前

    我正在写一个脚本,其中图标围绕给定的轴(或原点)旋转。我已经能够使图标围绕椭圆旋转,但我也希望它们围绕一个具有一定宽度、高度和原点的矩形的周长移动。

    我这样做是因为我当前的代码将所有坐标存储在一个数组中,每个角度整数作为键,并且重用此代码将更容易处理。

    如果有人能给我一个100x150矩形的例子,那就太好了。

    编辑: 为了澄清,通过旋转,我的意思是围绕一个形状的周界(或轨道)移动。

    6 回复  |  直到 8 年前
        1
  •  4
  •   Spooky Muscothym    9 年前

    你知道矩形的大小,你需要把整个角度间隔分割成四个不同的区域,所以你知道从矩形中心来的光线是否与矩形的右、上、左或下相交。

    如果角度为-atan(d/w)<alfa<atan(d/w),则光线与矩形的右侧相交。既然你知道从矩形中心到右边的x位移是d/2,那么位移dy除以d/2就是tan(alfa),所以

    Dy=d/2*tan(alfa)

    你可以用其他三个角度来处理这个问题。

    好的,来吧。你有一个宽度为w,深度为d的矩形。在中间有一个中心点,cp。我假设你想计算不同角度alfa值的p。

    alt text

    我把这个矩形分成四个不同的区域,或者角度间隔(1到4)。我上面提到的间隔是右边的第一个。我希望这对你有意义。

    首先你需要计算角度间隔,它们完全由w和d决定。 根据alfa的值,相应地计算p,即如果从cp到p的“光线”与矩形的上、下、右或左侧相交。

    干杯

        2
  •  1
  •   Rob Spiess    8 年前

    这是为Pebble SmartWatch设计的,并经验证可在其上工作,但修改为伪代码:

    struct GPoint {
      int x;
      int y;
    }
    
    // Return point on rectangle edge.  Rectangle is centered on (0,0) and has a width of w and height of h
    GPoint getPointOnRect(int angle, int w, int h) {
      var sine = sin(angle), cosine = cos(angle);   // Calculate once and store, to make quicker and cleaner
      var dy = sin>0 ? h/2 : h/-2;                  // Distance to top or bottom edge (from center)
      var dx = cos>0 ? w/2 : w/-2;                  // Distance to left or right edge (from center)
      if(abs(dx*sine) < abs(dy*cosine)) {           // if (distance to vertical line) < (distance to horizontal line)
        dy = (dx * sine) / cosine;                  // calculate distance to vertical line
      } else {                                      // else: (distance to top or bottom edge) < (distance to left or right edge)
        dx = (dy * cosine) / sine;                  // move to top or bottom line
      }
      return GPoint(dx, dy);                        // Return point on rectangle edge
    }
    
    
    Use:
    rectangle_width  = 100;
    rectangle_height = 150;
    rectangle_center_x = 300;
    rectangle_center_y = 300;
    draw_rect(rectangle_center_x - (rectangle_width/2), rectangle_center_y - (rectangle_center_h/2), rectangle_width, rectangle_height);
    GPoint point = getPointOnRect(angle, rectangle_width, rectangle_height);
    point.x += rectangle_center_x;
    point.y += rectangle_center_y;
    draw_line(rectangle_center_x, rectangle_center_y, point.x, point.y);
    
        3
  •  0
  •   breitak67    15 年前

    使用角度作为参数进行此操作的一个简单方法是使用矩形的边界简单地剪裁X和Y值。换句话说,计算位置,就像图标将围绕圆形或椭圆形路径旋转一样,然后应用此选项:

    (假设轴对齐矩形以(0,0)为中心,X轴长度为x axis,Y轴长度为y axis):

    if (X > XAxis/2)    
             X = XAxis/2;
    
    if (X < 0 - XAxis/2)
             X = 0 - XAxis/2;
    
    if (Y > YAxis/2)    
             Y = YAxis/2;
    
    if (Y < 0 - YAxis/2)    
             Y = 0 - YAxis/2;
    

    这种方法的问题是,角度将不完全准确,沿矩形周长的速度将不恒定。建模一个椭圆,在它的角落密切矩形可以最小化的影响,但如果你正在寻找一个平滑,恒定速度的“轨道”,这种方法将是不够的。

        4
  •  0
  •   nonopolarity    15 年前

    如果你认为你的意思是像地球围绕太阳旋转一样旋转(而不是自转…所以你的问题是如何沿着矩形的边缘滑动?)

    如果是这样,您可以尝试一下:

    # pseudo coode
    for i = 0 to 499
      if i < 100:  x++
      else if i < 250: y--
      else if i < 350: x--
      else y++
    
      drawTheIcon(x, y)
    

    更新: (请参阅下面的评论)

    要使用角度,一条线将

    y / x = tan(th)       # th is the angle
    

    其他线条很简单,因为它们只是水平或垂直的。例如,它是x=50,你可以把它放到上面的线中,得到y。在水平线和垂直线的交叉点做这个(例如,角度是60度,它拍摄“东北方向”……现在你有两点。然后,最接近原点的点是首先碰到矩形的点)。

        5
  •  0
  •   Alex Feinman    15 年前

    使用A 2D transformation matrix . 许多语言(例如Java)支持这个(查找的情感转换);否则,编写一个例程来自己旋转,一旦调试好,就永远使用它。我必须用五种不同的语言写。

    一旦可以简单地进行旋转,就可以通过执行以下操作找到矩形上的位置 line-line intersection . 通过相交两条线找到环绕图标的中心:

    1. 从你的旋转中心照出你想要的角度的光线
    2. 四条边中的一条,以所需角度(四个象限)为界。
        6
  •  0
  •   user229044    12 年前

    在一张有矩形和旋转中心的纸上画一个草图。首先将矩形转换为坐标系原点的中心(记住转换参数,稍后需要反转转换)。旋转矩形,使其边与坐标轴平行(同样的原因)。

    现在您有了一个三角形,在原点处具有已知的角度,另一侧具有已知的长度(矩形一侧长度的一半),现在可以:

    --解三角形

    --撤消旋转

    --撤消翻译