31i45
31i45

Reputation: 315

Simplifying NSBezierPath (Or UIBezierPath) code, How?

theLen = [NSBezierPath bezierPath];
[theLen moveToPoint:NSMakePoint(_frame.size.width/2 +  base / 2 , _frame.size.height/2 - (diameter / 2))];
[theLen lineToPoint:NSMakePoint(_frame.size.width/2 -  base / 2 , _frame.size.height/2 - (diameter / 2))];
[theLen lineToPoint:NSMakePoint(_frame.size.width/2 - (thickness / 2 ) , _frame.size.height/2)];
[theLen lineToPoint:NSMakePoint(_frame.size.width/2 -  base / 2 , _frame.size.height/2 + (diameter / 2))];
[theLen lineToPoint:NSMakePoint(_frame.size.width/2 + base / 2 , _frame.size.height/2 + (diameter / 2))];
[theLen lineToPoint:NSMakePoint(_frame.size.width/2 + (thickness / 2 ) , _frame.size.height/2)];
[theLen closePath];
theLen.lineWidth = 2;
[theLen stroke];
[theLen fill];

Given this code, how would you simplify it? I'm trying to learn how to simplify code and all I could think off is turning that into...

float commonNSPoint[4];
commonNSPoint[0] = _frame.size.width/2 +  base / 2;
commonNSPoint[1] = _frame.size.width/2 -  base / 2;
commonNSPoint[2] = _frame.size.height/2 - (diameter / 2);
commonNSPoint[3] = _frame.size.height/2 + (diameter / 2);

theLen = [NSBezierPath bezierPath];
[theLen moveToPoint:NSMakePoint( commonNSPoint[0],  commonNSPoint[2])];
[theLen lineToPoint:NSMakePoint(commonNSPoint[1],  commonNSPoint[2])];
[theLen lineToPoint:NSMakePoint(_frame.size.width/2 - (thickness / 2 ) , _frame.size.height/2)];
[theLen lineToPoint:NSMakePoint(commonNSPoint[1],  commonNSPoint[3])];
[theLen lineToPoint:NSMakePoint( commonNSPoint[0], commonNSPoint[3])];
[theLen lineToPoint:NSMakePoint(_frame.size.width/2 + (thickness / 2 ) , _frame.size.height/2)];
[theLen closePath];
[theLen closePath];
theLen.lineWidth = 2;
[theLen stroke];
[theLen fill];

Which doesn't really help me since NSBezierPath or UIBezierPath doesn't have their point location exactly the same. Also this made the code look messier.

How would you guys simplify a NSBezierPath or UIBezierPath such as this. Anything will help (since my program is base on different value of NSPoint and many NSBezierPath drawing).

Thank

Upvotes: 1

Views: 232

Answers (1)

rob mayoff
rob mayoff

Reputation: 386038

First, factor out your common subexpressions and give them meaningful names (which commonNSPoint is not). Here's a reasonable start:

    CGFloat xMid = _frame.size.width / 2;
    CGFloat yMid = _frame.size.height / 2;
    CGFloat radius = diameter / 2;
    CGFloat halfBase = base / 2;
    CGFloat halfThick = thickness / 2;

Then make an array of just the points without the function and method calls cluttering things up:

    CGPoint points[] = {
        { xMid + halfBase,  yMid - radius },
        { xMid - halfBase,  yMid - radius },
        { xMid - halfThick, yMid },
        { xMid - halfBase,  yMid + radius },
        { xMid + halfBase,  yMid + radius },
        { xMid + halfThick, yMid },
    };

Finally, create a path containing those points:

    theLen = [NSBezierPath bezierPath];
    [theLen appendBezierPathWithPoints:points count:sizeof points / sizeof points[0]];
    [theLen closePath];

Alternatively, let the points be centered around the origin, and then translate (slide) the path after creating it:

    CGFloat radius = diameter / 2;
    CGFloat halfBase = base / 2;
    CGFloat halfThick = thickness / 2;

    CGPoint points[] = {
        { halfBase,  radius },
        { halfBase,  radius },
        { halfThick, 0 },
        { halfBase,  radius },
        { halfBase,  radius },
        { halfThick, 0 },
    };

    theLen = [NSBezierPath bezierPath];
    [theLen appendBezierPathWithPoints:points count:sizeof points / sizeof points[0]];
    [theLen closePath];

    NSAffineTransform *transform = [NSAffineTransform transform];
    [transform translateXBy:_frame.size.width / 2 yBy:_frame.size.height / 2];
    [theLen transformUsingAffineTransform:transform];

Upvotes: 3

Related Questions