Как я могу переместить CGPath без создания нового
-
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)];