2012-01-09 75 views
3

我有一套CGPoint s代表一個形狀有點像一個顛倒'T'形狀,現在我想轉換成CGRect適合內部的形狀,所以創建一個CGRect,其中包含我只是循環的整個形狀,並找出最左邊的最低xy和最高的xy右下角,這是偉大的,但留下圖像以外的白色區域,我怎麼能弄清楚最大的矩形沒有白色區域,所以最終的形狀更像是一個'|'形狀?我的代碼到目前爲止:多CGPoints CGREct

CGPoint topLeft = CGPointZero; 
CGPoint bottomRight = CGPointZero; 
for(NSValue *value in points) { 
    CGPoint point = [value CGPointValue]; 
    if(topLeft.x == 0 || topLeft.x > point.x) shapeRect.x = point.x; 
    if(topLeft.y == 0 || topLeft.y > point.y) shapeRect.y = point.y; 
    if(bottomRight.x < point.x) bottomRight.x = point.x; 
    if(bottomRight.y < point.y) bottomRight.y = point.y; 
} 
CGRect shapeRect = CGRectMake(topLeft.x, topLeft.y, bottomRight.x - topLeft.x, bottomRight.y - topLeft.y); 

編輯:我畫了一些照片,以顯示我想要實現的東西。灰色區域顯示CGRect

這裏的圖像形狀,我有座標的形狀各點:

Image Hosted by ImageShack.us http://img684.imageshack.us/img684/121/crop1.png

這裏就是我上面的代碼產生:

Image Hosted by ImageShack.us http://img26.imageshack.us/img26/2521/crop2j.png

這裏就是我想實現:

Image Hosted by ImageShack.us http://img689.imageshack.us/img689/5499/crop3.png

+0

形狀中的線是垂直的還是水平的? – joerick 2012-01-09 22:50:44

+1

另外,底部的形狀對於同樣的問題是否也是同樣有效的答案? (這也將是一個適合此形狀的矩形。) – 2012-01-09 23:46:17

回答

2

如果我沒有誤解的問題,你的目的是要找到藍點:
enter image description here

如果我是正確的,那麼它足以讓您存儲兩個點(比如topLtopR)和一個值(比如bottom)。

enter image description here

迭代:

  • 檢查當前的點有y < topL.y,最終更新topLtopR
    • 如果改爲y == topL.y檢查當前的x是否小於topL.x。如果是更新topL
    • 否則檢查是否當前x>topR.x;如果是更新topR
  • 檢查電流y>bottom。如果是更新bottom

需要注意的是,當我說「更新topL」我的意思是既xy

在最後你可以得到你的左下方,用的topLtopRx協調右下點和設置y協調底部。

1

希望你只是在談論這個形狀,總是以這種方式定向,否則這會變成一個棘手的計算幾何問題(類似凹多邊形中最大的封閉矩形)。

鑑於貴點的列表,下面應該工作:

  1. 一個。找到具有最大值的值。 b。用同樣大的值查找另一個點值。
    c。比較這兩個值的x並確定哪一個是最左邊的。

  2. 找到所有點的最小值的值。

  3. 創建兩個新的點,每個都具有X值等於在步驟1中發現的點中的一個,並與來自2.

  4. 的兩點在步驟中找到的ÿ值第1步是左上角和右上角,第3步中創建的兩個是左下角和右下角。您現在可以構建最終的矩形。

5

很難掌握你實際詢問的內容。關於標題,這個函數將爲任意數量的CGPoint創建最小的矩形。

CGRect CGRectSmallestWithCGPoints(CGPoint pointsArray[], int numberOfPoints) 
{ 
    CGFloat greatestXValue = pointsArray[0].x; 
    CGFloat greatestYValue = pointsArray[0].y; 
    CGFloat smallestXValue = pointsArray[0].x; 
    CGFloat smallestYValue = pointsArray[0].y; 

    for(int i = 1; i < numberOfPoints; i++) 
    { 
     CGPoint point = pointsArray[i]; 
     greatestXValue = MAX(greatestXValue, point.x); 
     greatestYValue = MAX(greatestYValue, point.y); 
     smallestXValue = MIN(smallestXValue, point.x); 
     smallestYValue = MIN(smallestYValue, point.y); 
    } 

    CGRect rect; 
    rect.origin = CGPointMake(smallestXValue, smallestYValue); 
    rect.size.width = greatestXValue - smallestXValue; 
    rect.size.height = greatestYValue - smallestYValue; 

    return rect; 
} 

可以像這樣使用

CGPoint poinstArray[] = {topLeft, bottomRight}; 
CGRect smallestRect = CGRectSmallestWithCGPoints(poinstArray, 2); 
1

hfossli的斯威夫特版本(它的偉大工程!):

func pointToRect(pointsArray: [CGPoint]) -> CGRect { 
    var greatestXValue = pointsArray[0].x 
    var greatestYValue = pointsArray[0].y 
    var smallestXValue = pointsArray[0].x 
    var smallestYValue = pointsArray[0].y 
    for point in pointsArray { 
     greatestXValue = max(greatestXValue, point.x); 
     greatestYValue = max(greatestYValue, point.y); 
     smallestXValue = min(smallestXValue, point.x); 
     smallestYValue = min(smallestYValue, point.y); 
    } 
    let origin = CGPoint(x: smallestXValue, y: smallestYValue) 
    let size = CGSize(width: greatestXValue - smallestXValue, height: greatestYValue - smallestYValue) 
    return CGRect(origin: origin, size: size) 
} 
0

如果你願意,你可以使用核芯顯卡:

let path = CGMutablePath() 
path.addLines(between: [p1, p2, p3, p4]) 
return path.boundingBoxOfPath