Re: Is it a bug in NSAffineTransform?
Re: Is it a bug in NSAffineTransform?
- Subject: Re: Is it a bug in NSAffineTransform?
- From: Henry McGilton <email@hidden>
- Date: Tue, 20 Jun 2006 08:28:09 -0700
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@hidden | http://www.trilithon.com
|
===============================+============================
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Cocoa-dev mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden