座標 a と座標 b の間の角度を求める方法と、角度の方向を求める方法メモ。
物体の回転なんかをタッチで操作するときに使えるかも。
まず角度のみを求める場合には次のようにする。
1 2 3 4 5 |
Vector2 v2center,v2a,v2b; Vector3 v3center,v3a,v3b; Vector2.Angle(v2a - v2center, v2b - v2center); //deg Vector3.Angle(v3a - v3center, v3b - v3center); //deg |
度で返ってくるのでラジアンにしたい場合は Mathf.Deg2Rad をかける。
鋭角であれば正規化して内積をとって arccos すればそのままラジアンが計算できる。
1 2 3 4 5 6 |
Mathf.Acos( Vector3.Dot( (v3a - v3center).normalized, (v3b - v3center).normalized ) ); |
外積の式を使ってもいい。
1 2 3 |
Mathf.Asin( Vector3.Cross(v3a - v3center, v3b - v3center).magnitude / ( (v3b - v3center).magnitude * (v3b - v3center).magnitude ) ) |
ラジアンから度にするには Mathf.Rad2Deg をかける。
角度と方向
Vector3 のだと、どこから見ての回転方向なのかを定義しないといけない。
次の式から回転軸を求めることが出来る。
Vector3.Cross(v3a - v3center, v3b - v3center);
この軸から見て正の方向に回転していることになる。
Vector2 は平面に垂直な軸を用いて方向も計算できる。
Vector2 では外積(Cross積)はないので自分で定義して計算する。
1 2 3 4 5 6 7 8 9 10 11 |
float V2NmlzCross(Vector2 v1,Vector2 v2){ return v1.normalized.x*v2.normalized.y - v1.normalized.y*v2.normalized.x; } float angle = Vector2.Angle(v2a - v2center, v2b - v2center); //from -180 to 180 angle*= Mathf.Sign( V2NmlzCross( (v2a - v2center), (v2b - v2center) ) ); //from 0 to 360 angle = Mathf.Sign( V2NmlzCross( (v2a - v2center), (v2b - v2center) ) )==-1 ? 360-angle : angle); |