2012-02-13 2 views
4

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

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

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

Вот код, который я создал в этой попытке:

- (CGPoint)rotateVertex:(CGPoint)vertex byRadians:(float)radians 
{ 
    float deltaX = center.x - vertex.x; 
    float deltaY = center.y - vertex.y; 
    float currentAngle = atanf(deltaX/deltaY); 
    float newAngle = currentAngle + radians; 
    float newX = cosf(newAngle) + vertex.x; 
    float newY = sinf(newAngle) + vertex.y; 
    return CGPointMake(newX, newY); 
} 

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

Я посмотрел, что CGContextRotateCTM может сделать для меня, но в конечном итоге мне нужно знать, какие вершины после вращения, поэтому просто поворот графического контекста не оставляет меня с этими измененными координатами.

Я также пробовал описанную технику here, но это привело к тому, что треугольник перевернулся вокруг второй вершины, что кажется нечетным, но затем эта техника работает с p и q, являющимися координатами x и y второй вершины.

Спасибо, что посмотрели!

Решено: Вот исправленная функция. Предполагается, что вы рассчитали центр треугольника. Я использовал метод 1/3 (x1 + x2 + x3), 1/3 (y1 + y2 + y3), описанный в статье Википедии о Centroids.

- (CGPoint)rotatePoint:(CGPoint)currentPoint byRadians:(float)radiansOfRotation 
{ 
    float deltaX = currentPoint.x - center.x; 
    float deltaY = currentPoint.y - center.y; 
    float radius = sqrtf(powf(deltaX, 2.0) + powf(deltaY, 2.0)); 
    float currentAngle = atan2f(deltaY, deltaX); 
    float newAngle = currentAngle + radiansOfRotation; 
    float newRun = radius * cosf(newAngle); 
    float newX = center.x + newRun; 
    float newRise = radius * sinf(newAngle); 
    float newY = center.y + newRise; 
    return CGPointMake(newX, newY); 
} 

примечательного отношения к почему первый коду листинг не работа, что аргументы atan2 были отменены. Кроме того, правильный расчет дельта-значений был отменен.

ответ

4

Вы забываете умножать радиус круга. Кроме того, поскольку ось Y указывает вниз в системе координат UIKit, вы должны вычесть вместо добавления радианов и отрицать координату y в конце. И вам нужно использовать atan2 только дает выход в диапазоне -pi/2 до пи/2:

float currentAngle = atan2f(deltaY, deltaX); 
float newAngle = currentAngle - radians; 
float radious = sqrtf(powf(deltaX, 2.0) + powf(deltaY, 2.0)); 
float newX = radius * cosf(newAngle) + vertex.x; 
float newY = -1.0 * radius * sinf(newAngle) + vertex.y; 
+0

Спасибо, юдзи, за то, что указали это. Я включил это в код. Это делает его правильной, но теперь мои новые координаты вершин являются выходками из-под удара. Я помещаю много сообщений регистрации и обрабатываю математику назад, чтобы проверить, могут ли входы быть пересчитаны. Я еще не там, но я думаю, вы помогли! – tobinjim

+0

Мое удовольствие. Я нашел еще одну проблему - попробуйте новую отредактированную версию выше. – yuji

+0

Ты двигаешься быстрее, чем я! Я помещаю в записи регистрации, чтобы узнать, где моя ошибка. Я строил осознание того, что Y идет в неправильном направлении, но еще не добрался. Вы меняли знак, потому что оси Y на iOS растут больше вниз, в отличие от декартовых координат? – tobinjim

0

Ответ вложен сейчас в оригинальном вопросе. Ган застенчивый о правильном приличии ;-)

Смежные вопросы