Commits

Anonymous committed 55bd9b4

fix case when vertical line meets horizontal line and end point, and round final curve

  • Participants
  • Parent commits 7461a36

Comments (0)

Files changed (6)

File VectorBoolean/Canvas.m

         NSArray *curves2 = [FBBezierCurve bezierCurvesFromBezierPath:path2];
         
 #if 0
-        FBBezierCurve *curve1 = [curves1 objectAtIndex:0];
-        FBBezierCurve *curve2 = [curves2 objectAtIndex:0];
+        FBBezierCurve *curve1 = [curves1 objectAtIndex:13];
+        FBBezierCurve *curve2 = [curves2 objectAtIndex:4];
         NSArray *intersections = [curve1 intersectionsWithBezierCurve:curve2];
         for (FBBezierIntersection *intersection in intersections)
             NSLog(@"intersection at %f, %f", intersection.location.x, intersection.location.y);

File VectorBoolean/FBBezierCurve.m

             if ( intersectionPoint.x > range.maximum )
                 range.maximum = intersectionPoint.x;
         }
+        if ( FBAreValuesClose(startPoint.y, endPoint.y) && FBAreValuesClose(startPoint.y, bounds.minimum) && !FBAreValuesClose(bounds.minimum, bounds.maximum) )
+            range = FBRangeMake(0, 1);
+        
         if ( LineIntersectsHorizontalLine(startPoint, endPoint, bounds.maximum, &intersectionPoint) ) {
             if ( intersectionPoint.x < range.minimum )
                 range.minimum = intersectionPoint.x;
             if ( intersectionPoint.x > range.maximum )
                 range.maximum = intersectionPoint.x;
         }
+        if ( FBAreValuesClose(startPoint.y, endPoint.y) && FBAreValuesClose(startPoint.y, bounds.maximum) && !FBAreValuesClose(bounds.minimum, bounds.maximum) )
+            range = FBRangeMake(0, 1);
         
         // We want to be able to refine t even if the convex hull lies completely inside the bounds. This
         //  also allows us to be able to use range of [1..0] as a sentinel value meaning the convex hull
 {
     NSArray *curves1 = [self splitCurveAtParameter:range.minimum];
     FBBezierCurve *upperCurve = [curves1 objectAtIndex:1];
+    if ( range.minimum == 1.0 )
+        return upperCurve;
     CGFloat adjustedMaximum = (range.maximum - range.minimum) / (1.0 - range.minimum);
     NSArray *curves2 = [upperCurve splitCurveAtParameter:adjustedMaximum];
     return [curves2 objectAtIndex:0];

File VectorBoolean/FBBezierGraph.m

         BOOL firstPoint = YES;        
         for (FBContourEdge *edge in contour.edges) {
             if ( firstPoint ) {
-                [path moveToPoint:edge.curve.endPoint1];
+                [path moveToPoint:FBRoundPoint(edge.curve.endPoint1)];
                 firstPoint = NO;
             }
             
-            [path curveToPoint:edge.curve.endPoint2 controlPoint1:edge.curve.controlPoint1 controlPoint2:edge.curve.controlPoint2];
+            [path curveToPoint:FBRoundPoint(edge.curve.endPoint2) controlPoint1:FBRoundPoint(edge.curve.controlPoint1) controlPoint2:FBRoundPoint(edge.curve.controlPoint2)];
         }
     }
     

File VectorBoolean/Geometry.h

 CGFloat FBPointSquaredLength(NSPoint point);
 NSPoint FBNormalizePoint(NSPoint point);
 NSPoint FBNegatePoint(NSPoint point);
+NSPoint FBRoundPoint(NSPoint point);
 
 BOOL FBArePointsClose(NSPoint point1, NSPoint point2);
 BOOL FBArePointsCloseWithOptions(NSPoint point1, NSPoint point2, CGFloat threshold);

File VectorBoolean/Geometry.m

     return NSMakePoint(-point.x, -point.y);
 }
 
+NSPoint FBRoundPoint(NSPoint point)
+{
+    NSPoint result = { roundf(point.x), roundf(point.y) };
+    return result;
+}
+
 NSPoint FBLineNormal(NSPoint lineStart, NSPoint lineEnd)
 {
     return FBNormalizePoint(NSMakePoint(-(lineEnd.y - lineStart.y), lineEnd.x - lineStart.x));

File VectorBoolean/MyDocument.m

 {
     self = [super init];
     if (self) {
-        _resetAction = @selector(addTriangleInsideRectangle);
+        _resetAction = @selector(addComplexShapes);
     }
     return self;
 }