2009-06-20 35 views
9

Có cách nào để tìm hiểu xem hai CGPathRef có được giao nhau hay không. Trong trường hợp của tôi tất cả các CGPaths đang có closePath.Giao lộ CGPathRef

Ví dụ: tôi có hai đường dẫn. Một đường là hình chữ nhật được xoay với một số góc và đường khác là đường cong. Nguồn gốc của hai con đường sẽ thay đổi thường xuyên. Tại một số điểm họ có thể giao nhau. Tôi muốn biết khi nào họ bị giao nhau. Vui lòng cho tôi biết nếu bạn có bất kỳ giải pháp nào.

Cảm ơn trước

Trả lời

0

1) Không có bất kỳ CGPath API nào để thực hiện việc này. Nhưng, bạn có thể làm toán để tìm ra. Hãy xem bài viết wikipedia này trên Bezier curves để xem cách các đường cong trong CGPath được triển khai.

2) Điều này sẽ chậm trên iPhone mà tôi mong đợi nhưng bạn có thể điền cả hai đường dẫn vào bộ đệm trong các màu khác nhau (nói, đỏ và xanh, với alpha = 0,5) và sau đó lặp qua bộ đệm để tìm bất kỳ điểm ảnh nào xuất hiện tại nút giao. Điều này sẽ rất chậm.

+0

# 2 thực sự là rất nhanh, và là một giải pháp tuyệt vời cho một số loại vấn đề (chẳng hạn như tìm kiếm giao lộ của đột quỵ thay vì điền). –

3

Thực hiện một con đường con đường cắt, vẽ con đường khác, sau đó tìm kiếm pixel mà sống sót sau quá trình cắt:

// initialise and erase context 
CGContextAddPath(context, path1); 
CGContextClip(context); 

// set fill colour to intersection colour 
CGContextAddPath(context, path2); 
CGContextFillPath(context); 

// search for pixels that match intersection colour 

này hoạt động vì cắt = giao nhau.

Đừng quên giao lộ đó phụ thuộc vào định nghĩa về độ trong, trong đó có một số điểm. Mã này sử dụng quy tắc điền số cuộn, bạn có thể muốn quy tắc lẻ hoặc một lần nữa. Nếu nội thất không giữ cho bạn vào ban đêm, sau đó mã này sẽ được sử dụng tốt.

Câu trả lời trước của tôi liên quan đến việc vẽ đường cong trong suốt đến ngữ cảnh RGBA. Giải pháp này là vượt trội so với cái cũ vì nó là

  1. đơn giản
  2. sử dụng một phần tư của bộ nhớ như một bối cảnh 8bit greyscale cũng đủ
  3. obviates sự cần thiết cho lông, khó khăn để gỡ lỗi đang tính minh bạch

Ai có thể yêu cầu thêm?

Tôi đoán bạn có thể yêu cầu thực hiện đầy đủ, sẵn sàng cắt giảm, nhưng điều đó sẽ làm hỏng niềm vui và làm xáo trộn câu trả lời đơn giản khác.

TRỞ LÊN, khó hiểu và kém hiệu quả ĐÁP

Vẽ cả CGPathRefsriêng ở mức 50% trong suốt thành một zeroed, CGBitmapContextCreate -ed nhớ RGBA đệm và kiểm tra xem có bất kỳ giá trị pixel> 128. công trình này trên bất kỳ nền tảng nào hỗ trợ CoreGraphics (tức là iOS và OSX).

Trong giả

// zero memory 

CGContextRef context; 
context = CGBitmapContextCreate(memory, wide, high, 8, wide*4, CGColorSpaceCreateDeviceRGB(), kCGImageAlphaPremultipliedLast); 
CGContextSetRGBFillColor(context, 1, 1, 1, 0.5); // now everything you draw will be at 50% 

// draw your path 1 to context 

// draw your path 2 to context 

// for each pixel in memory buffer 
if(*p > 128) return true; // curves intersect 
else p+= 4; // keep looking 

Hãy để cho độ phân giải của các phiên bản rasterised được độ chính xác của bạn và chọn chính xác cho phù hợp với nhu cầu hiệu suất của bạn.

+0

Cảm ơn giải pháp. Nhưng, tôi không giỏi về đồ họa lõi. Làm cách nào chúng tôi có thể truy xuất và kiểm tra các pixel không phải màu trắng. –

+0

Bị bỏ qua, vì điều này dường như không hoạt động - nó sẽ KHÔNG THÊM các giá trị màu trên iOS, nó chỉ thay thế chúng. Tôi đã xem qua các tài liệu và thử các cấu hình khác nhau của không gian màu để xem có cách nào làm cho nó hoạt động không, nhưng không thành công – Adam

+0

Nếu bạn không tìm được cách để mã minh bạch hoạt động, hãy bắt đầu một câu hỏi mới. –

-1

Đối với iOS, quá trình trộn alpha dường như bị bỏ qua.

Thay vào đó, bạn có thể làm một sự pha trộn màu sắc, mà sẽ đạt được tác dụng tương tự, nhưng không cần alpha:

