2013-03-22 19 views
5

我很難搞清楚如何確定可可中兩個NSBezierPath封閉對象的交集。我在網上做了一些研究,到目前爲止找不到答案。如何確定NSBezierPaths是否在Cocoa中相交?

這是我的。 enter image description here

我需要編寫某種方法,在所有這些情況下都會返回true。

什麼到目前爲止,我當時的想法是,通過使用bezierPathByFlatteningPath使用elementAtIndex扁平化的矩形,然後取每個元素(如線段):associatedPoints:要經過它的每一個點和檢查,如果第二對象(矩形或橢圓)包含該點(使用containsPoint:)。

不過,我不知道如何去通過一個段的所有點......

如果任何人有任何提示或想法,可以幫助我將不勝感激!

+2

如果你只對矩形感興趣,那麼CGRectIsEmpty(CGRectIntersection(r1,r2))將返回YES,否則它們不相交。 – verec 2013-03-22 19:33:17

+0

噢抱歉...我完全忘了提及我也有橢圓...我會更新我的問題 – 2013-03-22 19:59:44

+1

如果您對近似解決方案感興趣,會給您誤報(即:如果答案爲否,那麼肯定不會相交,如果答案是YES,那麼它們大部分時間相交,但並不總是),使用eclipse邊界框作爲矩形來計算與另一個矩形/月蝕邊界框的交點... – verec 2013-03-22 20:53:12

回答

3

如果你有2米貝塞爾路徑的矩形,並瞭解他們的每一個幀,那麼你可以使用NSIntersectsRect()

NSRect rect1 = NSMakeRect(20.0, 150.0, 300.0, 100.0); 
NSRect rect2 = NSMakeRect(100.0, 100.0, 100.0, 200.0); 

[[NSColor redColor] set]; 

[NSBezierPath strokeRect:rect1]; 
[NSBezierPath strokeRect:rect2]; 

BOOL intersects = NSIntersectsRect(rect1, rect2); 

NSLog(@"intersects == %@", (intersects ? @"YES" : @"NO")); 

產地:

enter image description here

在這種情況下,它會記錄intersects == YES

2

這是一個相當快速和乾淨的解決方案。 它也可以測試多個路徑與一個,這很好,不是嗎?

它適用於CGBezier(iOS和MacOS的兼容)

•1 - 創建必需品上下文

具有相同的尺寸比創建一個16位,一個部件(無alpha)圖形端口查看

  • 不要在每次測試中重新創建此上下文,這很耗時。 僅在視圖大小調整時重新創建它。
  • 讓我們稱此上下文computeContext

創建16個比特,一個部件1個像素的寬度和高度的(無alpha)圖形端口。

  • 讓我們把這種情況下的TestContext

•2 - 當你需要測試的路徑交集:

我們工作computeContext以下操作:

  • 清除上下文(這將是全黑)
  • 剪輯的背景下,你想測試
  • 填寫所有與你想測試 與白色的路徑的路徑
  • (從現在開始,你不需要在computeContext中。 )獲取圖像和類似的東西畫出來的的TestContext
CGImageRef clippedPathsImage = CGBitmapContextCreateImage(computeContext); 
CGRect  onePixSquare = CGRectMake(0,0,1,1); 
CGContextDrawImage(testContext, onePixSquare, clippedPathsImage); 

(別擔心,影像創建功能是快速它不malloc的,因爲任何記憶。位分配在bitmapContext中)

我們完成了!

long* data = CGBitmapContextGetData(testContext); 
BOOL intersects = (*data!=0); 
  • 這比做一些組合物具有α-繪圖快得多值

  • 這比在一個大的圖像 的圖像縮放測試所有的像素在內部作出快得多,硬件加快。所以這不是什麼大問題。

然而,如果你想更加快,並能負擔得起精度要求不高, 您可以創建一個較小的computeContext,對於爲例視圖大小的25%,並呈現所有分的路徑變換矩陣。

然後,1像素上下文中的傳輸速度會更快,但是您不能確定檢測到大小小於4像素的交點(使用25%縮放比例邏輯)。

不要使用8位灰色。我認爲它不會加快處理速度,並且在縮小到1像素時會失去很多精確度。足以失敗。

不要忘記,使用困難的方式之前要做的第一個測試是測試邊界框交集!

這是所有

開了GitHub上與庫;) https://github.com/moosefactory

希望這有助於,乾杯!;)


這是創建16位灰色上下文的代碼。 它可以更簡潔,但我聲明變量來說清楚。你不需要任何bitmapInfo(最後一個參數),因爲沒有alphaValue,所以我們不使用float格式。

-(CGContextRef)createComputeContext 
{ 
    size_t w = (size_t)self.bounds.size.width; 
    size_t h = (size_t)self.bounds.size.height; 
    size_t nComps = 1; 
    size_t bits = 16; 
    size_t bitsPerPix = bits*nComps; 
    size_t bytesPerRow = bitsPerPix*w;  
    CGColorSpaceRef cs = CGColorSpaceCreateDeviceGray(); 

    CGContextRef bmContext = CGBitmapContextCreate(NULL, w, h, bits, bytesPerRow, cs, 0); 

    return bmContext; 
} 
+0

這很有趣,但除非你有證據,否則你不應該聲稱它是「硬件加速」。這種CG繪圖 - 路徑光柵化和圖像繪製到位圖上下文中 - 通常發生在CPU上。 – 2013-07-26 00:36:16

+0

你好庫爾特,謝謝你的精確度。 我只提到圖像縮放的GPU加速。 我知道所有的位圖操作都是由CIImage和CALayer中的GPU處理的。我不認爲CoreGraphics是不同的... 也許它需要一點調查;) 乾杯。 – Moose 2013-08-31 11:07:10

相關問題