2015-05-30 7 views
0

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

Вот мой текущий код:

void Line::rotate(int x_anchor, int y_anchor, double angle) { 
    // Change the coordinate system 
    int xOffset = m_pt1.x() - x_anchor; 
    int yOffset = m_pt1.y() - y_anchor; 

    // Move to 0, 0 
    int xTemp = m_pt2.x() - xOffset; 
    int yTemp = m_pt2.y() - yOffset; 

    // Rotate 
    double tCos = cos(angle); 
    double tSin = sin(angle); 
    double xNew = (xTemp * tCos) - (yTemp * tSin); 
    double yNew = (xTemp * tSin) + (yTemp * tCos); 

    // Make new 
    m_pt2 = Point(xNew + xOffset, yNew + yOffset); 
} 

То, что я пытаюсь сделать, это переместить начало координат, а затем переместить линию вниз к этому orgin, вращать его, а затем положить его обратно. Делая это, если я что-то типа:

void Rectangle::rotate(int x_anchor, int y_anchor, double angle) { 
    m_t.rotate(x_anchor, y_anchor, angle); 
    m_r.rotate(x_anchor, y_anchor, angle); 
    m_b.rotate(x_anchor, y_anchor, angle); 
    m_l.rotate(x_anchor, y_anchor, angle); 
} 

Коробка должна вращаться вместе. Тем не менее, это даже не работает для строки, поэтому я не уверен, где я ошибся в своей формуле. This thread - это то, что я ссылаюсь на формулу.

Спасибо.


EDIT:

Я изменил свой код в соответствии с предложением FalconUA по:

void Line::rotate(int x_anchor, int y_anchor, double angle) { 
    /* Change the coordinate system */ 
    // Start point 
    int xStartOffset = m_pt1.x() - x_anchor; 
    int yStartOffset = m_pt1.y() - y_anchor; 
    // End point 
    int xEndOffset = m_pt2.x() - x_anchor; 
    int yEndOffset = m_pt2.y() - y_anchor; 

    /* Move to 0, 0 */ 
    // Start point 
    int xStartTemp = m_pt2.x() - xStartOffset; 
    int yStartTemp = m_pt2.y() - yStartOffset; 
    // End point 
    int xEndTemp = m_pt2.x() - xEndOffset; 
    int yEndTemp = m_pt2.y() - yEndOffset; 

    // Precalculate sin and cos 
    double tCos = cos(angle); 
    double tSin = sin(angle); 

    /* Rotate */ 
    // Start point 
    double xStartNew = (xStartTemp * tCos) - (yStartTemp * tSin); 
    double yStartNew = (xStartTemp * tSin) + (yStartTemp * tCos); 
    // End point 
    double xEndNew = (xEndTemp * tCos) - (yEndTemp * tSin); 
    double yEndNew = (xEndTemp * tSin) + (yEndTemp * tCos); 

    // Make new points 
    m_pt1 = Point(xStartNew + xStartOffset, yStartNew + yStartOffset); 
    m_pt2 = Point(xEndNew + xEndOffset,  yEndNew + yEndOffset); 
} 

Однако, до сих пор не совсем получить то, что я должен.

Дано:

Rectangle r(5, 5, 10, 10); 

Какие выходы:

xxxxxx 
x x 
x x 
x x 
x x 
xxxxxx 

И потом, если я поворачиваю на 90 (PI/2) градусов, что делается этим:

// Use the bottom left corner as the common point 
rotate(m_l.getEnd().x(), m_l.getEnd().y(), PI/2); 

Я получаю

x x 
x x 
    x x 
    x x 
    x x 
    x 
     x 
     x 
     x 
    x x 
    x 
     x 
     x 
     x 
     x 
+1

Почему бы не использовать [матрицу вращения] (http://en.wikipedia.org/wiki/Rotation_matrix)? – Axalo

+0

@ Аксало, вот что я пытаюсь использовать. Посмотрите на правую сторону 'xNew' и' yNew'. – David

+0

Я имею в виду, зачем изобретать колесо? См. [Здесь] (http://scicomp.stackexchange.com/questions/351/recommendations-for-a-usable-fast-c-matrix-library). – Axalo

ответ

1

Кажется, что это происходит потому, что вы вращаете линии относительно первой точки линии. Итак, поверните не линию относительно первой точки, а поверните две точки отдельно.

Update: если у вас есть якорь (xa, ya), и вы хотите, чтобы повернуть точку (x, y) вокруг него. Ваша точка может быть представлена ​​как (xa + u, ya + v), где (u, v) = (x - xa, y - ya). Итак, все, что вам нужно сделать, это повернуть вектор (u, v), используя формулу с sin и cos, которую вы использовали выше, и итоговая точка будет (xa + u_rotated, ya + v_rotated).

void Line::rotate(int x_anchor, int y_anchor, double angle) { 
    // the vector to rotate 
    int rotvec_x1 = m_pt1.x() - x_anchor; 
    int rotvec_y1 = m_pt1.y() - y_anchor; 

    // the vector to rotate 
    int rotvec_x2 = m_pt2.x() - x_anchor; 
    int rotvec_y2 = m_pt2.y() - y_anchor; 

    // pre-calculation for sin and cos 
    double tCos = cos(angle); 
    double tSin = sin(angle); 

    // rotating first vector 
    double rotvec_x1_new = (rotvec_x1 * tCos) - (rotvec_y1 * tSin); 
    double rotvec_y1_new = (rotvec_x1 * tSin) + (rotvec_y1 * tCos); 

    // rotating second vector 
    double rotvec_x2_new = (rotvec_x2 * tCos) - (rotvec_y2 * tSin); 
    double rotvec_y2_new = (rotvec_x2 * tSin) + (rotvec_y2 * tCos); 

    // Make new 
    m_pt1 = Point(x_anchor + rotvec_x1_new, y_anchor + rotvec_y1_new); 
    m_pt2 = Point(x_anchor + rotvec_x2_new, y_anchor + rotvec_y2_new); 
} 
+0

Лучше, но все равно не работает. См. Мое редактирование. Я поместил свой измененный код и что я вижу для вывода. – David

+0

@David Извините, мой предыдущий код был неправильным и неясным, потому что я испортил имена переменных. Я отредактировал код и добавил объяснение идеи вращения точки. Я также тестировал его на некотором входе и, похоже, правильно. – FalconUA

+0

А, ладно. Это работает для прямых углов, но не для неправильных углов. Есть идеи по этому поводу? – David

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