2012-10-10 13 views
5

मैं एनएसजीडियेंट से भरे बहुत सारे ट्रैपेज़ोइड खींच रहा हूं। मैं उनसे सहजता से जुड़ने की उम्मीद करता हूं, जो मामला नहीं है। इस मामले में, मैं ढाल के साथ NSBezierPath को स्पष्ट रूप से भरने के बजाय क्लिपिंग का उपयोग करना पसंद करूंगा।क्लिपिंग क्षेत्रों के बीच गैप

Gap between two clipped regions

यहाँ दोषी कोड है:

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

मैं दो त्रिकोण के बीच की खाई से बचने के लिए क्या करना चाहिए?

संपादित करें: यहां 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]; 
} 

A seam between the two paths

बाईं तरफ, दो त्रिकोण एक ही NSGradient से भरा। दाईं तरफ, एक एनएसजीडियेंट से भरा वर्ग, जिस लक्ष्य तक मैं पहुंचने की कोशिश कर रहा हूं। सीम दो NSBezierPath के बीच काली रेखा को छिपाने का प्रयास है, लेकिन यह वास्तव में काम नहीं करता है। इस मामले में, यह मुश्किल से दिखाई देता है, लेकिन अगर मैं बड़ी संख्या में ऐसे त्रिकोण खींचता हूं तो यह दिखाई देगा। Rengers जवाब के लिए

संपादित करें:

यहाँ कैसे यह एंटीलायज़िंग़ बिना लग रहा है:

No antialiasing, but the problem has moved

तकनीकी तौर पर, यह अच्छा जवाब है, लेकिन अब समस्या यह है कि, आश्चर्य, है बहुभुज के किनारे अब एंटीअलाइज्ड नहीं हैं। किसी भी विचार से मैं किनारों पर एंटीअलाइजिंग खोने के बिना, क्लिपिंग क्षेत्रों के बीच के अंतर को कैसे हटा सकता हूं?

+0

इसके बजाय क्लिपिंग का उपयोग करने का आपका कारण क्या है: 1. बेजियर पथों में ड्राइंग - या - 2. एक ढाल के साथ एक पथ बनाना? शायद इस समस्या से निपटने के लिए एक और तरीका बेहतर है। – Rengers

+0

मेरी प्रारंभिक समस्या यह थी: मेरे पास दो 2 चरणीय कार्यों के साथ परिभाषित प्लानर 2 डी सतह है: x (u, v) और y (u, v)। मैं इस सतह को 2 डी ढाल के साथ भरना चाहता हूं। ऐसा करने के लिए मैं सतह को यू और वी के साथ उप-विभाजित करता हूं, जिसके परिणामस्वरूप क्वाड्रैंगल्स या त्रिकोण के 2 डी सरणी होती है। इस बिंदु पर, मैं उन बहुभुजों को मूल 2 डी ढाल से गणना की गई ढाल के साथ भरता हूं ताकि आम किनारों का रंग समान हो। मैंने इस सरल मामले (2 त्रिकोण) के साथ दोनों दृष्टिकोणों की कोशिश की है और प्रत्येक की अपनी समस्या है जैसा आप देख सकते हैं। – alecail

+2

अपने बहुभुज को ऑफ-स्क्रीन बिटमैप संदर्भ * को स्केल सेट 2.0 * के साथ प्रस्तुत करें। बिटमैप संदर्भ की सामग्री को अपने नियमित संदर्भ में 0.5 स्केल के साथ प्रस्तुत करें। आप प्रभावी ढंग से 4x multisampling लागू करेंगे। –

उत्तर

2

यह संभवतः एंटी-एलाइजिंग की वजह से है जो डिफ़ॉल्ट रूप से सक्षम है। आप इसका उपयोग कर अक्षम कर सकते हैं:

[[NSGraphicsContext currentContext] setShouldAntialias:NO]; 
+0

कोई व्यक्ति इस कुकी को एक कुकी देता है। मेरी समस्या हल हो गई! –

संबंधित मुद्दे