Sto disegnando un sacco di trapezi riempiti con un NSGradient. Mi aspetto che si uniscano senza problemi, il che non è il caso. In questo caso, preferirei usare il clipping invece di riempire esplicitamente un NSBezierPath con un gradiente.Distanza tra le aree di ritaglio
ecco il codice incriminato:
-(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];
Cosa devo fare per evitare il divario tra i due triangoli?
Modifica: Questo è un tentativo di aggirare questo problema riempiendo esplicitamente 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];
}
Sulla sinistra, due triangoli riempito con lo stesso NSGradient. A destra, un quadrato riempito con un NSGradient, l'obiettivo che sto cercando di raggiungere. La giunzione è un tentativo di nascondere la linea nera tra i due NSBezierPath, ma in realtà non funziona. In questo caso, è appena visibile, ma sarà visibile se disegno una grande quantità di tali triangoli.
Modifica per Rengers risposta:
Ecco come appare senza antialiasing:
Tecnicamente, questa è la buona risposta, ma ora il problema è che, ovviamente, il il bordo del poligono non è più antialiasato. Qualche idea su come rimuovere lo spazio tra le regioni di ritaglio, senza perdere l'antialiasing sui bordi?
Qual è la tua ragione per usare il clipping invece di: 1. disegnare in percorsi Bezier - o - 2. creare un percorso con un gradiente? Forse c'è un altro approccio per affrontare meglio questo problema. – Rengers
Il mio problema iniziale era questo: ho una superficie 2D planare definita con due 2 funzioni variabili: x (u, v) ey (u, v). Voglio riempire questa superficie con un gradiente 2d. Per fare ciò suddivido la superficie lungo uev, risultando in una matrice 2D di quadrangoli o triangoli. A questo punto, riempio quei poligoni con un gradiente calcolato dal gradiente 2D originale in modo che i bordi comuni abbiano lo stesso colore. Ho provato entrambi gli approcci con questo semplice caso (2 triangoli) e ognuno ha il suo problema come puoi vedere. – alecail
Renderizza il poligono in contesto bitmap off-screen * con scala impostata su 2.0 *. Rendi il contenuto del contesto bitmap sul tuo normale contesto con scala 0.5. Implementerai efficacemente il multisampling 4x. –