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传递被拖动点的新坐标并重新绘制它。

但正如我所提到的,我需要这条线特别是固定长度。

另一件事(不确定它是否会有所作为),这条线实际上是一个较大UIBezierPath的不规则形状的一部分。图中的“特定不动点”就是这条线对较大不规则线的附着点UIBezierPathUIBezierPath这条线是作为您将在以下代码中看到的相同部分的一部分绘制的。

所以这就是我现在所拥有的:

//    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:

我用来找到固定点和拖动点之间角度的方法给了我正确的角度,因为我已经测试过了。但是,我无法弄清楚如何以一种相对于可拖动点正确旋转线的方式应用这两个点之间的角度。

编辑:添加链接以更好地解释我正在尝试完成的工作。

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);

其中长度是您的固定长度。现在您可以使用quartz-2d 在center 和finalPoint 之间画一条线。

注意:有时角度会变成负数。因此,在您的实现中,您可能希望将其转换为等效的 +ve 角度。

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