多个CGPoint如何转换为CGRect

3
我有一组表示一个有点像倒置的“T”形状的形状的CGPoints,现在我想将这些点转换为适合该形状的CGRect,所以要创建一个包含整个形状的CGRect,我只需循环并计算左上角的最低xy以及右下角的最高xy,这非常好,但留下了图像外的白色区域,如何找出没有白色区域的最大矩形,使最终形状更像“|”形状? 我到目前为止的代码:
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


形状中的线条始终是垂直或水平的吗? - joerick
1
此外,底部的“—”形状是否也是同一个问题的一个同样有效的答案?(它也将是一个适合于这个形状的矩形。) - Peter Hosey
5个回答

5

很难理解您实际在询问什么。关于标题,此函数将为任意数量的CGPoints创建最小矩形。

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);

3

hfossli的Swift版本(非常好用!):

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)
}

2
如果我没有误解问题的意思,你的目标是找到蓝色点:
enter image description here 如果我理解正确的话,那么你只需要存储两个点(例如topLtopR)和一个值(例如bottom)就足够了。
迭代如下:
- 检查当前点是否具有y < topL.y并最终更新topLtopR
- 如果y == topL.y,则检查当前x是否小于topL.x。如果是,则更新topL。 - 否则检查当前x>topR.x;如果是,则更新topR。 - 检查当前y>bottom。如果是,则更新bottom
请注意,当我说“更新topL”时,我指的是xy
最后,您可以使用topLtopRx坐标,并将y坐标设置为底部来获取底部左侧和底部右侧的点。

2

如果您想使用,您可以使用核心图形(Core Graphics):

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

1

计算几何

希望你所说的只是一个形状,而且始终朝着这个方向,否则这将成为一项棘手的计算几何问题(类似于一个凸多边形中的最大封闭矩形)。

根据你的点列表,以下方法应该有效:

  1. a. 找到具有最大 y 值的点。
    b. 找到另一个具有同样大的 y 值的点。
    c. 比较这两个点的 x 值,并确定哪个是最左边的。

  2. 找到所有点中最小的 y 值。

  3. 创建两个新点,每个点的 x 值均等于步骤 1 中找到的一个点,并且其 y 值为步骤 2 中找到的值。

  4. 步骤 1 中的两个点是左上角和右上角的点,步骤 3 中创建的两个点是左下角和右下角。现在可以构建最终的矩形。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接