Re: NSAffineTransform
Re: NSAffineTransform
- Subject: Re: NSAffineTransform
- From: Graham cox <email@hidden>
- Date: Tue, 26 Oct 2004 11:27:32 +1000
I don't have code to hand, as I work on several geographically
separated machines... but here's a rough outline. This is (pseudo)code
I typed straight in here, untested, off the top of my head, so don't
cut and paste it - just try and see how it's meant to work. I'm not
even sure if the method names are right.
@interface MyObject : NSObject
{
NSPoint location; // where the object is drawn
NSSize scale; // how the object is scaled
float angle; // how the object is rotated
NSBezierpath* path; // the original path positioned at the origin
}
- (void) drawTheObject;
- (void) moveObjectTo:(NSPoint) pt;
- (void) rotateObjectToRadians:(float) rad;
@end
-----
@implementation MyObject
- (void) drawTheObject
{
NSAffineTransform* tfm = [NSAffineTransform transform];
[tfm translateXBy:location.x yBy:location.y];
[tfm scaleXBy:scale.width yBy:scale.height];
[tfm rotateByRadians;angle];
NSBezierPath* temp = [path transformUsingAffineTransform:tfm];
[temp stroke]; // or whatever
}
- (void) moveObjectTo:(NSPoint) pt
{
location = pt;
}
- (void) rotateObjectToRadians:(float) rad
{
angle = rad;
}
@end
What this does is stores a path <path> which is the original,
untransformed path. Once set, it never changes. This path is relative
to the origin - e.g. centred at 0,0 or whatever. User interaction
simply changes one of the data members location, scale, angle - it does
not do anything to the path. When the object is drawn in a view, then
an affine transform is made which creates a temporary path transformed
from the original. The temp path is what gets actually drawn, then
thrown away again (or maybe cached for performance). Building a whole
graphics architecture is obviously a lot more complex than this, but
this is a reasonable principle on which to build.
You can think of <path> as describing the objects' shape only, the
other members add to this to build up the actual graphical object the
user sees. In other words the object they see and manipulate is a
<MyObject>, not a NSBezierPath object.
For a mouse drag, just override NSView's mouseDragged mehod and call
moveObjectTo, scale, etc then NSView setNeedsDisplay(InRect). When the
view refreshes, the object will be drawn with the new transform, so it
will track the mouse. Don't create a tight loop like below - work with
the architecture, not against it.
hope this helps,
Graham
On 25/10/2004, at 4:40 PM, Lorenzo wrote:
Hi thanks.
May you please show me the code? I ask so because I tried several
approaches, and finally I have got one which works but it's not so
fine.
I create a copy of the original bezier(s) then when dragging I create
continuosly a new bezier with the new scale. I guess this is not a fine
method. What do you think?
newBezier = [originalBezier copy];
while(mouseDrag){
NSAffineTransform *aTransform = [NSAffineTransform
transform];
xFactor = newX / oldX;
[aTransform scaleXBy:xFactor yBy:1.0];
newBezier = [aTransform transformBezierPath:originalBezier];
[self DrawBezier:newBezier];
// until mouseUp
}
originalBezier = [newBezier copy];
Best Regards
--
Lorenzo
email: email@hidden
From: Graham Cox <email@hidden>
Date: Mon, 25 Oct 2004 08:33:33 +1000
To: Lorenzo <email@hidden>
Cc: email@hidden
Subject: Re: NSAffineTransform
Store the path untransformed and store the scaling factors along with
it. Dragging the mouse just changes the stored scaling factors so it's
fast. Then when you draw the path, apply the transformation. The
original path is never changed.
--Graham
On 24 Oct 2004, at 2:39 am, Lorenzo wrote:
Hi there,
suppose that when I drag the mouse I want to resize dinamically a
NSBezierPath. Actually I do that resampling any point of the
bezierPath. And
it works, slowly but it works. Now I have just discovered that I can
use
NSAffineTransform.
NSAffineTransform *myTransform = [NSAffineTransform transform];
while(mouseDrag){
[myTransform scaleXBy:factorX scaleYBy:factorY];
[bezierPath transformUsingAffineTransform:myTransform];
// ...
}
but the problem is that once I apply the first scaling to the
bezierPath,
it became transformed thus the next scaling should pay attention to
the new
scale. The final (wrong) effect is that it keeps to resize double
than
the
expected value. Do you suggest something in order to fix this
problem?
Should I save the original bezierPath then duplicate and tranform the
bezierPath at any loop...?
Best Regards
--
Lorenzo
email: email@hidden
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Cocoa-dev mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
email@hidden
This email sent to email@hidden
_______________________________________________
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