CGContextSetBlendMode(context, kCGBlendModeColorDodge); 
CGFloat semiTransparent[] = { .5,.5,.5,1}; 

Pixels sản lượng hình ảnh sẽ là:

  • RGB = 0 , 0,0 = (0,0f) ... không có đường dẫn
  • RGB = 64,64,64 = (0,25f) ... một đường, không có giao lộ
  • RGB = 128,128,128 = (0.5f) .. hai đường, giao lộ được tìm thấy

mã hoàn chỉnh để vẽ:

-(void) drawFirst:(CGPathRef) first second:(CGPathRef) second into:(CGContextRef)context 
{ 
    /** setup the context for DODGE (everything gets lighter if it overlaps) */ 
    CGContextSetBlendMode(context, kCGBlendModeColorDodge); 

    CGFloat semiTransparent[] = { .5,.5,.5,1}; 

    CGContextSetStrokeColor(context, semiTransparent); 
    CGContextSetFillColor(context, semiTransparent); 

    CGContextAddPath(context, first); 
    CGContextFillPath(context); 
    CGContextStrokePath(context); 

    CGContextAddPath(context, second); 
    CGContextFillPath(context); 
    CGContextStrokePath(context); 
} 

Toàn bộ mã cho kiểm tra đầu ra:

[self drawFirst:YOUR_FIRST_PATH second:YOUR_SECOND_PATH into:context]; 

// Now we can get a pointer to the image data associated with the bitmap 
// context. 
BOOL result = FALSE; 
unsigned char* data = CGBitmapContextGetData (context); 
if (data != NULL) { 

    for(int i=0; i<width; i++) 
     for(int k=0; k<width; k++) 
     { 
    //offset locates the pixel in the data from x,y. 
    //4 for 4 bytes of data per pixel, w is width of one row of data. 
    int offset = 4*((width*round(k))+round(i)); 
    int alpha = data[offset]; 
    int red = data[offset+1]; 
    int green = data[offset+2]; 
    int blue = data[offset+3]; 

      if(red > 254) 
      { 
       result = TRUE; 
       break; 
      } 
     } 

Và, cuối cùng, đây là một mã chút thay đổi từ một câu trả lời SO ... mã hoàn chỉnh cho việc tạo không gian RGB trên iOS 4, iOS 5, sẽ hỗ trợ các chức năng trên:

- (CGContextRef) createARGBBitmapContextWithFrame:(CGRect) frame 
{ 
    /** NB: this requires iOS 4 or above - it uses the auto-allocating behaviour of Apple's method, to reduce a potential memory leak in the original StackOverflow version */ 
    CGContextRef context = NULL; 
    CGColorSpaceRef colorSpace; 
    void *   bitmapData; 
    int    bitmapByteCount; 
    int    bitmapBytesPerRow; 

    // Get image width, height. We'll use the entire image. 
    size_t pixelsWide = frame.size.width; 
    size_t pixelsHigh = frame.size.height; 

    // Declare the number of bytes per row. Each pixel in the bitmap in this 
    // example is represented by 4 bytes; 8 bits each of red, green, blue, and 
    // alpha. 
    bitmapBytesPerRow = (pixelsWide * 4); 
    bitmapByteCount  = (bitmapBytesPerRow * pixelsHigh); 

    // Use the generic RGB color space. 
    colorSpace = CGColorSpaceCreateDeviceRGB(); 
    if (colorSpace == NULL) 
    { 
     fprintf(stderr, "Error allocating color space\n"); 
     return NULL; 
    } 

    // Create the bitmap context. We want pre-multiplied ARGB, 8-bits 
    // per component. Regardless of what the source image format is 
    // (CMYK, Grayscale, and so on) it will be converted over to the format 
    // specified here by CGBitmapContextCreate. 
    context = CGBitmapContextCreate (NULL, 
            pixelsWide, 
            pixelsHigh, 
            8,  // bits per component 
            bitmapBytesPerRow, 
            colorSpace, 
            kCGImageAlphaPremultipliedFirst 
            //kCGImageAlphaFirst 
            ); 
    if (context == NULL) 
    { 
     fprintf (stderr, "Context not created!"); 
    } 

    // Make sure and release colorspace before returning 
    CGColorSpaceRelease(colorSpace); 

    return context; 
} 
+0

iOS không bỏ qua alpha. Kiểm tra mã của bạn - bạn đã thử tạo CGContext với kCGImageAlphaPremultipliedLast chưa? –

+0

Tôi nghĩ rằng vấn đề minh bạch của bạn là do thực tế là bạn đã tạo một bitmap ARGB chưa chỉ định màu RGBA. Trong ARGB, màu SemiTransparent của bạn là một màu xanh lam hoa ngô khá đẹp với 50% alpha. Hãy thử CGContextSetRGBFillColor rõ ràng và cho tôi biết nếu nó sửa chữa nó. p.s. Tôi đã cập nhật giải pháp của mình để tránh những thứ trong suốt không rõ ràng này. –

+0

kCGImageAlphaPremultipliedLast (và tất cả các biến thể) không thành công. – Adam

Các vấn đề liên quan