获取旋转的矩形 UIView 角的坐标 iOS

Posted

技术标签:

【中文标题】获取旋转的矩形 UIView 角的坐标 iOS【英文标题】:Get rotated rectangle UIView corners' coordinates iOS 【发布时间】:2013-09-30 15:02:06 【问题描述】:

我正在尝试找到一个旋转的矩形 UIView 的四个角的坐标。

我认为我可以做的一种方法是使用识别器旋转,找到旋转的角度然后计算原点。但这需要一些几何计算。

- (IBAction)handlePan:(UIRotationGestureRecognizer*)recognizer 
    NSLog(@"Rotation in degrees since last change: %f", [recognizer rotation] * (180 / M_PI));
    recognizer.view.transform = CGAffineTransformRotate(recognizer.view.transform, recognizer.rotation);
    NSLog(@"%@",recognizer);

    recognizer.rotation = 0;
    NSLog(@"bound is %f and %f, frame is %f and %f, %f and %f.",recognizer.view.bounds.size.width,recognizer.view.bounds.size.height, recognizer.view.frame.size.width,recognizer.view.frame.size.height, recognizer.view.frame.origin.x, recognizer.view.frame.origin.y);

我只是想知道是否还有其他更简单的方法来获取坐标? 谢谢!

编辑:

看起来我们在这里有一个很好的答案(见下面的答案)。我设法通过一种愚蠢的方式计算了角落——使用旋转角度和几何形状。它有效,但并不容易和轻巧。我在这里分享我的代码,以防有人想要使用它(尽管我对此表示怀疑。)

    float r = 100;
    NSLog(@"radius is %f.",r);
    float AAngle = M_PI/3+self.rotatedAngle;
    float AY = recognizer.view.center.y - sin(AAngle)*r;
    float AX = recognizer.view.center.x - cos(AAngle)*r;
    self.pointPADA = CGPointMake(AX, AY);
    NSLog(@"View Center is (%f,%f)",recognizer.view.center.x,recognizer.view.center.y);
    NSLog(@"Point A has coordinate (%f,%f)",self.pointPADA.x,self.pointPADA.y);

    float BAngle = M_PI/3-self.rotatedAngle;
    float BY = recognizer.view.center.y - sin(BAngle)*r;
    float BX = recognizer.view.center.x + cos(BAngle)*r;
    self.pointPADB = CGPointMake(BX, BY);
    NSLog(@"Point B has coordinate (%f,%f)",BX,BY);

    float CY = recognizer.view.center.y + sin(AAngle)*r;
    float CX = recognizer.view.center.x + cos(AAngle)*r;
    self.pointPADC = CGPointMake(CX, CY);
    NSLog(@"Point C has coordinate (%f,%f)",CX,CY);

    float DY = recognizer.view.center.y + sin(BAngle)*r;
    float DX = recognizer.view.center.x - cos(BAngle)*r;
    self.pointPADD = CGPointMake(DX, DY);
    NSLog(@"Point D has coordinate (%f,%f)",DX,DY);

【问题讨论】:

你是如何得到 r = 100 的值的? 【参考方案1】:

这是我的解决方案,但我想知道是否有更简洁的方法:

CGPoint originalCenter = CGPointApplyAffineTransform(theView.center,
    CGAffineTransformInvert(theView.transform));

CGPoint topLeft = originalCenter;
topLeft.x -= theView.bounds.size.width / 2;
topLeft.y -= theView.bounds.size.height / 2;
topLeft = CGPointApplyAffineTransform(topLeft, theView.transform);

CGPoint topRight = originalCenter;
topRight.x += theView.bounds.size.width / 2;
topRight.y -= theView.bounds.size.height / 2;
topRight = CGPointApplyAffineTransform(topRight, theView.transform);

CGPoint bottomLeft = originalCenter;
bottomLeft.x -= theView.bounds.size.width / 2;
bottomLeft.y += theView.bounds.size.height / 2;
bottomLeft = CGPointApplyAffineTransform(bottomLeft, theView.transform);

CGPoint bottomRight = originalCenter;
bottomRight.x += theView.bounds.size.width / 2;
bottomRight.y += theView.bounds.size.height / 2;
bottomRight = CGPointApplyAffineTransform(bottomRight, theView.transform);

【讨论】:

我添加了 topLeft.x += self.mainImageView.transform.tx;和 topLeft.y += self.mainImageView.transform.ty;在 topLeft = CGPointApplyAffineTransform(topLeft, theView.transform) 之后;用于平移以及缩放和旋转的视图。【参考方案2】:

在 Swift 中检查答案

struct ViewCorners 
    private(set) var topLeft:     CGPoint!
    private(set) var topRight:    CGPoint!
    private(set) var bottomLeft:  CGPoint!
    private(set) var bottomRight: CGPoint!

    private let originalCenter: CGPoint
    private let transformedView: UIView

    private func pointWith(multipliedWidth: CGFloat, multipliedHeight: CGFloat) -> CGPoint 
        var x = originalCenter.x
        x += transformedView.bounds.width  / 2 * multipliedWidth

        var y = originalCenter.y
        y += transformedView.bounds.height / 2 * multipliedHeight

        var result = CGPoint(x: x, y: y).applying(transformedView.transform)
        result.x += transformedView.transform.tx
        result.y += transformedView.transform.ty

        return result
    

    init(view: UIView) 
        transformedView = view
        originalCenter = view.center.applying(view.transform.inverted())

        topLeft =     pointWith(multipliedWidth:-1, multipliedHeight:-1)
        topRight =    pointWith(multipliedWidth: 1, multipliedHeight:-1)
        bottomLeft =  pointWith(multipliedWidth:-1, multipliedHeight: 1)
        bottomRight = pointWith(multipliedWidth: 1, multipliedHeight: 1)

    

然后创建结构实例并获取转换后的矩形角新点。

let view = UIView(frame: CGRect(x: 40, y: 20, width: 100, height: 50))
view.transform = .init(rotationAngle: .pi / 4)
let corners = ViewCorners(view: view)
print(corners.topLeft,
      corners.topRight,
      corners.bottomLeft,
      corners.bottomRight,
      separator: "\n")

【讨论】:

【参考方案3】:

使用 Swift 4,我们可以通过简单的方式获得旋转视图的边界。

让transformedBounds = view.bounds.applying(view.transform)

【讨论】:

以上是关于获取旋转的矩形 UIView 角的坐标 iOS的主要内容,如果未能解决你的问题,请参考以下文章

从旋转的矩形计算边界框坐标

获取叠加在地图上的矩形的角的坐标

Tkinter:获取鼠标绘制矩形的坐标

从旋转的矩形计算边界框坐标

HTML5 Canvas:旋转后获取矩形坐标(相对于屏幕)

想问一个关于数学旋转的问题,就是在直角坐标系中,某个点绕原点旋转某个度数,应该怎么求出旋转后的度数