简体   繁体   中英

Rotating four lines around a common point

I have four lines held in a Rectangle object. I'm trying to rotate the entire box by any angle, but I'm getting weird results.

Here's my current code:

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

What I'm trying to do is move the origin, then move the line down to that orgin, rotate it, then put it back. By doing this, if I do something like:

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

The box should rotate together. However, this doesn't even work for a line, so I'm not sure where I've gone wrong on my formula. This thread is what I'm referencing for the formula.

Thanks.


EDIT:

I've modified my code according to FalconUA's suggestion:

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

However, still not quite getting what I should.

Given:

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

Which outputs:

xxxxxx
x    x
x    x
x    x
x    x
xxxxxx

And then if I rotate by 90 (PI / 2) degrees, which is done by this:

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

I get

x    x
 x    x
  x    x
   x    x
    x    x
     x
      x
       x
        x
    x    x
     x
      x
       x
        x
         x

Seems like it happens because you're rotating lines relatively to the first point of the line. So, rotate not the line relatively to the first point, but rotate two points separately.

Update: if you have an anchor (xa, ya) , and you want to rotate the point (x, y) around it. Your point can be represented as (xa + u, ya + v) , where (u, v) = (x - xa, y - ya) . So all you have to do is rotate teh vector (u, v) by using the formula with sin and cos that you've used above and the resulting point will be (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);
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM