c++ - 围绕一个公共(public)点旋转四条线

标签 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

最佳答案

这似乎是因为您相对于直线的第一个点旋转直线。因此,不是相对于第一个点旋转直线,而是分别旋转两个点。

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

关于c++ - 围绕一个公共(public)点旋转四条线,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30545934/

相关文章:

c++ - 带节点删除函数的链表问题

c++ - 如何在子类的 vector 上应用多态函数

c++ - 无法将 vector<int> 转换为 int* 用于 bool testPIN

c++ - 为什么在这段代码中编译器选择 r-value ref 版本

c++ - 四元数和旋转轴

java - 获取矩阵的当前旋转 - 使用库?

c++ - C/C++ 函数中的引用、指针或值语义

c++ - 做一个静态断言模板类型是另一个模板

javascript - 使用 Javascript 旋转文本

C++ - 混洗对象 vector