我正在尝试简单地让物体围绕一个中心点运行,例如
绿色和蓝色对象表示应根据我传递给方法的角度在旋转时与中心点保持距离的对象。
我试图在 objective-c 中创建一个函数,但如果没有静态数字,它就无法正常工作。例如(它围绕中心旋转,但不是从真正的起点或到物体的距离。)
-(void) rotateGear: (UIImageView*) view heading:(int)heading
{
// int distanceX = 160 - view.frame.origin.x;
// int distanceY = 240 - view.frame.origin.y;
float x = 160 - view.image.size.width / 2 + (50 * cos(heading * (M_PI / 180)));
float y = 240 - view.image.size.height / 2 + (50 * sin(heading * (M_PI / 180)));
view.frame = CGRectMake(x, y, view.image.size.width, view.image.size.height);
}
我的魔数(Magic Number) 160 和 240 是我在其中绘制图像的 Canvas 中心。 50 是一个静态数字(也是问题所在),它允许函数部分正确地工作——无需保持对象的起始位置或正确的距离。不幸的是,我不知道该放什么。
heading
是传递度数的参数,从 0 到 359。它由定时器计算,并在该类之外递增。
本质上,我希望能够将任何图像拖放到我的 Canvas 上,并且基于图像的起点,它会围绕我的圆心旋转。这意味着,如果我要在点 (10,10)
放置图像,到圆心的距离将保持不变,使用 (10,10)
作为一个起点。物体将围绕中心旋转 360 度,并到达其原始起点。
预期的结果是将例如 (10,10)
传递到方法中,基于零度,然后返回,(15,25
)(不是真实的)在 5 度。
我知道这很简单(而且这个问题描述完全是矫枉过正),但我会睁大眼睛试图弄清楚我在哪里解决问题。我不关心你使用什么语言示例,如果有的话。我将能够破译你的意思。
失败更新
我已经走得更远了,但我仍然无法得到正确的计算。我的新代码如下所示:
heading
设置为 1 度。
-(void) rotateGear: (UIImageView*) view heading:(int)heading
{
float y1 = view.frame.origin.y + (view.frame.size.height/2); // 152
float x1 = view.frame.origin.x + (view.frame.size.width/2); // 140.5
float radius = sqrtf(powf(160 - x1 ,2.0f) + powf(240 - y1, 2.0f)); // 90.13
// I know that I need to calculate 90.13 pixels from my center, at 1 degree.
float x = 160 + radius * (cos(heading * (M_PI / 180.0f))); // 250.12
float y = 240 + radius * (sin(heading * (M_PI / 180.0f))); // 241.57
// The numbers are very skewed.
view.frame = CGRectMake(x, y, view.image.size.width, view.image.size.height);
}
我得到的结果与应有的位置相去甚远。问题在于 x 和 y 的分配。我哪里错了?
最佳答案
你可以很容易地找到点到中心的距离:
radius = sqrt((160 - x)^2 + (240 - y)^2)
其中 (x, y) 是对象中心的初始位置。然后只需用半径替换 50。
http://en.wikipedia.org/wiki/Pythagorean_theorem
然后您可以使用三角函数计算出初始角度(tan = opposite/adjacent,因此使用中心质量和轨道物体的中心绘制一个直角三角形以可视化它):
angle = arctan((y - 240) / (x - 160))
如果 x > 160,或者:
angle = arctan((y - 240) / (x - 160)) + 180
如果 x < 160
http://en.wikipedia.org/wiki/Inverse_trigonometric_functions
编辑:请记住,我实际上并不知道任何 Objective-C,但这基本上是我认为你应该做的(你应该能够很容易地将它翻译成正确的 Obj-C,这只是为了演示) :
// Your object gets created here somewhere
float x1 = view.frame.origin.x + (view.frame.size.width/2); // 140.5
float y1 = view.frame.origin.y + (view.frame.size.height/2); // 152
float radius = sqrtf(powf(160 - x1 ,2.0f) + powf(240 - y1, 2.0f)); // 90.13
// Calculate the initial angle here, as per the first part of my answer
float initialAngle = atan((y1 - 240) / (x1 - 160)) * 180.0f / M_PI;
if(x1 < 160)
initialAngle += 180;
// Calculate the adjustment we need to add to heading
int adjustment = (int)(initialAngle - heading);
所以我们只执行一次上面的代码(当对象被创建时)。我们需要记住 radius
和 adjustment
以备后用。然后我们更改 rotateGear
以将角度和半径作为输入而不是 heading
(无论如何这更灵活):
-(void) rotateGear: (UIImageView*) view radius:(float)radius angle:(int)angle
{
float x = 160 + radius * (cos(angle * (M_PI / 180.0f)));
float y = 240 + radius * (sin(angle * (M_PI / 180.0f)));
// The numbers are very skewed.
view.frame = CGRectMake(x, y, view.image.size.width, view.image.size.height);
}
每次我们想要更新位置时,我们都会像这样调用:
[objectName rotateGear radius:radius angle:(adjustment + heading)];
顺便说一句,一旦你成功完成这项工作,我强烈建议你转换所有的角度,这样你就可以一直使用弧度,这样会更整洁/更容易理解!
关于ios - 围绕中心质量创建圆形路径的算法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6668358/