Como posso mover um CGPath sem criar um novo
-
20-09-2019 - |
Pergunta
Estou criando um CGPath
Para definir uma área no meu jogo como este:
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 );
Eu sei que isso é apenas um quadrado e que eu poderia usar outro CGRect
Mas o caminho que desejo realmente criar não é realmente um retângulo (estou apenas testando no momento). E depois detectar a área de toque simplesmente com a:
if (CGPathContainsPoint(myPath, nil, location, YES))
Tudo isso funciona bem, o problema é que o CGPath
pode estar subindo até 40 vezes por segundo. Como posso movê -lo sem ter que criar um novo? Eu sei que posso fazer algo assim para "mover" isso:
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 );
Mas eu tenho que liberar e criar um novo caminho até 40 vezes por segundo, o que acho que pode ter uma penalidade de desempenho; isso é verdade?
Eu gostaria de poder movê -lo exatamente como se estivesse movendo alguns CGRects
Simplesmente definindo a origem como um valor diferente, isso é possível com CGPath
?
Obrigada.
Edit: esqueci de mencionar que não tenho um GraphicsContext, pois não estou desenhando em um UIView
.
Solução
A aplicação de uma transformação ao CGPath e teste contra um ponto é equivalente a aplicar o inverso transformação ao ponto.
Portanto, você pode usar
CGPoint adjusted_point = CGPointMake(location.x - center.x, location.y - center.y);
if (CGPathContainsPoint(myPath, NULL, adjusted_point, YES))
Mas CGPathContainsPoint
já leva um CGAffineTransform
parâmetro (que você tem NULL
-Ed isso), então você também pode usar
CGAffineTransform transf = CGAffineTransformMakeTranslation(-center.x, -center.y);
if (CGPathContainsPoint(myPath, &transf, location, YES))
Se você estiver desenhando, em vez de alterar o caminho, poderá alterar o CTM no seu código de desenho diretamente.
CGContextSaveGState(c);
CGContextTranslateCTM(c, center.x, center.y);
// draw your path
CGContextRestoreGState(c);
Use um CAShapeLayer
Se você precisar de desempenho.
Outras dicas
@A resposta de Kennytm funcionou perfeitamente para os fins do OP, mas a pergunta permanece:
Como posso mover um CGPath sem criar um novo?
Bem, duas linhas de código fizeram o truque para mim:
UIBezierPath* path = [UIBezierPath bezierPathWithCGPath:cgPath];
[path applyTransform:CGAffineTransformMakeTranslation(2.f, 0.f)];