Re: Affine Transform
Re: Affine Transform
- Subject: Re: Affine Transform
- From: Scott Thompson <email@hidden>
- Date: Mon, 13 Feb 2006 08:58:05 -0600
On Feb 12, 2006, at 9:32 AM, Terry Heaford wrote:
I am having difficulty getting my head around bounds vs frame vs
origin.
The coordinate system I think you want concentrate on first is the
bounds of the document view in your NSScrollView.
The bounds rectangle of a view defines the coordinate system inside
of that view. It creates a little 2D world that fits nicely into the
view and anything that goes into that view (drawing, subviews, etc..)
will have it's location defined by that 2D world.
If you can get the bounds of the view to your liking the rest of the
rectangles will be easier.
Your code to find out how big the image will be when rotated (the one
with all the trig routines in it) looks like it's trying to do things
"the hard way" to simplify the code I'd use something similar to your
original code:
NSSize imageSize = NSMakeSize([image size].width, [image
size].height);
NSAffineTransform *trans = [NSAffineTransform transform];
[trans rotateByDegrees: rotationAngle];
NSSize imageXformedSize = [trans transformSize: imageRect.size];
You can get the same effect with trig routines pretty easily, but
this code is clearer (to me anyway). If performance became a problem
you could always figure out the trig.
After you have this size in hand, you can change the bounds of the
document view to match (using setBoundsSize:). After you do this,
try the code to see if the rotation "works". With just this change
you may see the image scaling down as you rotate it.
Then inside your drawRect: you can use a transformation similar to
the one in your original code to draw the image. If your original
code work then that might look something like this (Note these code
changes were typed into mail, not XCode) :
if (image)
{
deg = 45;
// find out how big the view's local coordinate system is
NSRect bounds = [self bounds];
// Collect information about the image
NSRect imageRect = NSMakeRect(0, 0, [image size].width, [image
size].height);
NSPoint imageCenter = NSMakePoint(NSMidX(imageRect), NSMidY
(imageRect);
// create a transformation to rotate the image
NSAffineTransform *trans = [NSAffineTransform transform];
// move the origin of the coordinate system to the center of the image
[trans translateXBy: imageCenter.x yBy: imageCenter.y];
// rotate the image by deg. Note that sense this transformation
describes
// the rotation of the coordinate system (and not the image) we
need to use -deg
[trans rotateByDegrees: -deg];
// Now put the center of the coordinate system (dragging the image
along with it)
// to the center of the bounds
[trans translateXBy: NSMidX(bounds) yBy: NSMidY(bounds)];
[trans concat];
[image drawAtPoint: NSZeroPoint fromRect:imageRect
operation:NSCompositeCopy fraction:opacity];
}
One interesting thing to note is the change in sign of the "deg" used
in the rotateByDegrees: call. You mentioned that your images were
rotating just fine, but I can't help but think that they were
probably rotating in the wrong direction. Since you are manipulating
the coordinate system here, I think you want to use -deg... but a
little experimentation in code that runs (as opposed to code typed
into mail) should get you what you want.
If these changes work then you're going to want to change the size of
the frame of your view to match the change in the size of the bounds.
Use setFrameSize: to keep the size of your frame, and the size of
your bounds, in sync.
Scott
_______________________________________________
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