Skip to content

Instantly share code, notes, and snippets.

@hatfinch
Created August 17, 2011 09:54
Show Gist options
  • Save hatfinch/1151231 to your computer and use it in GitHub Desktop.
Save hatfinch/1151231 to your computer and use it in GitHub Desktop.
CGAffineTransformFromRectToRect (not working)
CGAffineTransform CGAffineTransformFromRectToRect(CGRect fromRect, CGRect toRect)
{
CGSize scale = CGSizeMake(toRect.size.width / fromRect.size.width, toRect.size.height / fromRect.size.height);
CGRect scaledFromRect = CGRectMake(fromRect.origin.x * scale.width, fromRect.origin.y * scale.height,
fromRect.size.width * scale.width, fromRect.size.height * scale.height);
CGSize translation = CGSizeMake(fromRect.origin.x - scaledFromRect.origin.x, fromRect.origin.y - scaledFromRect.origin.y);
return CGAffineTransformMake(scale.width, 0.0, 0.0, scale.height, translation.width, translation.height);
}
CGRect fromRect = CGRectMake(3, -1, 1, 1);
CGRect toRect = CGRectMake(1, 3, 3, 2);
CGAffineTransform trans = OLVAffineTransformFromRectToRect(fromRect, toRect); // [3, 0, 0, 2, -6, 1]
CGRect calculatedFromRect = CGRectApplyAffineTransform(fromRect, trans); // {{3, -1}, {3, 2}}
@MattFoley
Copy link

I tried to use this for some CI work and noticed that it was just slightly off. I think you guys may have been missing a small bit to offset for the size change:

 CGAffineTransform CGAffineTransformFromRectToRect(CGRect fromRect, CGRect toRect)
 {
     CGAffineTransform trans1 = CGAffineTransformMakeTranslation(-fromRect.origin.x, -fromRect.origin.y);
     CGAffineTransform scale = CGAffineTransformMakeScale(toRect.size.width/fromRect.size.width, toRect.size.height/fromRect.size.height);

     CGFloat heightDiff = fromRect.size.height - toRect.size.height;
     CGFloat widthDiff = fromRect.size.width - toRect.size.width;

     CGAffineTransform trans2 = CGAffineTransformMakeTranslation(toRect.origin.x - (widthDiff / 2), toRect.origin.y - (heightDiff / 2));
     return CGAffineTransformConcat(CGAffineTransformConcat(trans1, scale), trans2);
 }

What do you think?

@vovasty
Copy link

vovasty commented Jan 22, 2016

improved @MattFoley variant (fix for non-zero initial coordinates)

func CGAffineTransformFromRectToRect(fromRect: CGRect, toRect: CGRect) -> CGAffineTransform {
    let sx  = toRect.size.width/fromRect.size.width
    let sy  = toRect.size.height/fromRect.size.height

    let scale = CGAffineTransformMakeScale(sx, sy)

    let heightDiff = fromRect.size.height - toRect.size.height
    let widthDiff = fromRect.size.width - toRect.size.width

    let dx = toRect.origin.x - widthDiff / 2 - fromRect.origin.x
    let dy = toRect.origin.y - heightDiff / 2 - fromRect.origin.y

    let trans = CGAffineTransformMakeTranslation(dx, dy)
    return CGAffineTransformConcat(scale, trans)
}

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