Determine if crop rect is entirely contained within rotated UIView

Premise: I’m building a cropping tool that handles two-finger arbitrary rotation of an image as well as arbitrary cropping.

Sometimes the image ends up rotated in a way that empty space is inserted to fill a gap between the rotated image and the crop rect (see the examples below).

  • Objective-C check if subviews of rotated UIViews intersect?
  • I need to ensure that the image view, when rotated, fits entirely into the cropping rectangle. If it doesn’t, I then need to re-transform the image (zoom it) so that it fits into the crop bounds.

    Using this answer, I’ve implemented the ability to check whether a rotated UIImageView intersects with the cropping CGRect, but unfortunately that doesn’t tell me if the crop rect is entirely contained in the rotated imageview. Hoping that I can make some easy modifications to this answer?

    A visual example of OK:

    enter image description here

    and not OK, that which I need to detect and deal with:

    enter image description here

    Update: not working method

    - (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;
            return NO;

    Solutions Collect From Internet About “Determine if crop rect is entirely contained within rotated UIView”

    That should be easier than checking for intersection (as in the referenced thread).

    The (rotated) image view is a convex quadrilateral. Therefore it suffices to check
    that all 4 corner points of the crop rectangle are within the rotated image view.

    • Use [cropView convertPoint:point toView:imageView] to convert the corner points of the crop rectangle to the coordinate system of the
      (rotated) image view.
    • Use CGRectContainsPoint() to check that the 4 converted corner points are within the bounds rectangle of the image view.

    Sample code:

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