FROM : Henry McGilton
DATE : Tue Jun 20 17:28:09 2006
On Jun 19, 2006, at 10:20 PM, Bill So wrote:
> I m not an expert in computer graphics. I m trying to use
> NSAffineTransform as documented in Cocoa Drawing Guide -> Coordinate
> Systems and Transforms -> Using Transforms in Your Code -> Undoing a
> Transformation.
>
> http://developer.apple.com/documentation/Cocoa/Conceptual/
> CocoaDrawingGuide/Transforms/chapter_4_section_4.html#//apple_ref/
> doc/uid/TP40003290-CH204-BCIJGDAA
>
> I found a strange behaviour in NSAffineTransform which doesn't align
> with what's described in the documentation.
<<<< munch --- see below >>>>
> As specified in the guide, the SECOND transform should be relative to
> the previous element. My understanding is that the frist transform
> translated the origin to (10, 10). And the second transform
> translated the origin to (15, 10).
>
> But I don't find it correct when I implement the example in my testing
> application. I implemented a custom NSView class "TransformView" and
> draw this view in NSWindows.
>
> The "drawRect" method of my TransformView class is as follow:
>
> - (void)drawRect:(NSRect)rect
> {
> NSPoint testPoint = { 0.0, 0.0 };
> [[NSColor whiteColor] setFill];
> NSRectFill(rect);
>
> NSColor *myColor = [NSColor grayColor];
> NSAffineTransform* xform = [NSAffineTransform transform];
> [xform translateXBy:10.0 yBy:10.0];
At this point, the transform has translated origin to (10, 10)
> [xform concat];
At this point, you have concated the CTM so that the origin
has been translated by (10, 10)
> [myColor setFill];
> NSRect myRect = NSMakeRect(0.0, 0.0, 4.0, 4.0);
>
> // fill 1st square
> NSRectFill(myRect);
>
> [xform translateXBy:5.0 yBy:0.0];
At this point, the transform has translated origin to (15, 10)
> [xform concat];
At this point, you have concated the *already* transformed CTM by
a *further* (15, 10) so that the origin becomes transformed by (25, 20).
concat operations are cumulative. You might want to also take a
look at NSGraphicsContext as well, and look at the saveGraphicsState
and restoreGraphicsState methods.
If you insert a line of code before the second translateXBy:
xform = [NSAffineTransform transform];
to obtain a fresh identity transform, your example then works as
you expect.
>
> // fill 2nd square
> NSRectFill(myRect);
> }
>
> I found that the 2nd square is not drawn at (15, 10 ). Instead, it is
> drawing at (25, 20)
>
> i.e. let 1st transformation matrix be T1 and 2nd transformation
> matrix be T2.
>
> The transformation matrix when drawing the 2nd square is T1 x (T1 x
> T2) instead of T1 x T2
Precisely --- that is the answer according to the code as originally
written.
> There's one strange behaviour. For the sake of debugging, I put an
> NSPoint variable "testPoint" and initialize it to (0, 0). The result
> of [xform transformPoint:testPoint] is correct, i.e. (15, 10), not
> (25, 20).
Yes. In that case, you simply transformed the point by the affine
transform itself --- the CTM in the graphics state was not involved.
To see what happens, in your original code, put these lines at the
end of the drawRect method.:
NSRect testRect = NSMakeRect(testPoint.x, testPoint.y, 4.0, 4.0);
[[NSColor redColor] set];
NSRectFill(testRect);
> Is there anything wrong in my code or analysis?
Yes . . . See above . . .
> Is it a bug in NSAffineTransform?
Highly unlikely . . .
Cheers,
........ Henry
===============================+============================
Henry McGilton, Boulevardier | Trilithon Software
Objective-C/Java Composer | Seroia Research
-------------------------------+----------------------------
mailto:<email_removed> | http://www.trilithon.com
|
===============================+============================
DATE : Tue Jun 20 17:28:09 2006
On Jun 19, 2006, at 10:20 PM, Bill So wrote:
> I m not an expert in computer graphics. I m trying to use
> NSAffineTransform as documented in Cocoa Drawing Guide -> Coordinate
> Systems and Transforms -> Using Transforms in Your Code -> Undoing a
> Transformation.
>
> http://developer.apple.com/documentation/Cocoa/Conceptual/
> CocoaDrawingGuide/Transforms/chapter_4_section_4.html#//apple_ref/
> doc/uid/TP40003290-CH204-BCIJGDAA
>
> I found a strange behaviour in NSAffineTransform which doesn't align
> with what's described in the documentation.
<<<< munch --- see below >>>>
> As specified in the guide, the SECOND transform should be relative to
> the previous element. My understanding is that the frist transform
> translated the origin to (10, 10). And the second transform
> translated the origin to (15, 10).
>
> But I don't find it correct when I implement the example in my testing
> application. I implemented a custom NSView class "TransformView" and
> draw this view in NSWindows.
>
> The "drawRect" method of my TransformView class is as follow:
>
> - (void)drawRect:(NSRect)rect
> {
> NSPoint testPoint = { 0.0, 0.0 };
> [[NSColor whiteColor] setFill];
> NSRectFill(rect);
>
> NSColor *myColor = [NSColor grayColor];
> NSAffineTransform* xform = [NSAffineTransform transform];
> [xform translateXBy:10.0 yBy:10.0];
At this point, the transform has translated origin to (10, 10)
> [xform concat];
At this point, you have concated the CTM so that the origin
has been translated by (10, 10)
> [myColor setFill];
> NSRect myRect = NSMakeRect(0.0, 0.0, 4.0, 4.0);
>
> // fill 1st square
> NSRectFill(myRect);
>
> [xform translateXBy:5.0 yBy:0.0];
At this point, the transform has translated origin to (15, 10)
> [xform concat];
At this point, you have concated the *already* transformed CTM by
a *further* (15, 10) so that the origin becomes transformed by (25, 20).
concat operations are cumulative. You might want to also take a
look at NSGraphicsContext as well, and look at the saveGraphicsState
and restoreGraphicsState methods.
If you insert a line of code before the second translateXBy:
xform = [NSAffineTransform transform];
to obtain a fresh identity transform, your example then works as
you expect.
>
> // fill 2nd square
> NSRectFill(myRect);
> }
>
> I found that the 2nd square is not drawn at (15, 10 ). Instead, it is
> drawing at (25, 20)
>
> i.e. let 1st transformation matrix be T1 and 2nd transformation
> matrix be T2.
>
> The transformation matrix when drawing the 2nd square is T1 x (T1 x
> T2) instead of T1 x T2
Precisely --- that is the answer according to the code as originally
written.
> There's one strange behaviour. For the sake of debugging, I put an
> NSPoint variable "testPoint" and initialize it to (0, 0). The result
> of [xform transformPoint:testPoint] is correct, i.e. (15, 10), not
> (25, 20).
Yes. In that case, you simply transformed the point by the affine
transform itself --- the CTM in the graphics state was not involved.
To see what happens, in your original code, put these lines at the
end of the drawRect method.:
NSRect testRect = NSMakeRect(testPoint.x, testPoint.y, 4.0, 4.0);
[[NSColor redColor] set];
NSRectFill(testRect);
> Is there anything wrong in my code or analysis?
Yes . . . See above . . .
> Is it a bug in NSAffineTransform?
Highly unlikely . . .
Cheers,
........ Henry
===============================+============================
Henry McGilton, Boulevardier | Trilithon Software
Objective-C/Java Composer | Seroia Research
-------------------------------+----------------------------
mailto:<email_removed> | http://www.trilithon.com
|
===============================+============================
| Related mails | Author | Date |
|---|---|---|
| Bill So | Jun 20, 07:20 | |
| Henry McGilton | Jun 20, 17:28 |






Cocoa mail archive

