首页 > 解决方案 > 在边界内旋转图像

问题描述

我尝试在其超级视图中旋转图像视图,以便旋转时此图像视图始终接触超级视图的边界而不跨越它们,并进行适当的调整大小。我该如何实施?图像视图应该能够围绕 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));
}

例子 编辑

由于答案,我覆盖了常规,现在它可以工作了!

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

标签: objective-calgorithmgeometrycgaffinetransformcgaffinetransformscale

解决方案


当您旋转矩形WxH时,边界框采用尺寸W' = W |cos Θ| + H |sin Θ|, H' = W |sin Θ| + H |cos Θ|

如果您需要将其放入W"xH"矩形中,则比例因子是W"/W'和中的最小值H"/H'


推荐阅读