私はリング(幅25px)を持っていUIView
ます。ユーザーがリング上の任意の場所を選択すると、円の中心を考慮して、円上の固定点で選択されたポイント間の角度を計算したいと思います。私はいくつかの例を見つけましたが、それらは中心を考慮していません。
これを行う最適な方法は何ですか?
私はリング(幅25px)を持っていUIView
ます。ユーザーがリング上の任意の場所を選択すると、円の中心を考慮して、円上の固定点で選択されたポイント間の角度を計算したいと思います。私はいくつかの例を見つけましたが、それらは中心を考慮していません。
これを行う最適な方法は何ですか?
コードは自分で処理する必要がありますが (私は Java 開発者です)、円の 2 点間の角度 (円の中心に対して測定) を取得する最も簡単な方法は、状況のジオメトリを思い出すことです。円周上の任意の 2 点と円の中心によって形成される三角形は、必然的に二等辺三角形になります。
二等辺三角形には、(少なくとも) 同じ長さの 2 つの辺があります。これは、2 つの点に対する放射状のセグメントです。角度を 2 等分すると、2 点を結ぶ線に垂直で 2 等分する放射状のセグメントが生成されます。これは、半径を斜辺とし、2 点間の距離の半分を「反対側」とする直角三角形のペアを形成します。
係数 2 を分母に移動し、半径の 2 倍を認識して、(円周上の) 2 点間の距離を単純に計算し、それを直径で割ります。得られる値は半角のサインです (全体の角度が必要です)。逆正弦を取ると、角度の半分になります。
θ/2 = sin -1 (d/D)
2d
点間の距離として、およびD
円の直径として。直径が与えられ、2 点間の距離は簡単に計算できるため、この点に到達するのは簡単です。その後、計算された値を 2 倍にするだけで、2 点間の全体の角度を取得できます。
これはあなたを助けるかもしれません.私は自分のプロジェクトの1つで同じことを使用しました.
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
beginPoint = [[[event allTouches] anyObject] locationInView:self];
currentAngle = 0.0f;
centerPoint = self.center;
}
-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
endPoint = [[[event allTouches] anyObject] locationInView:self];
float fromAngle = atan2(beginPoint.y - self.center.y, beginPoint.x - self.center.x);
float toAngle = atan2(endPoint.y - self.center.y, endPoint.x - self.center.x);
float newAngle = [self wrapd:currentAngle + (toAngle - fromAngle) min:0 max:2 * 3.14];
currentAngle = newAngle;
CGAffineTransform cgaRotate = CGAffineTransformMakeRotation(newAngle);
[self setTransform:cgaRotate];
}
-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
endPoint = [[[event allTouches] anyObject] locationInView:self];
float fromAngle = atan2(beginPoint.y - self.center.y, beginPoint.x - self.center.x);
float toAngle = atan2(endPoint.y - self.center.y, endPoint.x - self.center.x);
float newAngle = [self wrapd:currentAngle + (toAngle - fromAngle) min:0 max:2 * 3.14];
currentAngle = newAngle;
}
- (double) wrapd:(double)_val min:(double)_min max:(double)_max {
if(_val < _min) return _max - (_min - _val);
if(_val > _max) return _val - _max; /*_min - (_max - _val)*/;
return _val;
}