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

Math 给定角度和尺寸,沿矩形的周长找到一个坐标,math,coordinates,angle,Math,Coordinates,Angle,我正在编写一个脚本,其中图标围绕给定的轴(或原点)旋转。我已经能够使图标围绕椭圆旋转,但我也希望它们围绕一个具有一定宽度、高度和原点的矩形的周长移动 我这样做是因为我当前的代码将所有坐标存储在一个数组中,每个角度整数作为键,重用此代码将更容易处理 如果有人能给我一个100x150矩形的例子,那就太好了 编辑:为了澄清这一点,我说的旋转是指围绕形状的周长(或轨道)移动。如果你认为旋转就像地球围绕太阳旋转一样(不是自转……那么你的问题是如何沿着矩形的边缘滑动?) 如果是这样,您可以尝试一下: # p

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

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

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


编辑:为了澄清这一点,我说的旋转是指围绕形状的周长(或轨道)移动。

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

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

# 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)

其他行很简单,因为它们只是水平或垂直的。例如,它是x=50,你可以把它放到上面的一行中,得到y。在水平线和垂直线的交点处这样做(例如,角度为60度,它向“东北”方向射出……现在你有两个点。那么最靠近原点的点就是首先击中矩形的点).

您知道矩形的大小,并且需要将整个角度间隔分割为四个不同的角度间隔,以便您知道矩形中心的光线是否与矩形的右、上、左或下相交

如果角度为:-atan(d/w) dy=d/2*tan(阿尔法)

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

好了,开始吧。您有一个宽度为w、深度为d的矩形。在中间,你有中心点,Cp。我假设你想计算P,对于角度的不同值alf.

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

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


干杯

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

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

--解三角形

--撤消旋转


--撤消平移

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

(假设以(0,0)为中心的轴对齐矩形,X轴长度为XAxis,Y轴长度为YAxis):

if(X>XAxis/2)
X=XAxis/2;
if(X<0-XAxis/2)
X=0-XAxis/2;
如果(Y>YAxis/2)
Y=YAxis/2;
if(Y<0-YAxis/2)
Y=0-YAxis/2;
这种方法的问题是,角度不会完全精确,沿矩形周长的速度也不会恒定。对一个椭圆进行建模,使其在矩形的角处紧贴矩形,可以将效果降至最低,但如果您要寻找一个平滑的、恒定速度的“环绕”,这种方法将是不够的。许多语言(如Java)本机支持此功能(查找仿射翻译);否则,自己编写一个例程来做旋转,一次,调试好,然后永远使用它。我必须用不同的语言写五本

一旦可以简单地进行旋转,就可以通过执行以下操作找到矩形上的位置。通过与两条线相交找到轨道图标的中心:

  • 从你的旋转中心到你想要的角度的光线
  • 四条边之一,以你想要的角度(四个象限)为边界

  • 这是为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);
    
    struct GPoint{
    int x;
    int-y;
    }
    //矩形边上的返回点。矩形以(0,0)为中心,宽度为w,高度为h
    GPoint getPointOnRect(整数角度、整数w、整数h){
    var sine=sin(角度),cosine=cos(角度);//计算一次并存储,以便更快更干净
    var dy=sin>0?h/2:h/-2;//到顶部或底部边缘的距离(从中心)
    var dx=cos>0?w/2:w/-2;//到左边缘或右边缘的距离(从中心)
    if(abs(dx*正弦)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;
    
    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);