Note that there are some explanatory texts on larger screens.

plurals
  1. POGap between clipping regions
    primarykey
    data
    text
    <p>I'm drawing a lot of trapezoids filled with a NSGradient. I expect them to join seamlessly, which is not the case. In this case, I would prefer to use clipping instead of explicitly filling a NSBezierPath with a gradient.</p> <p><img src="https://i.stack.imgur.com/J9Uoe.png" alt="Gap between two clipped regions"></p> <p>Here is the incriminated code:</p> <pre><code>-(void)drawRect:(NSRect)dirtyRect { [[NSColor blackColor]set]; NSRectFill(self.bounds); NSPoint v0 = NSMakePoint(100,100); NSPoint v1 = NSMakePoint(200,100); NSPoint v2 = NSMakePoint(100,200); NSPoint v3 = NSMakePoint(200,200); NSPoint v4 = NSMakePoint(150, 150); NSBezierPath * triangle0 = [NSBezierPath bezierPath]; [triangle0 moveToPoint:v0]; [triangle0 lineToPoint:v1]; [triangle0 lineToPoint:v2]; [triangle0 closePath]; NSBezierPath * triangle1 = [NSBezierPath bezierPath]; [triangle1 moveToPoint:v1]; [triangle1 lineToPoint:v2]; [triangle1 lineToPoint:v3]; [triangle1 closePath]; NSGradient * gradient = [[NSGradient alloc] initWithColorsAndLocations:[NSColor whiteColor],0.0,[NSColor orangeColor],1.0,nil]; [NSGraphicsContext saveGraphicsState]; [triangle0 addClip]; [gradient drawFromPoint:v0 toPoint:v4 options:NSGradientDrawsAfterEndingLocation|NSGradientDrawsBeforeStartingLocation]; // [gradient drawFromPoint:v0 toPoint:v4 options:0]; [NSGraphicsContext restoreGraphicsState]; [NSGraphicsContext saveGraphicsState]; [triangle1 addClip]; [gradient drawFromPoint:v3 toPoint:v4 options:NSGradientDrawsAfterEndingLocation|NSGradientDrawsBeforeStartingLocation]; //[gradient drawFromPoint:v3 toPoint:v4 options:0]; [NSGraphicsContext restoreGraphicsState]; </code></pre> <p>What should I do to avoid the gap between the two triangles ?</p> <p>Edit: Here is an attempt to go around this problem by explicitely filling NSBezierPath.</p> <pre><code>-(void)drawRect:(NSRect)dirtyRect { [[NSColor blackColor]set]; NSRectFill([self bounds]); CGContextRef c = [[NSGraphicsContext currentContext] graphicsPort]; CGContextTranslateCTM(c, 0.5, 0.5); NSPoint v0 = NSMakePoint(100,100); NSPoint v1 = NSMakePoint(200,100); NSPoint v2 = NSMakePoint(100,200); NSPoint v3 = NSMakePoint(200,200); NSBezierPath * triangle0 = [NSBezierPath bezierPath]; [triangle0 moveToPoint:v0]; [triangle0 lineToPoint:v1]; [triangle0 lineToPoint:v2]; [triangle0 closePath]; NSBezierPath * triangle1 = [NSBezierPath bezierPath]; [triangle1 moveToPoint:v1]; [triangle1 lineToPoint:v2]; [triangle1 lineToPoint:v3]; [triangle1 closePath]; [[NSColor whiteColor]set]; NSGradient * gradient = [[NSGradient alloc] initWithColorsAndLocations:[NSColor whiteColor],0.0,[NSColor orangeColor],1.0,nil]; [gradient drawInBezierPath:triangle0 angle:45]; [gradient drawInBezierPath:triangle1 angle:45+180]; NSBezierPath * seam = [ NSBezierPath bezierPath]; [seam moveToPoint:v1]; [seam lineToPoint:v2]; [[NSColor orangeColor]set]; [seam stroke]; NSGradient * gradient2 = [[NSGradient alloc] initWithColorsAndLocations:[NSColor whiteColor],0.0,[NSColor orangeColor],0.5,[NSColor whiteColor],1.0,nil]; NSBezierPath * squarePath = [NSBezierPath bezierPath]; [squarePath moveToPoint:v0]; [squarePath lineToPoint:v1]; [squarePath lineToPoint:v3]; [squarePath lineToPoint:v2]; [squarePath closePath]; CGContextTranslateCTM(c, 200, 0); [gradient2 drawInBezierPath:squarePath angle:45]; } </code></pre> <p><img src="https://i.stack.imgur.com/fh57e.png" alt="A seam between the two paths"></p> <p>On the left, two triangles filled with the same NSGradient. On the right, a square filled with an NSGradient, the goal I'm trying to reach. The seam is an attempt to hide the black line between the two NSBezierPath, but it doesn't really work. In this case, it is barely visible, but it will be visible if I draw a large amount of such triangles.</p> <p><strong>Edit for Rengers answer:</strong></p> <p>Here is how it looks without antialiasing:</p> <p><img src="https://i.stack.imgur.com/AAKRW.png" alt="No antialiasing, but the problem has moved"></p> <p>Technically, this is the good answer, but now the problem is that, unsurprisingly, the edge of the polygon are not longer antialiased. Any idea how I could remove the gap between the clipping regions, without losing the antialiasing on the edges ?</p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload