iosmacoscocoansbezierpathnsaffinetransform

Is there a way to make NSAffineTransform from CGAffineTransform?


I'm trying to convert the iOS code to OSX code, and having some difficulties with graphics porting.

Under iOS I had this:

NSRect rect = NSMakeRect(centerX.doubleValue - width.doubleValue / 2, 
                         centerY.doubleValue - height.doubleValue / 2, 
                         width.doubleValue, height.doubleValue);

UIBezierPath * path = nil;

switch (self.shape) 
{
    case HSTargetShapeInvisible:
        path = [UIBezierPath bezierPath];
        break;
    case HSTargetShapeOval:
        path = [UIBezierPath bezierPathWithOvalInRect:rect];
        break;
    case HSTargetShapeRectangle:
        path = [UIBezierPath bezierPathWithRect:rect];
        break;
    default:
        break;
}

CGAffineTransform translate = CGAffineTransformMakeTranslation(-1 * centerX.doubleValue, 
                                                               -1 * centerY.doubleValue);
[path applyTransform:translate];

CGAffineTransform rotate = CGAffineTransformMakeRotation(rotation.doubleValue / 180 * M_PI);
[path applyTransform:rotate];

translate = CGAffineTransformMakeTranslation(centerX.doubleValue, centerY.doubleValue);
[path applyTransform:translate];

and this worked perfectly...then I rewrote it this way for OSX:

NSRect rect = NSMakeRect(centerX.doubleValue - width.doubleValue / 2,
                         centerY.doubleValue - height.doubleValue / 2, 
                         width.doubleValue, height.doubleValue);

NSBezierPath * path = nil;

switch (self.shape) 
{
    case HSTargetShapeInvisible:
        path = [NSBezierPath bezierPath];
        break;
    case HSTargetShapeOval:
        path = [NSBezierPath bezierPathWithOvalInRect:rect];
        break;
    case HSTargetShapeRectangle:
        path = [NSBezierPath bezierPathWithRect:rect];
        break;
    default:
        break;
}

NSAffineTransform *rot = [NSAffineTransform transform];
NSAffineTransform *pos = [NSAffineTransform transform];

[pos translateXBy:-1*centerX.doubleValue yBy:-1*centerY.doubleValue];

[rot rotateByRadians:rotation.doubleValue / 180 * M_PI];

[pos translateXBy:centerX.doubleValue
              yBy:centerY.doubleValue ];

[rot appendTransform:pos];
[path transformUsingAffineTransform:rot];

And this doesn't work the same way. Does anyone know where the problem is?!

Any kind of help is highly appreciated!


Solution

  • Your original code uses three transforms, you've now tried to do it with two. Just go back to three (using distinct variables to make it clear):

    NSAffineTransform *pos1 = [NSAffineTransform transform];   
    [pos1 translateXBy:-1*centerX.doubleValue yBy:-1*centerY.doubleValue];
    [path transformUsingAffineTransform:pos1];
    
    NSAffineTransform *rot = [NSAffineTransform transform];
    [rot rotateByRadians:rotation.doubleValue / 180 * M_PI];
    [path transformUsingAffineTransform:rot];
    
    NSAffineTransform *pos2 = [NSAffineTransform transform];
    [pos2 translateXBy:centerX.doubleValue yBy:centerY.doubleValue];
    [path transformUsingAffineTransform:pos2];
    

    If you wish to just use one transformUsingAffineTransform: you can delete the three uses above and add the code:

    [pos1 appendTransform:rot];
    [pos1 appendTransform:pos2];
    [path transformUsingAffineTransform:pos1];
    

    You can even do it with one, but note the order - work from last to first:

    NSAffineTransform *compound = [NSAffineTransform transform];
    [compound translateXBy:centerX.doubleValue yBy:centerY.doubleValue];
    [compound rotateByRadians:rotation.doubleValue / 180 * M_PI];
    [compound translateXBy:-1*centerX.doubleValue yBy:-1*centerY.doubleValue];
    [path transformUsingAffineTransform:compound];
    

    HTH