2つのオブジェクトがあり、一方を移動するときに、もう一方から角度を取得したいと思います。
例えば:
Object1X = 211.000000, Object1Y = 429.000000
Object2X = 246.500000, Object2Y = 441.500000
私は太陽の下で次のすべてのバリエーションを試しました:
double radians = ccpAngle(Object1,Object2);
double degrees = ((radians * 180) / Pi);
しかし、45度などが必要な場合は2.949023が返されます。
この他の答えは役に立ちますか?
私はそれをこのように書いた:
- (CGFloat) pointPairToBearingDegrees:(CGPoint)startingPoint secondPoint:(CGPoint) endingPoint
{
CGPoint originPoint = CGPointMake(endingPoint.x - startingPoint.x, endingPoint.y - startingPoint.y); // get Origin point to Origin by subtracting end from start
float bearingRadians = atan2f(originPoint.y, originPoint.x); // get bearing in radians
float bearingDegrees = bearingRadians * (180.0 / M_PI); // convert to degrees
bearingDegrees = (bearingDegrees > 0.0 ? bearingDegrees : (360.0 + bearingDegrees)); // correct discontinuity
return bearingDegrees;
}
コードの実行:
CGPoint p1 = CGPointMake(10, 10);
CGPoint p2 = CGPointMake(20,20);
CGFloat f = [self pointPairToBearingDegrees:p1 secondPoint:p2];
そしてこれは45を返します。
お役に立てれば。
@tomasのソリューションを合理化するように変更しました。この数学は頻繁に呼び出される可能性があります(私にとってはそうだった)。
私の化身では、2つのポイントの違いを自分で実行する必要があります(または、運が良ければ、(0,0)はすでにポイントの1つです)。計算される値は、(0,0)からのポイントの方向です。はい、それは十分に単純であり、本当に必要な場合はインライン化できます。私の好みは、より読みやすいコードです。
また、それを関数呼び出しに変換しました。
_CGFloat CGPointToDegree(CGPoint point) {
// Provides a directional bearing from (0,0) to the given point.
// standard cartesian plain coords: X goes up, Y goes right
// result returns degrees, -180 to 180 ish: 0 degrees = up, -90 = left, 90 = right
CGFloat bearingRadians = atan2f(point.y, point.x);
CGFloat bearingDegrees = bearingRadians * (180. / M_PI);
return bearingDegrees;
}
_
負の値が必要ない場合は、自分で変換する必要があります。負の値は私にとっては問題ありませんでした-不必要な計算をする必要はありません。
私はこれをcocos2d環境で使用していました、これは私がそれを呼ぶ方法です:(数学的には、平面を変換して_p0
_を原点にします。したがって、_p0
_から_p1
_を減算します(_p0
_ --_p0
_ = {0,0})。平面が平行移動されても角度は変更されません。)
_CGPoint p0 = self.position;
CGPoint p1 = other.position;
CGPoint pnormal = ccpSub(p1, p0);
CGFloat angle = CGPointToDegree(pnormal);
_
ccpSub
はcocos2dによって提供されます。これはタプルの減算です。使用可能なものがない場合は、自分で行うことができます。
余談ですが、関数をCoreGraphics
の一部として識別する_CG___
_命名スキームを使用して、上記のようにメソッドに名前を付けるのは一般的に礼儀正しいスタイルではありません。したがって、名前をMyConvertCGPointToBearing()
に変更する場合はまたはFredLovesWilma()
それならあなたはそれをするべきです。
これが私がSwiftに興味のある人のためにそれをしている方法です、それはキャレイヤー回転システムに一致するのを助けるためにいくつかの修正を加えた上記の@bshirleyの答えに基づいています:
extension CGPoint {
func angle(to comparisonPoint: CGPoint) -> CGFloat {
let originX = comparisonPoint.x - self.x
let originY = comparisonPoint.y - self.y
let bearingRadians = atan2f(Float(originY), Float(originX))
var bearingDegrees = CGFloat(bearingRadians).degrees
while bearingDegrees < 0 {
bearingDegrees += 360
}
return bearingDegrees
}
}
extension CGFloat {
var degrees: CGFloat {
return self * CGFloat(180.0 / M_PI)
}
}
これにより、次のような座標系が提供されます。
270
180 0
90
使用法:
point.angle(to: point2)
CGPoint.zero.angle(to: CGPoint(x: 0, y: 1)) // 90
2点間に角度はありません。原点(0,0)からオブジェクトまでのベクトル間の角度を知りたい場合は、スカラー(ドット)積を使用します。
theta = arccos ( (veca dot vecb) / ( |veca| * |vecb| )
使用している言語のmathstd libは、アーカスコサイン、スカラー積、および長さの関数を確実に提供します。
角度の頂点は点(0,0)です。
Object1X = x1 .... object2Y = y2について考えてみます。
Angle(object1-object2) =
90 * ( (1 + sign(x1)) * (1 - sign(y1^2))
- (1 + sign(x2)) * (1 - sign(y2^2)) )
+ 45 * ( (2 + sign(x1)) * sign(y1)
- (2 + sign(x2)) * sign(y2) )
+ 180/pi() * sign(x1*y1) * atan( (abs(x1) - abs(y1)) / (abs(x1) + abs(y1)) )
- 180/pi() * sign(x2*y2) * atan( (abs(x2) - abs(y2)) / (abs(x2) + abs(y2)) )