计算旋转矩形的位置
main.cpp
#include <QApplication>
#include <QtMath>
#include <QDebug>
#include <QPointF>
#include <QRectF>
#include <QWidget>
#include <QResizeEvent>
#include <QGraphicsView>
#include <QGraphicsScene>
#include <QGraphicsItem>
#include <QPainter>
#include <QPen>
qreal calculateEuclideanDistance(const QPointF &startPoint, const QPointF &endPoint) {
const QPointF delta = endPoint - startPoint;
return qSqrt(
qPow(delta.y(), 2.0) + qPow(delta.x(), 2.0)
);
}
qreal calculateSlopRadian(const QPointF &startPoint, const QPointF &endPoint) {
const QPointF delta = endPoint - startPoint;
if (0 == delta.x() && 0 == delta.y()) {
return 0;
} else if (0 == delta.x()) {
// ↓↑
if (delta.y() >= 0) {
// ↓
return M_PI_2;
} else {
// ↑
return M_PI_2 * 3;
}
} else if (0 == delta.y()) {
// →←
if (delta.x() >= 0) {
// →
return 0;
} else {
// ←
return M_PI;
}
} else {
// ↘↙↖↗
if (delta.y() >= 0) {
// ↘↙
return qAtan2(delta.y(), delta.x());
} else {
// ↖↗
return qAtan2(delta.y(), delta.x()) + M_PI * 2;
}
}
}
void demoCalculateSlopRadian() {
QPointF p1(0, 0);
for (int i = 0; i <= 720; i += 45) {
qreal r = (i / 360.0) * (2 * M_PI);
QPointF p2(150 * qCos(r), 150 * qSin(r));
qreal slopRadian = calculateSlopRadian(p1, p2);
qDebug() << slopRadian / M_PI * 180;
}
}
void calculateRotatedRect(const QRectF &rectF, const QPointF &anchor, qreal rotateRadian, QPointF outPointArray[4]) {
// A -- B
// | |
// D -- C
QPointF pointArray[4];
pointArray[0] = rectF.topLeft();
pointArray[1] = rectF.topRight();
pointArray[2] = rectF.bottomRight();
pointArray[3] = rectF.bottomLeft();
#define MS_initPointByLengthAndRadian(MP_point, MP_l, MP_r) \
MP_point.setX(MP_l * qCos(MP_r)); \
MP_point.setY(MP_l * qSin(MP_r));
//
qreal distance, radian;
for (int i = 0; i < 4; i++) {
distance = calculateEuclideanDistance(anchor, pointArray[i]);
// qDebug() << distance;
radian = calculateSlopRadian(anchor, pointArray[i]) + rotateRadian;
MS_initPointByLengthAndRadian(outPointArray[i], distance, radian)
outPointArray[i] += anchor;
}
#undef MS_initPointByLengthAndRadian
}
void demoCalculateRotatedRect(QPainter *painter) {
const Qt::GlobalColor colorArray[] = {Qt::red, Qt::green, Qt::yellow, Qt::blue};
const int colorSize = 4;
QRectF rectF;
QPointF anchor;
QPointF pointArray[4];
for (int i = 0, j = 0; i <= 360; i += 45, j++) {
qreal r = (i / 360.0) * (2 * M_PI);
painter->setPen(QPen(colorArray[j % colorSize]));
rectF.setRect(j * 80, 0, 70, 30);
anchor.setX(j * 80 + 70);
painter->drawRect(rectF);
calculateRotatedRect(rectF, anchor, r, pointArray);
//
painter->drawLine(pointArray[0], pointArray[1]);
painter->drawLine(pointArray[1], pointArray[2]);
painter->drawLine(pointArray[2], pointArray[3]);
painter->drawLine(pointArray[3], pointArray[0]);
// qDebug() << pointArray[0] << pointArray[1] << pointArray[2] << pointArray[3];
}
}
class MainItem : public QGraphicsItem {
public:
QRectF boundingRect() const override {
return {-5000, -5000, 5000 * 2, 5000 * 2};
}
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override {
demoCalculateSlopRadian();
demoCalculateRotatedRect(painter);
}
};
class MainWidget : public QWidget {
public:
QGraphicsView *view;
QGraphicsScene *scene;
MainWidget() {
view = new QGraphicsView(this);
scene = new QGraphicsScene();
view->setScene(scene);
scene->addItem(new MainItem());
}
protected:
void resizeEvent(QResizeEvent *event) override {
QWidget::resizeEvent(event);
const QSize &size = event->size();
view->setGeometry(0, 0, size.width(), size.height());
}
};
int main(int argc, char *argv[]) {
QApplication app(argc, argv);
MainWidget widget;
widget.show();
return QApplication::exec();
}