帮助正确计算 atan2
Posted
技术标签:
【中文标题】帮助正确计算 atan2【英文标题】:help to calculate atan2 properly 【发布时间】:2011-05-04 01:32:45 【问题描述】:我需要计算线之间的角度。我需要计算 atan。所以我正在使用这样的代码
static inline CGFloat angleBetweenLinesInRadians2(CGPoint line1Start, CGPoint line1End)
CGFloat dx = 0, dy = 0;
dx = line1End.x - line1Start.x;
dy = line1End.y - line1Start.y;
NSLog(@"\ndx = %f\ndy = %f", dx, dy);
CGFloat rads = fabs(atan2(dy, dx));
return rads;
但我不能超过 180 度((在 179 度之后去 178..160..150 等等。
我需要旋转 360 度。我该怎么做?怎么了?
这可能会有所帮助:
//Tells the receiver when one or more fingers associated with an event move within a view or window.
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
NSArray *Touches = [touches allObjects];
UITouch *first = [Touches objectAtIndex:0];
CGPoint b = [first previousLocationInView:[self imgView]]; //prewious position
CGPoint c = [first locationInView:[self imgView]]; //current position
CGFloat rad1 = angleBetweenLinesInRadians2(center, b); //first angel
CGFloat rad2 = angleBetweenLinesInRadians2(center, c); //second angel
CGFloat radAngle = fabs(rad2 - rad1); //angel between two lines
if (tempCount <= gradus)
[imgView setTransform: CGAffineTransformRotate([imgView transform], radAngle)];
tempCount += radAngle;
【问题讨论】:
【参考方案1】:atan2
以 [-180,180] (或 -pi, pi 弧度)返回结果。要获得 0,360 的结果,请使用:
float radians = atan2(dy, dx);
if (radians < 0)
radians += M_PI*2.0f;
需要注意的是,通常用 [-pi,pi] 表示旋转,因此您可以直接使用 atan2
的结果而不必担心符号。
【讨论】:
什么不起作用?我假设您也用适当的常量替换了TWO_PI
。
我没有理由看到它不能让你的角度正确。具体是哪些值生成不正确?【参考方案2】:
删除fabs
调用并简单地调用它:
CGFloat rads = atan2(dy, dx);
【讨论】:
@yozhik:也许你应该解释一下什么是行不通的。预期结果是什么?您看到了什么? 我有一个 decart 坐标系。我正在拍摄图片。成像为零。当我在上方 180 度拍摄并移动照片时 - 一切都好。当我试图将安德移动 180 度时,例如 190 - 它显示了 170 度。我需要那个190度的地方。你看... @yozhik:尝试删除fabs(rad2 - rad1)
中的另一个fabs
。【参考方案3】:
在 Swift 中使用这个函数。这可以确保从“fromPoint”到“toPoint”的角度介于 0 到
func getAngle(fromPoint: CGPoint, toPoint: CGPoint) -> CGFloat
let dx: CGFloat = fromPoint.x - toPoint.x
let dy: CGFloat = fromPoint.y - toPoint.y
let twoPi: CGFloat = 2 * CGFloat(M_PI)
let radians: CGFloat = (atan2(dy, -dx) + twoPi) % twoPi
return radians * 360 / twoPi
对于原点在左下角的情况
let twoPi = 2 * Float(M_PI)
let radians = (atan2(-dy, -dx) + twoPi) % twoPi
let angle = radians * 360 / twoPi
【讨论】:
【参考方案4】:您的问题是 atan2 的结果在 -180 到 +180 度之间。 如果您希望它在 0 和 360 之间,则移动结果以确保为正值,然后进行取模。例如:
let angle = fmod(atan2(dx,dy) + .pi * 2, .pi * 2)
【讨论】:
以上是关于帮助正确计算 atan2的主要内容,如果未能解决你的问题,请参考以下文章
atan2 函数在 javascript 和 Excellsheet 中的行为不同