围绕公共点旋转四条线

时间:2015-05-30 12:04:01

标签: c++ vector rotation

我在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);
}

我要做的是移动原点,然后将线向下移动到该原点,旋转它,然后将其放回原处。通过这样做,如果我做了类似的事情:

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是我对公式的引用。

感谢。

编辑:

我根据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 个答案:

答案 0 :(得分:1)

似乎发生这种情况是因为你相对于线的第一点旋转了线。因此,不要相对于第一个点旋转线,而是分别旋转两个点。

更新:如果您有一个锚(xa, ya),并且想要围绕它旋转点(x, y)。您的观点可以表示为(xa + u, ya + v),其中(u, v) = (x - xa, y - ya)。因此,您所要做的就是使用上面使用的sin和cos公式来旋转矢量(u, v),结果点将为(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);
}