我正在编写一个脚本,其中图标围绕给定的枢轴(或原点)旋转。我已经能够使图标围绕椭圆旋转,但我也想让它们围绕具有一定宽度、高度和原点的矩形的周边移动。
我这样做是因为我当前的代码将所有坐标存储在一个数组中,每个角度整数作为键,并且重用此代码会更容易使用。
如果有人能给我一个 100x150 矩形的例子,那就太好了。
编辑:澄清一下,通过旋转我的意思是围绕形状的周边(或轨道)移动。
我正在编写一个脚本,其中图标围绕给定的枢轴(或原点)旋转。我已经能够使图标围绕椭圆旋转,但我也想让它们围绕具有一定宽度、高度和原点的矩形的周边移动。
我这样做是因为我当前的代码将所有坐标存储在一个数组中,每个角度整数作为键,并且重用此代码会更容易使用。
如果有人能给我一个 100x150 矩形的例子,那就太好了。
编辑:澄清一下,通过旋转我的意思是围绕形状的周边(或轨道)移动。
你知道矩形的大小,你需要将整个角度间隔分成四个不同的,这样你就知道来自矩形中心的光线是否与矩形的右、上、左或下相交。
如果角度是:-atan(d/w) < alfa < atan(d/w),则光线与矩形的右侧相交。那么既然你知道从矩形中心到右侧的x位移是d/2,那么位移dy除以d/2就是tan(alfa),所以
dy = d/2 * tan(alfa)
您可以用其他三个角度间隔类似地处理这个问题。
好的,这就去。你有一个宽度为 w 和深度为 d 的矩形。在中间你有中心点,cp。我假设您要计算 P,对于角度 alfa 的不同值。
我将矩形划分为四个不同的区域,或角度间隔(1 到 4)。我上面提到的间隔是右边的第一个。我希望这对你有意义。
首先,您需要计算角度间隔,这些完全由 w 和 d 确定。根据 alfa 的值,相应地计算 P,即从 CP 到 P 的“射线”是否与矩形的上、下、右侧或左侧相交。
干杯
这是为 Pebble 智能手表制作并经过验证的,但修改为伪代码:
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);
如果您认为您的意思是像地球围绕太阳旋转一样旋转(而不是自转……那么您的问题是关于如何沿着矩形的边缘滑动?)
如果是这样,您可以尝试一下:
# 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 度,它拍摄“NorthEast”......现在你有两个点。那么最接近原点的点就是命中先长方形)。
在一张纸上画一个草图,带有一个矩形和一个旋转中心。首先将矩形平移到坐标系原点的中心(记住平移参数,稍后您需要反转平移)。旋转矩形,使其边平行于坐标轴(同样的原因)。
现在您在原点有一个已知角度的三角形,另一边的长度已知(矩形一侧长度的一半),您现在可以:
-- 解决三角形
-- 撤销旋转
-- 撤消翻译
使用角度作为参数的一种简单方法是使用矩形的边界简单地裁剪 X 和 Y 值。换句话说,计算位置好像图标将围绕圆形或椭圆形路径旋转,然后应用:
(假设轴对齐矩形以 (0,0) 为中心,X 轴长度为 XAxis,Y 轴长度为 YAxis):
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;
这种方法的问题是角度不会完全准确,并且沿着矩形周边的速度不会恒定。对在其角处与矩形密切相关的椭圆进行建模可以最大限度地减少影响,但如果您正在寻找一个平滑、恒速的“轨道”,这种方法将不够用。
使用二维变换矩阵。许多语言(例如Java)本机支持这一点(查找AffineTransformation);否则,编写一个例程自己进行轮换,一次,调试好,并永远使用它。我必须有五个用不同的语言写成。
一旦您可以简单地进行旋转,请通过line-line intersection找到矩形上的位置。通过两条线相交找到轨道图标的中心: