1. Andy Finnell
  2. VectorBoolean

Commits

Andy Finnell  committed 2dc5c7b

moving code around

  • Participants
  • Parent commits 66bf617
  • Branches default

Comments (0)

Files changed (8)

File VectorBoolean.xcodeproj/project.pbxproj

View file
 
 /* Begin PBXBuildFile section */
 		A11131E513960B9D00C9395C /* NSBezierPath+Boolean.m in Sources */ = {isa = PBXBuildFile; fileRef = A11131E413960B9D00C9395C /* NSBezierPath+Boolean.m */; };
+		A11131F21398714800C9395C /* FBPolygon.m in Sources */ = {isa = PBXBuildFile; fileRef = A11131F11398714800C9395C /* FBPolygon.m */; };
+		A11131F51398814000C9395C /* FBPoint.m in Sources */ = {isa = PBXBuildFile; fileRef = A11131F41398814000C9395C /* FBPoint.m */; };
 		A1C48B381395FA380043E2C7 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A1C48B371395FA380043E2C7 /* Cocoa.framework */; };
 		A1C48B421395FA390043E2C7 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = A1C48B401395FA390043E2C7 /* InfoPlist.strings */; };
 		A1C48B451395FA390043E2C7 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = A1C48B441395FA390043E2C7 /* main.m */; };
 		A1C48B511395FA390043E2C7 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = A1C48B4F1395FA390043E2C7 /* MainMenu.xib */; };
 		A1C48B5F1395FAE20043E2C7 /* Geometry.m in Sources */ = {isa = PBXBuildFile; fileRef = A1C48B581395FAE10043E2C7 /* Geometry.m */; };
 		A1C48B601395FAE20043E2C7 /* NSBezierPath+FitCurve.m in Sources */ = {isa = PBXBuildFile; fileRef = A1C48B5A1395FAE10043E2C7 /* NSBezierPath+FitCurve.m */; };
-		A1C48B611395FAE20043E2C7 /* NSBezierPath+Simplify.m in Sources */ = {isa = PBXBuildFile; fileRef = A1C48B5C1395FAE10043E2C7 /* NSBezierPath+Simplify.m */; };
 		A1C48B621395FAE20043E2C7 /* NSBezierPath+Utilities.m in Sources */ = {isa = PBXBuildFile; fileRef = A1C48B5E1395FAE20043E2C7 /* NSBezierPath+Utilities.m */; };
 		A1C48B65139602480043E2C7 /* CanvasView.m in Sources */ = {isa = PBXBuildFile; fileRef = A1C48B64139602480043E2C7 /* CanvasView.m */; };
 		A1C48B68139602820043E2C7 /* Canvas.m in Sources */ = {isa = PBXBuildFile; fileRef = A1C48B67139602810043E2C7 /* Canvas.m */; };
 /* Begin PBXFileReference section */
 		A11131E313960B9D00C9395C /* NSBezierPath+Boolean.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSBezierPath+Boolean.h"; sourceTree = "<group>"; };
 		A11131E413960B9D00C9395C /* NSBezierPath+Boolean.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSBezierPath+Boolean.m"; sourceTree = "<group>"; };
+		A11131F01398714800C9395C /* FBPolygon.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FBPolygon.h; sourceTree = "<group>"; };
+		A11131F11398714800C9395C /* FBPolygon.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBPolygon.m; sourceTree = "<group>"; };
+		A11131F31398814000C9395C /* FBPoint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FBPoint.h; sourceTree = "<group>"; };
+		A11131F41398814000C9395C /* FBPoint.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBPoint.m; sourceTree = "<group>"; };
 		A1C48B331395FA380043E2C7 /* VectorBoolean.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = VectorBoolean.app; sourceTree = BUILT_PRODUCTS_DIR; };
 		A1C48B371395FA380043E2C7 /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = System/Library/Frameworks/Cocoa.framework; sourceTree = SDKROOT; };
 		A1C48B3A1395FA390043E2C7 /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = System/Library/Frameworks/AppKit.framework; sourceTree = SDKROOT; };
 		A1C48B581395FAE10043E2C7 /* Geometry.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Geometry.m; sourceTree = "<group>"; };
 		A1C48B591395FAE10043E2C7 /* NSBezierPath+FitCurve.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSBezierPath+FitCurve.h"; sourceTree = "<group>"; };
 		A1C48B5A1395FAE10043E2C7 /* NSBezierPath+FitCurve.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSBezierPath+FitCurve.m"; sourceTree = "<group>"; };
-		A1C48B5B1395FAE10043E2C7 /* NSBezierPath+Simplify.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSBezierPath+Simplify.h"; sourceTree = "<group>"; };
-		A1C48B5C1395FAE10043E2C7 /* NSBezierPath+Simplify.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSBezierPath+Simplify.m"; sourceTree = "<group>"; };
 		A1C48B5D1395FAE10043E2C7 /* NSBezierPath+Utilities.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSBezierPath+Utilities.h"; sourceTree = "<group>"; };
 		A1C48B5E1395FAE20043E2C7 /* NSBezierPath+Utilities.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSBezierPath+Utilities.m"; sourceTree = "<group>"; };
 		A1C48B63139602480043E2C7 /* CanvasView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CanvasView.h; sourceTree = "<group>"; };
 				A1C48B67139602810043E2C7 /* Canvas.m */,
 				A1C48B571395FAE00043E2C7 /* Geometry.h */,
 				A1C48B581395FAE10043E2C7 /* Geometry.m */,
+				A11131F31398814000C9395C /* FBPoint.h */,
+				A11131F41398814000C9395C /* FBPoint.m */,
+				A11131F01398714800C9395C /* FBPolygon.h */,
+				A11131F11398714800C9395C /* FBPolygon.m */,
 				A11131E313960B9D00C9395C /* NSBezierPath+Boolean.h */,
 				A11131E413960B9D00C9395C /* NSBezierPath+Boolean.m */,
 				A1C48B591395FAE10043E2C7 /* NSBezierPath+FitCurve.h */,
 				A1C48B5A1395FAE10043E2C7 /* NSBezierPath+FitCurve.m */,
-				A1C48B5B1395FAE10043E2C7 /* NSBezierPath+Simplify.h */,
-				A1C48B5C1395FAE10043E2C7 /* NSBezierPath+Simplify.m */,
 				A1C48B5D1395FAE10043E2C7 /* NSBezierPath+Utilities.h */,
 				A1C48B5E1395FAE20043E2C7 /* NSBezierPath+Utilities.m */,
 				A1C48B4C1395FA390043E2C7 /* MyDocument.xib */,
 				A1C48B4B1395FA390043E2C7 /* MyDocument.m in Sources */,
 				A1C48B5F1395FAE20043E2C7 /* Geometry.m in Sources */,
 				A1C48B601395FAE20043E2C7 /* NSBezierPath+FitCurve.m in Sources */,
-				A1C48B611395FAE20043E2C7 /* NSBezierPath+Simplify.m in Sources */,
 				A1C48B621395FAE20043E2C7 /* NSBezierPath+Utilities.m in Sources */,
 				A1C48B65139602480043E2C7 /* CanvasView.m in Sources */,
 				A1C48B68139602820043E2C7 /* Canvas.m in Sources */,
 				A11131E513960B9D00C9395C /* NSBezierPath+Boolean.m in Sources */,
+				A11131F21398714800C9395C /* FBPolygon.m in Sources */,
+				A11131F51398814000C9395C /* FBPoint.m in Sources */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};

File VectorBoolean/FBPoint.h

View file
+//
+//  FBPoint.h
+//  VectorBoolean
+//
+//  Created by Andrew Finnell on 6/2/11.
+//  Copyright 2011 Fortunate Bear, LLC. All rights reserved.
+//
+
+#import <Cocoa/Cocoa.h>
+
+
+@interface FBPoint : NSObject {
+    FBPoint *_next;
+    FBPoint *_previous;
+    FBPoint *_neighbor;
+    NSPoint _location;
+    BOOL _intersection;
+    BOOL _entry;
+    CGFloat _relativeDistance;
+}
+
+- (id) initWithLocation:(NSPoint)location;
+
+@property (assign) FBPoint *next;
+@property (assign) FBPoint *previous;
+@property NSPoint location;
+
+@end
+
+///////////////////////////////////////////////////////////////
+
+@interface FBPointList : NSObject {
+    FBPoint *_head;
+    FBPoint *_tail;
+    NSMutableArray *_points;
+}
+
+- (void) addPoint:(FBPoint *)point;
+- (void) enumeratePointsWithBlock:(void (^)(FBPoint *point, BOOL *stop))block;
+
+@end

