Определите, содержится ли прямоугольник обрезки полностью в повернутом UIView

Предпосылка: я создаю инструмент кадрирования, который обрабатывает произвольное вращение изображения двумя пальцами, а также произвольное кадрирование.

Иногда изображение оказывается повернутым таким образом, что вставляется пустое пространство, чтобы заполнить промежуток между повернутым изображением и прямоугольником обрезки (см. Примеры ниже).

Мне нужно убедиться, что изображение при повороте полностью помещается в прямоугольник обрезки. Если этого не произойдет, мне нужно повторно преобразовать изображение (увеличить его), чтобы оно вписалось в границы обрезки.

Используя этот ответ, я реализовал возможность проверить, пересекается ли повернутый UIImageView с обрезанным CGRect, но, к сожалению, это не говорит мне, полностью ли содержится прямоугольник обрезки в повернутом виде изображения. Надеетесь, что я смогу внести несколько простых изменений в этот ответ?

Наглядный пример ОК:

и не хорошо, то, что мне нужно обнаружить и иметь дело с:

Обновление: не работает метод

- (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;
}

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]));
}
Другие вопросы по тегам