Как можно масштабировать в точке опоры с помощью CGAffineTransform? - PullRequest
1 голос
/ 30 сентября 2010

Отредактировано, чтобы лучше объяснить мою проблему

Я пытаюсь выполнить операцию масштабирования, используя мой пользовательский вид (не UIView). Представление имеет перевод, масштабирование, поворот значений. Я использую их следующим образом, между вызовами glPushMatrix () и glPopMatrix ().

- (void)transform
{
    glTranslatef(translation.x + anchor.x, translation.y + anchor.y, 0.0f);
    //glRotatef(-rotation * 57.2957795f, 0.0f, 0.0f, 1.0f);
    glScalef(scale.x, scale.y, 1.0f);
    glTranslatef(-anchor.x, -anchor.y, 0.0f);
}

Я пытаюсь выяснить, как мне следует изменить значения привязки и / или перевода, чтобы операция масштабирования относилась к тому, что отображается на экране. В масштабе 1: 1 я могу просто использовать необработанные экранные координаты в качестве привязки и выполнить вышеуказанное преобразование. Но когда представление уже находится в некотором произвольном масштабе / положении, якорь и / или перевод должны учитывать это.

Пока это то, что я понял:

1) Получить смещение от центра шкалы к началу координат в экранных координатах.

2) Масштабируйте это значение, чтобы оно находилось в локальной системе координат представления.

3) Теперь у меня есть новый якорь для масштабирования. Я установил привязку представления к этому значению.

Одного этого недостаточно, кажется. Я думаю, что мне не хватает компонента перевода или другой переменной, которая входит в новую опорную точку. Чего мне не хватает?

Ответы [ 3 ]

2 голосов
/ 08 октября 2010

Я нашел решение.Я использовал отдельное преобразование специально для операции масштабирования, в дополнение к преобразованию, которое определяет исходный вид.Я просто объединяю их, чтобы получить желаемый результат, который должен был обеспечить масштабирование относительно исходного вида.

0 голосов
/ 01 октября 2010

Ваше намерение преобразования до сих пор не совсем ясно.

Преобразование CGAffineTransformMakeTranslation создаст матрицу перевода, необходимую для достижения желаемой точки, но, как я уже упоминал в моем другом ответе, некоторые из преобразований make делают предположения о других вещах, таких как вращение, если ваш объект не был повернут и поэтому не может быть сброшен, тогда это не проблема, в противном случае вы можете использовать компоненты перевода матрицы:

Transform.tx;
Transform.ty;

Редактировать: 3 отдельные анимации должны быть сделаны с 3 отдельными матрицами:

baseMatrix = CGAffineTransformIdentity;

affineMatrix1 = CGAffineTransformTranslate(baseMatrix, -anchor.x, -anchor.y);

affineMatrix2 = CGAffineTransformScale(baseMatrix, scale.x, scale.y);

affineMatrix3 = CGAffineTransformTranslate(baseMatrix, anchor.x, anchor.y);
0 голосов
/ 30 сентября 2010

Некоторые из CGAffine анимаций делают предположения о компонентах матрицы, которые вы не ожидаете.

Например, я обнаружил, что CGAffineTransformMakeTranslation также влияет на вращение вида. По этой причине я бы порекомендовал не использовать преобразования Make, если вы объединяете много экземпляров CGAffineTransform

Кроме того, в приведенном выше примере я вижу, что вы предполагаете, что ваша матрица понимает, что ваши два перевода должны происходить в разное время. Матрица преобразования - это набор физических атрибутов об объекте в любой 1 момент времени.

  • Вы хотите, чтобы объект переместился в -anchor и масштаб

  • Вы хотите, чтобы объект переместился назад якорь

Они должны рассматриваться как две разные анимации

Вы должны сделать это с помощью 'Key Frame Animation', вот пример: CGPath Animation

В качестве альтернативы вы можете связать два метода CGAffineTransform вместе.

 -(void)Anim1
    {
    [UIView beginAnimations:@"Anim1_Done" context:NULL];
    [UIView setAnimationDuration:0.5];
    [UIView setAnimationDelegate:self];
    UIView setAnimationDidStopSelector:@selector(animationFinished:finished:context:)];
    //DO STUFF HERE


    [UIView commitAnimations];
    }


- (void)animationFinished:(NSString *)animationID finished:(BOOL)finished context:(void *)context
{


    if ([animationID isEqualToString:@"Anim1_Done"])
    {
    [self Anim2];
    }
}


 -(void)Anim2
    {
    [UIView beginAnimations:@"Anim2_Done" context:NULL];
    [UIView setAnimationDuration:0.5];
    [UIView setAnimationDelegate:self];
    UIView setAnimationDidStopSelector:@selector(animationFinished:finished:context:)];
    //DO STUFF HERE
    [UIView commitAnimations];
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...