File VectorBoolean/FBPoint.m

View file
+//
+//  FBPoint.m
+//  VectorBoolean
+//
+//  Created by Andrew Finnell on 6/2/11.
+//  Copyright 2011 Fortunate Bear, LLC. All rights reserved.
+//
+
+#import "FBPoint.h"
+
+
+@implementation FBPoint
+
+@synthesize next=_next;
+@synthesize previous=_previous;
+@synthesize location=_location;
+
+- (id) initWithLocation:(NSPoint)location
+{
+    self = [super init];
+    
+    if ( self != nil ) {
+        _location = location;
+    }
+    
+    return self;
+}
+
+@end
+
+///////////////////////////////////////////////////////////////
+
+@implementation FBPointList
+
+- (id) init
+{
+    self = [super init];
+    
+    if ( self != nil ) {
+        _points = [[NSMutableArray alloc] initWithCapacity:20];
+    }
+    
+    return self;
+}
+
+- (void) dealloc
+{
+    [_points release];
+    
+    [super dealloc];
+}
+
+- (void) addPoint:(FBPoint *)point
+{
+    [_points addObject:point]; // add a ref to keep it around
+    
+    if ( _head == nil ) {
+        // No points yet
+        _head = point;
+        _tail = point;
+        point.previous = nil;
+        point.next = nil;
+    } else {
+        point.next = nil;
+        point.previous = _tail;
+        _tail.next = point;
+        _tail = point;
+    }
+}
+
+- (void) enumeratePointsWithBlock:(void (^)(FBPoint *point, BOOL *stop))block
+{
+    FBPoint *current = _head;
+    BOOL stop = NO;
+    while ( !stop && current != nil ) {
+        block(current, &stop);
+        
+        current = current.next;
+    }
+}
+
+@end

File VectorBoolean/FBPolygon.h

View file
+//
+//  FBPolygon.h
+//  VectorBoolean
+//
+//  Created by Andrew Finnell on 6/2/11.
+//  Copyright 2011 Fortunate Bear, LLC. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+
+@interface FBPolygon : NSObject {
+    NSMutableArray *_subpolygons;
+}
+
+- (id) initWithBezierPath:(NSBezierPath *)bezier;
+
+- (FBPolygon *) unionWithPolygon:(FBPolygon *)polygon;
+- (FBPolygon *) intersectWithPolygon:(FBPolygon *)polygon;
+- (FBPolygon *) differenceWithPolygon:(FBPolygon *)polygon;
+- (FBPolygon *) xorWithPolygon:(FBPolygon *)polygon;
+
+- (NSBezierPath *) bezierPath;
+
+@end

File VectorBoolean/FBPolygon.m

