Поворот изображения в границах - PullRequest
0 голосов
/ 05 декабря 2018

Я пытаюсь повернуть вид изображения в его суперпредставлении, чтобы этот вид изображения при вращении всегда касался границ суперпредставления, не пересекая их, с соответствующим изменением размера.Как я могу это реализовать?Представление изображения должно иметь возможность вращаться на 360˚.

Здесь я использую вычисления, основанные на формулах треугольника, с учетом исходного диагонального угла просмотра изображения.

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

Пока безуспешно, мой вид изображения уменьшается слишком быстро и слишком сильно.Так что моя цель, насколько я понимаю, получить правильный масштабный коэффициент для CGAffineTransformScale.Возможно, есть другие способы сделать то же самое.

// set initial values

    _planImageView.layer.affineTransform = CGAffineTransformScale(CGAffineTransformIdentity, 1, 1);

    _degrees = 0;

    _initialWidth = _planImageView.frame.size.width;
    _initialHeight = _planImageView.frame.size.height;
    _initialAngle = MathUtils::radiansToDegrees(atan((_initialWidth / 2) / (_initialHeight / 2)));

// rotation routine

- (void)rotatePlanWithDegrees:(double)degrees
{
    double deltaDegrees = degrees - _degrees;
    _initialAngle -= deltaDegrees;
    double newAngle = _initialAngle;
    double newWidth = (_initialWidth / 2) * tan(MathUtils::degreesToRadians(newAngle)) * 2;
    double newHeight = newWidth * (_initialHeight / _initialWidth);

    NSLog(@"DEG %f DELTA %f A %f W %f H %f", degrees, deltaDegrees, newAngle, newWidth, newHeight);

    double currentScale = newWidth / _initialWidth;

    _planImageView.layer.affineTransform = CGAffineTransformScale(CGAffineTransformIdentity, currentScale, currentScale);
    _planImageView.layer.affineTransform = CGAffineTransformRotate(_planImageView.layer.affineTransform, (CGFloat) MathUtils::degreesToRadians(degrees));

    _degrees = degrees;

    self->_planImageView.center = _center;

//    NSLog(@"%@", NSStringFromCGRect(_planImageView.frame));
}

example РЕДАКТИРОВАТЬ

Я переписал рутину благодаря ответу и теперьэто работает!

- (void)rotatePlanWithDegrees:(double)degrees
{
    double newWidth =
            _initialWidth  * abs(cos(MathUtils::degreesToRadians(degrees))) +
            _initialHeight * abs(sin(MathUtils::degreesToRadians(degrees)));
    double newHeight =
            _initialWidth  * abs(sin(MathUtils::degreesToRadians(degrees))) +
            _initialHeight * abs(cos(MathUtils::degreesToRadians(degrees)));

    CGFloat scale = (CGFloat) MIN(
            self.planImageScrollView.frame.size.width / newWidth,
            self.planImageScrollView.frame.size.height / newHeight);

    CGAffineTransform rotationTransform = CGAffineTransformMakeRotation((CGFloat) MathUtils::degreesToRadians(degrees));
    CGAffineTransform scaleTransform  = CGAffineTransformMakeScale(scale, scale);
    _planImageView.layer.affineTransform = CGAffineTransformConcat(rotationTransform, scaleTransform);

    self->_planImageView.center = _center;
}

1 Ответ

0 голосов
/ 05 декабря 2018

Когда вы поворачиваете прямоугольник W x H, ограничительная рамка принимает размеры W' = W |cos Θ| + H |sin Θ|, H' = W |sin Θ| + H |cos Θ|.

Если вам нужно поместить это в прямоугольник W" x H", коэффициент масштабирования будет наименьшим из W"/W' и H"/H'.

...