Несколько CGPoints для CGRect - PullRequest
       1

Несколько CGPoints для CGRect

3 голосов
/ 10 января 2012

У меня есть набор CGPoint s, которые представляют форму, которая немного похожа на перевернутую 'T' форму, теперь я хочу преобразовать эти точки в CGRect, который вписывается в форму, чтобы создатьCGRect, охватывающий всю фигуру, которую я просто зацикливаю и вырабатываю самые низкие x и y для верхнего левого угла и самые высокие x и y для нижнего правого, который является отличным, но оставляет белые областиза пределами изображения, как я могу определить самый большой прямоугольник без белых областей, чтобы окончательная форма была больше похожа на '|'форма?Мой код на данный момент:

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.

Вот форма изображения, у меня есть координаты для каждой точки в форме:

Изображение, размещенное на 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

Ответы [ 5 ]

5 голосов
/ 12 декабря 2012

Трудно понять, о чем вы на самом деле спрашиваете. Что касается заголовка, эта функция создаст наименьший прямоугольник для любого количества 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);
2 голосов
/ 24 октября 2017

Если хотите, вы можете использовать Core Graphics:

let path = CGMutablePath()
path.addLines(between: [p1, p2, p3, p4])
return path.boundingBoxOfPath
2 голосов
/ 10 января 2012

Если я не правильно понял вопрос, ваша цель - найти синие точки:
enter image description here

Если я прав, то вам достаточно сохранить две точки (скажем, topL и topR) и значение (скажем, bottom).

enter image description here

Итеративно:

  • проверить, есть ли у текущей точки y < topL.y и в конечном итоге обновить topL и topR.
    • Если вместо этого y == topL.y проверить, является ли ток x меньше topL.x. Если да, обновите topL
    • в противном случае проверить, является ли ток x>topR.x; если да, обновите topR.
  • проверить, если ток y>bottom. Если да, обновите bottom.

Обратите внимание, что когда я говорю "обновить topL", я имею в виду x и y.

В конце вы можете получить свои нижнюю левую и нижнюю правую точки, используя x координату topL и topR и установив y координату снизу.

1 голос
/ 07 июля 2016

Swift версия 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)
}
1 голос
/ 10 января 2012

Надеюсь, вы говорите только об этой единственной фигуре, всегда ориентированной таким образом, в противном случае это становится сложной вычислительной геометрией (что-то вроде самого большого заключенного прямоугольника в вогнутом многоугольнике).

Учитывая ваш списокбаллы, должны работать следующие:

  1. a.Найдите точку с наибольшим значением y .
    b.Найдите другую точку с таким же большим значением y .
    c.Сравните значения x этих двух и определите, какое из них левее.

  2. Найдите минимальное y значение всех точек.

  3. Создайте две новые точки, каждая со значением x , равным одной из точек, найденных на шаге 1, и значением y , найденным вшаг 2.

  4. Две точки из шага 1 - это ваши верхняя левая и правая точки, а две, созданные в шаге 3, - это нижняя левая и правая.Теперь вы можете построить последний прямоугольник.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...