On 07/07/2012, at 10:10 AM, William Squires wrote:

> Okay, I see in the doc set that you can perform an NSAffineTransform on an 
> NSBezierPath, but how do I perform a rotation of the NSBezierPath about an 
> arbitrary CGPoint and with a specified angle in radians?


Exactly that - use [NSAffineTransform transformBezierPath:]

You just have to set up the transform correctly (see below)

> Is this something deep in CoreGraphics, or CoreAnimation? If not, I can do 
> the trigonometry myself if I can get the list of points that make up the 
> NSBezierPath, but it seems these aren't exposed, only NSBezierPathElement 
> objects. Help!
>  Also, what is the formula for calculating the area of an arbitrary triangle 
> defined by three non-collinear points in 2D space? (i.e. I can't assume the 
> triangle even has a 90 degree angle in it, or any other such shortcuts…)

Google it, there are loads of geometry answers out there. One I use which is 
overkill for this is to calculate the area of an arbitrary polygon:

(This is a category on NSBezierPath, but the path must be flattened first - it 
doesn't work if there are curve segments)


- (CGFloat)     signedAreaOfFlattenedPath
{
        if([self isEmpty])
                return 0;
        
        NSInteger                       m, i, j;
        CGFloat                         a = 0;
        NSPoint                         ap, np;
        
        m = [self elementCount];
        
        for( i = 0; i < m; ++i )
        {
                j = (i + 1) % m;
                
                [self elementAtIndex:i associatedPoints:&ap];
                [self elementAtIndex:j associatedPoints:&np];
                
                // because we are using a flattened path, we can be sure there 
are no curve elements
                
                a += ((ap.x * np.y) - (np.x * ap.y));
        }
        
        return a * 0.5;
}




>  Finally, If an NSBezierPath consisting of a closed circuit of points:
> 
> …
> NSBezierPath *mySquarePath = [NSBezierPath bezierPath];
> 
> [mySquarePath setLineWidth:1.0];
> [mySquarePath moveToPoint:CGPointMake(0.0, 0.0)];
> [mySquarePath lineToPoint:CGPointMake(10.0, 0.0)];
> [mySquarePath lineToPoint:CGPointMake(10.0, 10.0)];
> [mySquarePath lineToPoint:CGPointMake(0.0, 10.0)];
> [mySquarePath closePath];
> …
> 
> will [mySquarePath containsPoint:CGPointMake(5.0, 5.0)] return YES even 
> before I fill or stroke the path, or do I have to fill the path first?

Yes. A path is a mathematical definition, it has nothing to do with graphics. 


Rotating a path: (again a category method on NSBezierPath)

- (NSBezierPath*)               rotatedPath:(CGFloat) angle 
aboutPoint:(NSPoint) cp
{
        // return a rotated copy of the receiver. The origin is taken as point 
<cp> relative to the original path.
        // angle is a value in radians
        
        if( angle == 0.0 )
                return self;
        else
        {
                NSBezierPath* copy = [self copy];
        
                NSAffineTransform*      xfm = RotationTransform( angle, cp );
                [copy transformUsingAffineTransform:xfm];
                
                return [copy autorelease];
        }
}

which uses:

NSAffineTransform*      RotationTransform( const CGFloat angle, const NSPoint 
cp )
{
        // return a transform that will cause a rotation about the point given 
at the angle given

        NSAffineTransform*      xfm = [NSAffineTransform transform];
        [xfm translateXBy:cp.x yBy:cp.y];
        [xfm rotateByRadians:angle];
        [xfm translateXBy:-cp.x yBy:-cp.y];

        return xfm;
}



--Graham




_______________________________________________

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Reply via email to