CocoaDev

Edit AllPages

@interface NSBezierPath (CocoaDevCategory)

@implementation NSBezierPath (CocoaDevCategory)

static NSPoint CubicBezierPathPointForPoints(NSPoint *p, float n) {

// basic cubic bezier path formula where m = 1.0f - n:
//		B(n) = m^3 * P0 + 3.0f * m^2 * n * P1 + 3.0f * m * n^2 * P2 + n^3 * P3
float m = 1.0f - n;
float mSquared = m * m, nSquared = n * n;
float c0 = mSquared * m;
float c1 = 3.0f * mSquared * n;
float c2 = 3.0f * m * nSquared;
float c3 = nSquared * n;
return NSMakePoint(	c0 * p[0].x + c1 * p[1].x + c2 * p[2].x + c3 * p[3].x, 
			c0 * p[0].y + c1 * p[1].y + c2 * p[2].y + c3 * p[3].y	); }

#define CubicBezierPathLengthApproximationMacro(c0, c1, c2, c3)\ x = c0 * points[0].x + c1 * points[1].x + c2 * points[2].x + c3 * points[3].x;\ y = c0 * points[0].y + c1 * points[1].y + c2 * points[2].y + c3 * points[3].y;\ length += *gaps++ = hypotf(lastX - x, y - lastY);\ lastX = x, lastY = y; *lengths++ = length;

// JaggedOvalCategory

static float CubicBezierPathGapAdjustment(float gap, float step, int *railCount, float *mod) {

if (gap > 0.0f) {
	gap += *mod = step - fmodf(gap, step);
	int count = (int)(gap / step);
	if (gap - (float)count * step > step / 2.0f) count++;
	*railCount += count;
} else
	*mod = 0.0f;
return gap / 2.0f; }

}

}

static NSRect RectWithFlippedNegativeDimensions(NSRect r) { if (NSHeight(r) < 0.0f) { r.size.height = -r.size.height; r.origin.y -= r.size.height; } if (NSWidth(r) < 0.0f) { r.size.width = -r.size.width; r.origin.x -= r.size.width; } return r; }

}

ABORT:; return [NSBezierPath bezierPathWithOvalInRect:r];

}

@end


Very cool! It would be nice, though, to be able to http://goo.gl/Cx9sQ easily control the actual number of points as well as the depth. “Spacing” helps, but sometimes you want a star with long points and sometimes you want one with shallow points.