Как я могу отразить UIBezierPath?

У меня есть UIBezierPath, и я хотел бы получить его зеркальное отражение. Как я могу это сделать?

 // Method for generating a path
 UIBezierPath *myPath = [self generateAPathInBounds:boundingRect];

 // ? now I would like to mirror myPath ?

person wfbarksdale    schedule 06.01.2014    source источник


Ответы (2)


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

Если вы пытаетесь отразить путь, который занимает весь вид (или, по крайней мере, находится на одном уровне с координатой 0 оси, по которой вы зеркалируете), то ответ @wbarksdale будет работать для вас. Однако, если вы пытаетесь отразить путь, представляющий собой небольшую часть общего представления, которая находится где-то в середине представления, вам нужно проделать больше работы. В общем алгоритм такой

  //this rect should be the bounds of your path within its superviews
  //coordinate system
  let rect = myPath.bounds
  //first, you need to move the view all the way to the left
  //because otherwise, if you mirror it in its current position, 
  //the view will be thrown way off screen to the left
  path.apply(CGAffineTransform(translationX: -rect.origin.x, y: 0))
  //then you mirror it
  path.apply(CGAffineTransform(scaleX: -1, y: 1))
  //then, after its mirrored, move it back to its original position
  path.apply(CGAffineTransform(translationX: rect.origin.x + rect.width, y: 0))

В общем, алгоритм должен быть

  1. Переместите путь либо в самый левый, либо в самый верхний угол представления в зависимости от того, листаете ли вы по горизонтали или по вертикали, используя CGAffineTransform(translateX....)

  2. Отразить вид с помощью CGAffineTransform(scaleX....

  3. Верните вид в исходное положение, используя CGAffineTransform(translateX....)

person gregkerzhner    schedule 16.08.2017

В случае, если ваш path не центрирован на (0,0), этот код правильный:

// Method for generating a path
UIBezierPath *myPath = [self generateAPathInBounds:boundingRect];

// Create two transforms, one to mirror across the x axis, and one to
// to translate the resulting path back into the desired boundingRect
CGAffineTransform mirrorOverXOrigin = CGAffineTransformMakeScale(-1.0f, 1.0f);
CGAffineTransform translate = CGAffineTransformMakeTranslation(CGRectGetMidX(boundingRect), 0);
CGAffineTransform translateBack = CGAffineTransformMakeTranslation(-CGRectGetMidX(boundingRect), 0);

// Apply these transforms to the path
[myPath applyTransform:translate];
[myPath applyTransform:mirrorOverXOrigin];
[myPath applyTransform:translateBack];
person k06a    schedule 27.07.2015
comment
Что верно по этому поводу - кажется, что он скопирован из другого ответа с дополнением, не имеющим объяснения? - person Mike; 18.10.2016
comment
@Mike, мой ответ содержит 3 необходимых преобразования - person k06a; 18.10.2016
comment
Зачем нужен третий? Вы скопировали код в принятом ответе и добавили код без изменения комментария, поэтому объяснения нет. - person Mike; 18.10.2016