5

NSGradient で満たされた台形をたくさん描いています。私は彼らがシームレスに参加することを期待していますが、そうではありません。この場合、NSBezierPath を明示的にグラデーションで埋めるのではなく、クリッピングを使用することをお勧めします。

2 つのクリップ領域間のギャップ

罪を犯したコードは次のとおりです。

-(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];

2 つの三角形の間のギャップを避けるにはどうすればよいですか?

編集: NSBezierPath を明示的に埋めることで、この問題を回避しようとする試みを次に示します。

-(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];
}

2 つのパスの間の継ぎ目

左側では、同じ NSGradient で塗りつぶされた 2 つの三角形。右側の NSGradient で満たされた四角形は、私が到達しようとしている目標です。継ぎ目は、2 つの NSBezierPath の間の黒い線を隠そうとする試みですが、実際には機能しません。この場合、ほとんど見えませんが、このような三角形を大量に描画すると表示されます。

レンジャーズ回答の編集:

アンチエイリアシングなしの場合は次のようになります。

アンチエイリアシングはありませんが、問題は解決しました

技術的には、これは良い答えですが、問題は、当然のことながら、ポリゴンのエッジがアンチエイリアス処理されていないことです。エッジのアンチエイリアシングを失うことなく、クリッピング領域間のギャップを削除する方法はありますか?

4

1 に答える 1