Как я могу переместить CGPath без создания нового

StackOverflow https://stackoverflow.com/questions/2255090

  •  20-09-2019
  •  | 
  •  

Вопрос

Я создаю CGPath чтобы определить область в моей игре следующим образом:

CGPathMoveToPoint   ( myPath, NULL, center.x, center.y );
CGPathAddLineToPoint( myPath, NULL,center.x + 100, center.y);
CGPathAddLineToPoint( myPath, NULL, center.x + 100, center.y + 100);
CGPathAddLineToPoint( myPath, NULL, center.x,  center.y + 100);
CGPathCloseSubpath  ( myPath );

Я знаю, что это всего лишь квадрат, и что я мог бы просто использовать другой CGRect но путь, который я хочу на самом деле создать, на самом деле не является прямоугольником (в данный момент я просто тестирую).И затем обнаруживать область касания просто с помощью:

if (CGPathContainsPoint(myPath, nil, location, YES))

Все это работает нормально, проблема в том, что CGPath может перемещаться до 40 раз в секунду.Как я могу переместить его без необходимости создавать новый?Я знаю, что могу сделать что-то подобное, чтобы "переместить" его:

center.y += x;
CGPathRelease(myPath);
myPath = CGPathCreateMutable();
CGPathMoveToPoint   ( myPath, NULL, center.x, center.y );
CGPathAddLineToPoint( myPath, NULL,center.x + 100, center.y);
CGPathAddLineToPoint( myPath, NULL, center.x + 100, center.y + 100);
CGPathAddLineToPoint( myPath, NULL, center.x,  center.y + 100);
CGPathCloseSubpath  ( myPath );

Но мне приходится освобождать и создавать новый путь до 40 раз в секунду, что, как мне кажется, может привести к снижению производительности;это правда?

Я хотел бы иметь возможность перемещать его точно так же, как я сейчас перемещаю некоторые CGRects просто установив исходное значение в другое значение, возможно ли это с CGPath?

Спасибо.

Редактировать:Я забыл упомянуть, что у меня нет GraphicsContext, поскольку я не рисую на UIView.

Это было полезно?

Решение

Применение преобразования к CGPath и проверка по точке эквивалентны применению обратный трансформация в точку.

Таким образом, вы можете использовать

CGPoint adjusted_point = CGPointMake(location.x - center.x, location.y - center.y);
if (CGPathContainsPoint(myPath, NULL, adjusted_point, YES)) 

Но CGPathContainsPoint уже занимает CGAffineTransform параметр (который у вас есть NULL- ред.), так что вы также можете использовать

CGAffineTransform transf = CGAffineTransformMakeTranslation(-center.x, -center.y);
if (CGPathContainsPoint(myPath, &transf, location, YES)) 

Если вы рисуете, вместо изменения пути вы можете изменить CTM непосредственно в коде чертежа.

CGContextSaveGState(c);
CGContextTranslateCTM(c, center.x, center.y);
// draw your path
CGContextRestoreGState(c);

Используйте CAShapeLayer если вам нужна производительность.

Другие советы

Ответ @KennyTM отлично сработал для целей OP, но вопрос остается:

Как я могу переместить CGPath без создания нового?

Что ж, две строки кода сделали свое дело за меня:

UIBezierPath* path = [UIBezierPath bezierPathWithCGPath:cgPath];
[path applyTransform:CGAffineTransformMakeTranslation(2.f, 0.f)];
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top