View file
+//
+//  FBPolygon.m
+//  VectorBoolean
+//
+//  Created by Andrew Finnell on 6/2/11.
+//  Copyright 2011 Fortunate Bear, LLC. All rights reserved.
+//
+
+#import "FBPolygon.h"
+#import "NSBezierPath+FitCurve.h"
+#import "NSBezierPath+Utilities.h"
+#import "FBPoint.h"
+
+@implementation FBPolygon
+
+- (id)init
+{
+    self = [super init];
+    if (self != nil) {
+        _subpolygons = [[NSMutableArray alloc] initWithCapacity:2];
+    }
+    
+    return self;
+}
+
+- (id) initWithBezierPath:(NSBezierPath *)bezier
+{
+    self = [self init];
+    
+    if ( self != nil ) {
+        // Normally there will only be one point list. However if the polygon has a hole,
+        //  or has been cut in half completely (from a previous operation, perhaps), then
+        //  there will be multiple. We use move to ops as a flag that we're starting a new
+        //  point list.
+        FBPointList *pointList = nil;
+        NSBezierPath *flatPath = [bezier bezierPathByFlatteningPath];
+        for (NSUInteger i = 0; i < [flatPath elementCount]; i++) {
+            NSBezierElement element = [flatPath fb_elementAtIndex:i];
+            if ( element.kind == NSMoveToBezierPathElement ) {
+                pointList = [[[FBPointList alloc] init] autorelease];
+                [_subpolygons addObject:pointList];
+            }
+            
+            if ( element.kind == NSMoveToBezierPathElement || element.kind == NSLineToBezierPathElement ) 
+                [pointList addPoint:[[[FBPoint alloc] initWithLocation:element.point] autorelease]];
+        }        
+    }
+    
+    return self;
+}
+
+
+- (void)dealloc
+{
+    [_subpolygons release];
+    
+    [super dealloc];
+}
+
+- (FBPolygon *) unionWithPolygon:(FBPolygon *)polygon
+{
+    return self; // TODO: implement
+}
+
+- (FBPolygon *) intersectWithPolygon:(FBPolygon *)polygon
+{
+    return self; // TODO: implement
+}
+
+- (FBPolygon *) differenceWithPolygon:(FBPolygon *)polygon
+{
+    return self; // TODO: implement
+}
+
+- (FBPolygon *) xorWithPolygon:(FBPolygon *)polygon
+{
+    FBPolygon *allParts = [self unionWithPolygon:polygon];
+    FBPolygon *intersectingParts = [self intersectWithPolygon:polygon];
+    return [allParts differenceWithPolygon:intersectingParts];
+}
+
+- (NSBezierPath *) bezierPath
+{
+    NSBezierPath *path = [NSBezierPath bezierPath];
+    
+    for (FBPointList *pointList in _subpolygons) {
+        __block BOOL firstPoint = YES;
+        NSBezierPath *polygonPath = [NSBezierPath bezierPath];
+        [pointList enumeratePointsWithBlock:^(FBPoint *point, BOOL *stop) {
+            if ( firstPoint ) {
+                [polygonPath moveToPoint:point.location];
+                firstPoint = NO;
+            } else
+                [polygonPath lineToPoint:point.location];
+        }];
+        [path appendBezierPath:[polygonPath fb_fitCurve:2]];
+    }
+    
+    return path;
+}
+
+@end

File VectorBoolean/NSBezierPath+Boolean.m

View file
 //
 
 #import "NSBezierPath+Boolean.h"
-#import "NSBezierPath+FitCurve.h"
+#import "FBPolygon.h"
 #import "NSBezierPath+Utilities.h"
 
