【问题标题】:Determine if crop rect is entirely contained within rotated UIView确定裁剪矩形是否完全包含在旋转的 UIView 中
【发布时间】:2014-11-08 20:27:38
【问题描述】:

前提:我正在构建一个裁剪工具,可以处理图像的两指任意旋转以及任意裁剪。

有时图像最终会以插入空白空间以填充旋转图像和裁剪矩形之间的间隙的方式旋转(参见下面的示例)。

我需要确保图像视图在旋转时完全适合裁剪矩形。如果没有,我需要重新转换图像(缩放),使其适合裁剪范围。

使用this answer,我实现了检查旋转的 UIImageView 是否与裁剪 CGRect 相交的功能,但不幸的是,这并不能告诉我裁剪矩形是否完全包含在旋转的图像视图。希望我可以对这个答案进行一些简单的修改?

OK 的视觉示例:

还不行,我需要检测和处理:

更新:无效的方法

- (BOOL)rotatedView:(UIView*)rotatedView containsViewCompletely:(UIView*)containedView {

    CGRect rotatedBounds = rotatedView.bounds;
    CGPoint polyContainedView[4];

    polyContainedView[0] = [containedView convertPoint:rotatedBounds.origin toView:rotatedView];
    polyContainedView[1] = [containedView convertPoint:CGPointMake(rotatedBounds.origin.x + rotatedBounds.size.width, rotatedBounds.origin.y) toView:rotatedView];
    polyContainedView[2] = [containedView convertPoint:CGPointMake(rotatedBounds.origin.x + rotatedBounds.size.width, rotatedBounds.origin.y + rotatedBounds.size.height) toView:rotatedView];
    polyContainedView[3] = [containedView convertPoint:CGPointMake(rotatedBounds.origin.x, rotatedBounds.origin.y + rotatedBounds.size.height) toView:rotatedView];

    if (CGRectContainsPoint(rotatedView.bounds, polyContainedView[0]) &&
        CGRectContainsPoint(rotatedView.bounds, polyContainedView[1]) &&
        CGRectContainsPoint(rotatedView.bounds, polyContainedView[2]) &&
        CGRectContainsPoint(rotatedView.bounds, polyContainedView[3]))
        return YES;
    else
        return NO;
}

【问题讨论】:

    标签: ios objective-c cgaffinetransform separating-axis-theorem


    【解决方案1】:

    这应该比检查交叉点更容易(如在引用的线程中)。

    (旋转的)图像视图是一个四边形。因此检查就足够了 裁剪矩形的所有 4 个角点都在旋转的图像视图内。

    • 使用[cropView convertPoint:point toView:imageView]将裁剪矩形的角点转换为裁剪矩形的坐标系 (旋转)图像视图。
    • 使用CGRectContainsPoint()检查转换后的4个角点是否在图像视图的bounds矩形内。

    示例代码:

    - (BOOL)rotatedView:(UIView *)rotatedView containsCompletely:(UIView *)cropView {
    
        CGPoint cropRotated[4];
        CGRect rotatedBounds = rotatedView.bounds;
        CGRect cropBounds = cropView.bounds;
    
        // Convert corner points of cropView to the coordinate system of rotatedView:
        cropRotated[0] = [cropView convertPoint:cropBounds.origin toView:rotatedView];
        cropRotated[1] = [cropView convertPoint:CGPointMake(cropBounds.origin.x + cropBounds.size.width, cropBounds.origin.y) toView:rotatedView];
        cropRotated[2] = [cropView convertPoint:CGPointMake(cropBounds.origin.x + cropBounds.size.width, cropBounds.origin.y + cropBounds.size.height) toView:rotatedView];
        cropRotated[3] = [cropView convertPoint:CGPointMake(cropBounds.origin.x, cropBounds.origin.y + cropBounds.size.height) toView:rotatedView];
    
        // Check if all converted points are within the bounds of rotatedView:
        return (CGRectContainsPoint(rotatedBounds, cropRotated[0]) &&
                CGRectContainsPoint(rotatedBounds, cropRotated[1]) &&
                CGRectContainsPoint(rotatedBounds, cropRotated[2]) &&
                CGRectContainsPoint(rotatedBounds, cropRotated[3]));
    }
    

    【讨论】:

    • 在花了 20 分钟后,我意识到我仍然在倒退。见 q。对于我正在使用的代码..这里的问题是我需要检查cropRect点是否在多边形内 - 但你不能为此使用CGRectContainsPoint。我也不能使用裁剪视图本身,因为该视图比它在屏幕上显示的图像(边缘插图等)略大。
    • @remus:您将图像视图角点转换为窗口坐标。但是您应该将裁剪矩形角点转换为图像视图坐标。
    • 为简洁起见,我尝试使用裁剪视图而不是矩形来执行此操作,但它的行为仍然不正确。我显然在这里遗漏了一些关于 convertPoint 逻辑的东西。我这样做是否正确?
    • @remus:我认为您正在转换错误的坐标。我现在添加了一些似乎可以工作的代码(与您的非常相似)。
    • NICE ;) 非常感谢!
    猜你喜欢
    • 2013-10-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-27
    • 1970-01-01
    • 2014-12-23
    • 2014-02-03
    • 2023-03-22
    相关资源
    最近更新 更多