1

特定の点を中心とした線の回転

男、私はこれに苦労してきました...

上の画像を参照すると、特定の点に固定された線があります。線の反対側には、固定されておらず、画面上の任意の位置にドラッグできる別のポイントがあります。その点をたどり、長さを変更せずにその位置に対して回転できるようにするには、線が必要です。

線の長さを固定しなくても、これらすべてを非常に簡単に実行できることはわかっています。

UIBezierPath次のdrawRect:ように簡単に描画できます。

UIBezierPath *bezPath = [UIBezierPath bezierPath];
[bezPath moveToPoint:fixedPointStart];
[bezPath addLineToPoint:draggedPointEnd];
[bezPath stroke];

次に、UIView を呼び出し[self setNeedsDisplay]-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event、ドラッグされたポイントの新しい座標を渡し、再描画します。

しかし、私が述べたように、私はラインが具体的に固定長である必要があります.

もう1つ(違いがあるかどうかはわかりませんが)、線は実際にはより大きなUIBezierPath不規則な形状の一部です. 写真に示されている「特定の固定点」は、この線がより大きな不規則な に接続されている点ですUIBezierPath。次のコードに示すように、線は同じものの一部として描画されUIBezierPathます。

だからここに私が今持っているものがあります:

//    I AM CREATING THE FIXED POINT HERE THAT IS BEING RETURNED BY A CUSTOM METHOD 
WHICH FINDS THE POINT OF ATTACHEMENT TO THE LARGER IRREGULAR SHAPED UIBEZIERPATH.
//    THE DRAGGABLE POINTS ARE ACTUALLY UIVIEW'S AND I'M USING THEIR ORIGINS.

CGPoint fixedPoint = [aPath findCurveBezierPathPointInBetweenTheStartPoint:point1.frame.origin
                                                             theEndPoint:topCurvePoint.frame.origin 
                                       withFirstControlPoint:topCurveFirstControlPoint.frame.origin
                   andSecondControlPoint:topCurveSecondControlPoint.frame.origin atPercentage:0.3];




//    This is the fixed point
CGPoint startPoint = fixedPoint;

//    This is the point that is going to be able to be dragged
CGPoint endPoint = topCurveFirstControlPoint.frame.origin;


//    I am finding the angle in between these two points to pass in an CGAffineTransform for the rotation. 
float angle = [self getRotatingAngle:startPoint secondPoint:endPoint];
NSLog(@"Angle in Radians: %f",angle);



//    I am creating the transform by passing in the angle and doing the necessary translations for the rotation to occur on the fixed point. 
CGAffineTransform transform = CGAffineTransformMakeTranslation(fixedPoint.x, fixedPoint.y);
transform = CGAffineTransformRotate(transform, angle);
transform = CGAffineTransformTranslate(transform,-fixedPoint.x,-fixedPoint.y);


//  I am setting up to draw the line of fixed length and applying the transform and 
[aPath moveToPoint:startPoint];
[aPath addLineToPoint:CGPointMake(fixedPoint.x, fixedPoint.y - 60)];
[aPath applyTransform:transform];



// I then continue to draw the rest of the BezierPath and stroke it at the end.    
[aPath moveToPoint:point1.frame.origin];

[aPath addCurveToPoint:topCurvePoint.frame.origin controlPoint1:topCurveFirstControlPoint.frame.origin controlPoint2:topCurveSecondControlPoint.frame.origin];

だから私の質問は次のとおりです:ドラッグ可能なポイントが新しい位置を見つけるときに呼び出されるたびに、固定線を変換する正しい角度を見つけるにはどうすればよいですか?drawRect:

固定点とドラッグ点の間の角度を見つけるために使用する方法は、テストしたとおり、正しい角度を示します。ただし、ドラッグ可能な点に対して線を正しく回転させる方法で、これらの 2 つの点の間に角度を適用する方法がわかりません。

編集:正確に達成しようとしていることのより良い説明のためにリンクを追加しました。

4

1 に答える 1

0

なぜあなたはそれを変換していますか?その単純なジオメトリ。中心と現在のポイントの間の角度を見つけることができます。長さが等しいので、パスは基本的に円です。したがって、中心点と角度を使用して円上の点を見つけます. ドラッグした後のタッチポイントが currentPoint であるとします。角度を見つけるには:

CGFloat angle = atan2f(currentPoint.y - centre.y, currentPoint.x - centre.x);

上記の角度に対応する円上の点を見つけます。

finalPoint.x = centre.x + length * cosf(angle);
finalPoint.y = centre.y + length * sinf(angle);

length は固定長です。これで、quartz-2d を使用して center と finalPoint の間に線を引くことができます。

注: 角度がマイナスになる場合があります。したがって、実装で、それを同等の +ve 角度に変換したい場合があります。

if (angle < 0)
     angle += 2 * M_PI;
于 2014-04-23T07:07:50.007 に答える