【问题标题】:iOS: Rotating a line with respect to a point that could be adjusted by touchiOS:相对于可以通过触摸调整的点旋转一条线
【发布时间】:2013-04-17 23:30:27
【问题描述】:

伙计,我一直在为此苦苦挣扎吗……

参考上图,我有一条固定到特定点的线。在该行的另一端,我有另一个不固定的点,可以拖动到屏幕上的任何位置。我需要这条线能够跟随该点并在不改变长度的情况下相对于它的位置进行旋转。

我知道所有这些都可以很容易地完成,而无需固定长度。

您可以像这样在drawRect: 中简单地画一个UIBezierPath

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

然后在您的 UIView 中调用 -(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event 中的 [self setNeedsDisplay] 以传递被拖动点的新坐标并重新绘制它。

但正如我所提到的,我需要将线条专门设置为固定长度。

另一件事(不确定它是否会有所不同),这条线实际上是不规则形状的较大@​​987654328@ 的一部分。图中的“特定固定点”就是这条线对较大的不规则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: 时,如何找到正确的角度来转换固定线?

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

编辑:添加了Link,以便更好地解释我想要完成的工作。

【问题讨论】:

  • 毕达哥拉斯是你的朋友。
  • 您能详细说明一下吗?我知道两点之间的角度,我很难将其应用于旋转。

标签: ios core-graphics quartz-2d cgaffinetransform uibezierpath


【解决方案1】:

为什么要改造它?其简单的几何形状。您可以找到中心和当前点之间的角度。由于长度相等,所以你的路径基本上是一个圆圈。因此,使用中心点和角度找到圆上的点。 假设拖动后的触摸点是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;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-06-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多