Commits

Anonymous committed 93d82e4

Modified FBBezierGraph NSBezierPath-based initializer to omit degenerate line segments from the graph, and to map NSClosePathBezierPathElements to their equivalent NSLineToBezierPathElements.
This change allows FBBezierGraph to more reliably work with generic NSBezierPath instances.

  • Participants
  • Parent commits af972df

Comments (0)

Files changed (2)

VectorBoolean/FBBezierGraph.m

                     break;
                     
                 case NSLineToBezierPathElement: {
-                    // Convert lines to bezier curves as well. Just set control point to be in the line formed
-                    //  by the end points
-                    [contour addCurve:[FBBezierCurve bezierCurveWithLineStartPoint:lastPoint endPoint:element.point]];
-                    
-                    lastPoint = element.point;
+                    // [MO] skip degenerate line segments
+                    if (!NSEqualPoints(element.point, lastPoint)) {
+                        // Convert lines to bezier curves as well. Just set control point to be in the line formed
+                        //  by the end points
+                        [contour addCurve:[FBBezierCurve bezierCurveWithLineStartPoint:lastPoint endPoint:element.point]];
+                        
+                        lastPoint = element.point;
+                    }
                     break;
                 }
                     
                     break;
                     
                 case NSClosePathBezierPathElement:
-                    lastPoint = NSZeroPoint;
+                    // [MO] attempt to close the bezier contour by
+                    // mapping closepaths to equivalent lineto operations,
+                    // though as with our NSLineToBezierPathElement processing,
+                    // we check so as not to add degenerate line segments which 
+                    // blow up the clipping code.
+                    
+                    if ([[contour edges] count]) {
+                        FBContourEdge *firstEdge = [[contour edges] objectAtIndex:0];
+                        NSPoint        firstPoint = [[firstEdge curve] endPoint1];
+                        
+                        // Skip degenerate line segments
+                        if (!CGPointEqualToPoint(lastPoint, firstPoint)) {
+                            [contour addCurve:[FBBezierCurve bezierCurveWithLineStartPoint:lastPoint endPoint:firstPoint]];
+                        }
+                    }
+                    lastPoint = CGPointZero;
                     break;
             }
         }

VectorBoolean/MyDocument.m

 - (void) addCircleOverlappingCircle
 {
     NSBezierPath *circle = [NSBezierPath bezierPath];
-    [self addCircleAtPoint:NSMakePoint(210, 110) withRadius:100 toPath:circle];
+    [self addCircleAtPoint:NSMakePoint(355, 240) withRadius:125 toPath:circle];
     [_view.canvas addPath:circle withColor:[NSColor blueColor]];
     
-    [self addCircleAtPoint:NSMakePoint(355, 240) withRadius:125];
+    [self addCircleAtPoint:NSMakePoint(210, 110) withRadius:100];
 }
 
 - (void) addComplexShapes
 
 - (void) addRectangle:(NSRect)rect toPath:(NSBezierPath *)rectangle
 {
-    [rectangle moveToPoint:NSMakePoint(NSMinX(rect), NSMinY(rect))];
-    [rectangle lineToPoint:NSMakePoint(NSMaxX(rect), NSMinY(rect))];
-    [rectangle lineToPoint:NSMakePoint(NSMaxX(rect), NSMaxY(rect))];
-    [rectangle lineToPoint:NSMakePoint(NSMinX(rect), NSMaxY(rect))];
-    [rectangle lineToPoint:NSMakePoint(NSMinX(rect), NSMinY(rect))];
+    [rectangle appendBezierPathWithRect:rect];
 }
 
 - (void) addCircleAtPoint:(NSPoint)center withRadius:(CGFloat)radius toPath:(NSBezierPath *)circle