-@interface FBPoint : NSObject {
-    FBPoint *_next;
-    FBPoint *_previous;
-    FBPoint *_neighbor;
-    NSPoint _location;
-    BOOL _intersection;
-    BOOL _entry;
-    CGFloat _relativeDistance;
-}
-
-- (id) initWithLocation:(NSPoint)location;
-
-@property (assign) FBPoint *next;
-@property (assign) FBPoint *previous;
-@property NSPoint location;
-
-@end
-
-@interface FBPolygon : NSObject {
-    FBPoint *_head;
-    FBPoint *_tail;
-    NSMutableArray *_points;
-}
-
-- (void) addPoint:(FBPoint *)point;
-
-- (void) enumeratePointsWithBlock:(void (^)(FBPoint *point, BOOL *stop))block;
-
-@end
-
-@interface FBShape : NSObject {
-    NSMutableArray *_polygons;
-}
-
-- (void) addPolygon:(FBPolygon *)polygon;
-- (void) enumeratePolygonsWithBlock:(void (^)(FBPolygon *polygon, BOOL *stop))block;
-
-@end
-
-@interface NSBezierPath (BooleanPrivate)
-
-- (FBShape *) fb_shape;
-- (NSBezierPath *) fb_bezierPathFromShape:(FBShape *)shape;
-
-@end
-
-@implementation FBPoint
-
-@synthesize next=_next;
-@synthesize previous=_previous;
-@synthesize location=_location;
-
-- (id) initWithLocation:(NSPoint)location
-{
-    self = [super init];
-    
-    if ( self != nil ) {
-        _location = location;
-    }
-    
-    return self;
-}
-
-@end
-
-@implementation FBPolygon
-
-- (id) init
-{
-    self = [super init];
-    
-    if ( self != nil ) {
-        _points = [[NSMutableArray alloc] initWithCapacity:20];
-    }
-    
-    return self;
-}
-
-- (void) dealloc
-{
-    [_points release];
-    
-    [super dealloc];
-}
-
-- (void) addPoint:(FBPoint *)point
-{
-    [_points addObject:point]; // add a ref to keep it around
-    
-    if ( _head == nil ) {
-        // No points yet
-        _head = point;
-        _tail = point;
-        point.previous = nil;
-        point.next = nil;
-    } else {
-        point.next = nil;
-        point.previous = _tail;
-        _tail.next = point;
-        _tail = point;
-    }
-}
-
-- (void) enumeratePointsWithBlock:(void (^)(FBPoint *point, BOOL *stop))block
-{
-    FBPoint *current = _head;
-    BOOL stop = NO;
-    while ( !stop && current != nil ) {
-        block(current, &stop);
-        
-        current = current.next;
-    }
-}
-
-@end
-
-@implementation FBShape
-
-- (id) init
-{
-    self = [super init];
-    
-    if ( self != nil ) {
-        _polygons = [[NSMutableArray alloc] initWithCapacity:2];
-    }
-    
-    return self;
-}
-
-- (void) dealloc
-{
-    [_polygons release];
-    
-    [super dealloc];
-}
-
-- (void) addPolygon:(FBPolygon *)polygon
-{
-    [_polygons addObject:polygon];
-}
-
-- (void) enumeratePolygonsWithBlock:(void (^)(FBPolygon *polygon, BOOL *stop))block
-{
-    BOOL stop = NO;
-    for (FBPolygon *polygon in _polygons) {
-        block(polygon, &stop);
-        if ( stop )
-            break;
-    }
-}
-
-@end
-
 @implementation NSBezierPath (Boolean)
 
 - (NSBezierPath *) fb_union:(NSBezierPath *)path
 {
-    return self;
+    FBPolygon *thisPolygon = [[[FBPolygon alloc] initWithBezierPath:self] autorelease];
+    FBPolygon *otherPolygon = [[[FBPolygon alloc] initWithBezierPath:path] autorelease];
+    NSBezierPath *result = [[thisPolygon unionWithPolygon:otherPolygon] bezierPath];
+    [result fb_copyAttributesFrom:self];
+    return result;
 }
 
 - (NSBezierPath *) fb_intersect:(NSBezierPath *)path
 {
-    
-    return self;
+    FBPolygon *thisPolygon = [[[FBPolygon alloc] initWithBezierPath:self] autorelease];
+    FBPolygon *otherPolygon = [[[FBPolygon alloc] initWithBezierPath:path] autorelease];
+    NSBezierPath *result = [[thisPolygon intersectWithPolygon:otherPolygon] bezierPath];
+    [result fb_copyAttributesFrom:self];
+    return result;
 }
 
 - (NSBezierPath *) fb_difference:(NSBezierPath *)path
 {
-    return self;
+    FBPolygon *thisPolygon = [[[FBPolygon alloc] initWithBezierPath:self] autorelease];
+    FBPolygon *otherPolygon = [[[FBPolygon alloc] initWithBezierPath:path] autorelease];
+    NSBezierPath *result = [[thisPolygon differenceWithPolygon:otherPolygon] bezierPath];
+    [result fb_copyAttributesFrom:self];
+    return result;
 }
 
 - (NSBezierPath *) fb_xor:(NSBezierPath *)path
 {
-    return self;
+    FBPolygon *thisPolygon = [[[FBPolygon alloc] initWithBezierPath:self] autorelease];
+    FBPolygon *otherPolygon = [[[FBPolygon alloc] initWithBezierPath:path] autorelease];
+    NSBezierPath *result = [[thisPolygon xorWithPolygon:otherPolygon] bezierPath];
+    [result fb_copyAttributesFrom:self];
+    return result;
 }
 
 @end
-
-@implementation NSBezierPath (BooleanPrivate)
-
-
-- (FBShape *) fb_shape
-{
-    FBShape *shape = [[[FBShape alloc] init] autorelease];
-    FBPolygon *polygon = nil;
-    
-    NSBezierPath *flatPath = [self bezierPathByFlatteningPath];
-    for (NSUInteger i = 0; i < [flatPath elementCount]; i++) {
-        NSBezierElement element = [flatPath fb_elementAtIndex:i];
-        if ( element.kind == NSMoveToBezierPathElement ) {
-            polygon = [[[FBPolygon alloc] init] autorelease];
-            [shape addPolygon:polygon];
-        }
-        
-        if ( element.kind == NSMoveToBezierPathElement || element.kind == NSLineToBezierPathElement ) 
-            [polygon addPoint:[[[FBPoint alloc] initWithLocation:element.point] autorelease]];
-    }
-    
-    return shape;
-}
-
-- (NSBezierPath *) fb_bezierPathFromShape:(FBShape *)shape
-{
-    NSBezierPath *path = [NSBezierPath bezierPath];
-    [path fb_copyAttributesFrom:self];
-    
-    [shape enumeratePolygonsWithBlock:^(FBPolygon *polygon, BOOL *stopShapes) {
-        __block BOOL firstPoint = YES;
-        NSBezierPath *polygonPath = [NSBezierPath bezierPath];
-        [polygon enumeratePointsWithBlock:^(FBPoint *point, BOOL *stop) {
-            if ( firstPoint ) {
-                [polygonPath moveToPoint:point.location];
-                firstPoint = NO;
-            } else
-                [polygonPath lineToPoint:point.location];
-        }];
-        [path appendBezierPath:[polygonPath fb_fitCurve:2]];
-    }];
-    
-    return path;
-}
-
-@end

File VectorBoolean/NSBezierPath+Simplify.h

-//
-//  NSBezierPath+Simplify.h
-//  VectorBrush
-//
-//  Created by Andrew Finnell on 5/27/11.
-//  Copyright 2011 Fortunate Bear, LLC. All rights reserved.
-//
-
-#import <Foundation/Foundation.h>
-
-
-@interface NSBezierPath (Simplify)
-
-- (NSBezierPath *) fb_simplify:(CGFloat)threshold;
-
-@end

File VectorBoolean/NSBezierPath+Simplify.m

-//
-//  NSBezierPath+Simplify.m
-//  VectorBrush
-//
-//  Created by Andrew Finnell on 5/27/11.
-//  Copyright 2011 Fortunate Bear, LLC. All rights reserved.
-//
-
-#import "NSBezierPath+Simplify.h"
-#import "NSBezierPath+Utilities.h"
-#import "Geometry.h"
-
-// Implements the Ramer-Douglas-Peucker algorithm
-
-@implementation NSBezierPath (Simplify)
-
-- (NSBezierPath *) fb_simplify:(CGFloat)threshold
-{
-    if ( [self elementCount] <= 2 )
-        return self;
-    
-    CGFloat maximumDistance = 0.0;
-    NSUInteger maximumIndex = 0;
-    
-    // Find the point the furtherest away
-    for (NSUInteger i = 1; i < ([self elementCount] - 1); i++) {
-        CGFloat distance = FBDistancePointToLine([self fb_pointAtIndex:i], [self fb_pointAtIndex:0], [self fb_pointAtIndex:[self elementCount] - 1]);
-        if ( distance > maximumDistance ) {
-            maximumDistance = distance;
-            maximumIndex = i;
-        }
-    }
-    
-    if ( maximumDistance >= threshold ) {
-        // The distance is too great to simplify, so recurse
-        NSBezierPath *results1 = [[self fb_subpathWithRange:NSMakeRange(0, maximumIndex + 1)] fb_simplify:threshold];
-        NSBezierPath *results2 = [[self fb_subpathWithRange:NSMakeRange(maximumIndex, [self elementCount] - maximumIndex)] fb_simplify:threshold];
-    
-        [results1 fb_appendPath:[results2 fb_subpathWithRange:NSMakeRange(1, [results2 elementCount] - 1)]];
-        return results1;
-    } 
-        
-    // The greatest distance from our end points isn't that much, so we can simplify
-    NSBezierPath *path = [NSBezierPath bezierPath];
-    [path fb_copyAttributesFrom:self];
-    [path moveToPoint:[self fb_pointAtIndex:0]];
-    [path lineToPoint:[self fb_pointAtIndex:[self elementCount] - 1]];
-    return path;
-}
-
-@end