Превратите два CGPoints в CGRect

Как я могу, учитывая два разных CGPoints, превратить их в CGRect?

Пример:

CGPoint p1 = CGPointMake(0,10);
CGPoint p2 = CGPointMake(10,0);

Как я могу превратить это в CGRect?


person christo16    schedule 11.11.2011    source источник


Ответы (6)


Это возьмет две произвольные точки и даст вам CGRect, который имеет их как противоположные углы.

CGRect r = CGRectMake(MIN(p1.x, p2.x), 
                      MIN(p1.y, p2.y), 
                      fabs(p1.x - p2.x), 
                      fabs(p1.y - p2.y));

Меньшее значение x в паре с меньшим значением y всегда будет источником прямоугольника (первые два аргумента). Абсолютное значение разницы между значениями x будет шириной, а между значениями y - высотой.

person Ben Zotto    schedule 11.11.2011
comment
Хорошее решение, я бы изменил fabs на fabsf для более строгого соответствия типов. - person nacross; 18.10.2013
comment
@nacross: Хорошее замечание, но имейте в виду, что при компиляции для 64-битной версии CGFloat имеют двойной размер, а не размер с плавающей запятой, поэтому при использовании fabsf вы потеряете информацию. - person Ben Zotto; 19.10.2013
comment
r не будет содержать ни одного из предложенных в вопросе пунктов. maxX и maxY ACGRect не включены в прямоугольник, и точки вдоль этих границ не будут работать CGRectContainsPoint - person Christopher Swasey; 19.04.2016
comment
@ChristopherSwasey: я изменил ответ, чтобы не вводить в заблуждение по этому поводу (спасибо), хотя обратите внимание, что это не обязательно верно: если одна из заданных точек является исходной, она содержится. Это полезный комментарий, но имеет значение только в том случае, если вам это небезразлично (маловероятно, что это сделал ОП). - person Ben Zotto; 21.04.2016
comment
@BenZotto Действительно, если одна из точек является исходной, она будет содержаться, а любой другой угол - нет, но ни одна из точек в вопросе не была исходной. Там, где это будет иметь реальный эффект, используется этот метод как часть кода рисования — это приведет к тому, что прямоугольник будет слишком мал по крайней мере в одном измерении. - person Christopher Swasey; 25.04.2016

Небольшая модификация ответа Кена. Позвольте CGGeometry "стандартизировать" прямоугольник для вас.

CGRect rect = CGRectStandardize(CGRectMake(p1.x, p1.y, p2.x - p1.x, p2.y - p1.y));

person colinta    schedule 08.11.2012

Предполагая, что p1 - это начало координат, а другая точка - противоположный угол прямоугольника, вы можете сделать это:

CGRect rect = CGRectMake(p1.x, p1.y,  fabs(p2.x-p1.x), fabs(p2.y-p1.y));
person Ken Aspeslagh    schedule 11.11.2011
comment
Если вы уже знаете, что p1 является источником (его нет в примере OP), вам не нужен fabs. Но тогда вы как бы заставляете звонящего делать тяжелую работу заранее. - person Ben Zotto; 12.11.2011

Эта функция берет любое количество CGPoints и возвращает вам наименьший CGRect.

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;
}
person hfossli    schedule 12.12.2012

Быстрое расширение:

extension CGRect {
    init(p1: CGPoint, p2: CGPoint) {
        self.init(x: min(p1.x, p2.x),
                  y: min(p1.y, p2.y),
                  width: abs(p1.x - p2.x),
                  height: abs(p1.y - p2.y))
    }
}
person kelin    schedule 08.04.2019

Это вернет прямоугольник ширины или высоты 0, если две точки находятся на линии

float x,y,h,w;
if (p1.x > p2.x) {
    x = p2.x;
    w = p1.x-p2.x;
} else {
    x = p1.x;
    w = p2.x-p1.x;
}
if (p1.y > p2.y) {
    y = p2.y;
    h = p1.y-p2.y;
} else {
    y = p1.y;
    h = p2.y-p1.y;
}

CGRect newRect = CGRectMake(x,y,w,h);
person Jesse Black    schedule 11.11.2011