Skip to content

Instantly share code, notes, and snippets.

@DavidBoyes
Created April 2, 2013 06:48
Show Gist options
  • Save DavidBoyes/5290376 to your computer and use it in GitHub Desktop.
Save DavidBoyes/5290376 to your computer and use it in GitHub Desktop.
Returns a rectangle which is the largest that can fit inside a rotated rectangle
- (CGRect)cropRectForRectSize:(CGSize)rectSize rotation:(float)radians {
int quadrant = ((int)floor(radians / (M_PI / 2))) & 3;
float sign_alpha = ((quadrant & 1) == 0) ? radians : M_PI - radians;
float alpha = fmod((fmod(sign_alpha, M_PI) + M_PI), M_PI);
CGSize bb = CGSizeMake(rectSize.width * cos(alpha) + rectSize.height * sin(alpha), rectSize.width * sin(alpha) + rectSize.height * cos(alpha));
float gamma = rectSize.width < rectSize.height ? atan2(bb.width, bb.height) : atan2(bb.height, bb.width);
float delta = M_PI - alpha - gamma;
float length = rectSize.width < rectSize.height ? rectSize.height : rectSize.width;
float d = length * cos(alpha);
float a = d * sin(alpha) / sin(delta);
float y = a * cos(gamma);
float x = y * tan(gamma);
return CGRectMake(x, y, bb.width - 2 * x, bb.height - 2 * y);
}
@macsourcerer
Copy link

You saved my life today. Thank You!!!

@alikaragoz
Copy link

For anyone looking, here is a swift version:

func cropRectForRectSize(_ rectSize: CGSize, rotation radians: CGFloat) -> CGRect {
        let quadrant = Int(floor(radians / .pi / 2.0)) & 3
        let signAlpha = ((quadrant & 1) == 0) ? radians : .pi - radians
        let alpha = fmod((fmod(signAlpha, .pi) + .pi), .pi)
        
        let s = CGSize(
            width: rectSize.width * cos(alpha) + rectSize.height * sin(alpha),
            height: rectSize.width * sin(alpha) + rectSize.height * cos(alpha)
        )

        let gamma = rectSize.width < rectSize.height
            ? atan2(s.width, s.height)
            : atan2(s.height, s.width)
        
        let delta = .pi - alpha - gamma
        
        let length = rectSize.width < rectSize.height
            ? rectSize.height
            : rectSize.width
        
        let d = length * cos(alpha)
        let a = d * sin(alpha) / sin(delta)
        let y = a * cos(gamma)
        let x = y * tan(gamma)

        return CGRect(x: x, y: y, width: s.width - 2 * x, height: s.height - 2 * y)
    }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment