1、QT实现了QPointF、QLineF、 QRectF等数据类型,但是就是没有实现旋转矩形的数据类型表示,所以为了方便使用,就自定了旋转矩形QRotatedRect,用来表示带角度方向的矩形。
2、旋转矩形QRotatedRect的成员如下:
float cx:矩形中心X坐标
float cy:矩形中心Y坐标
float w:矩形宽度
float h:矩形高度
float angle:矩形角度
QRotatedRect(float cx = 0, float cy = 0, float w = 0, float h = 0, float angle = 0):无参构造函数
QRotatedRect(const QPointF& center, const QSizeF& size, float angle):有参构造函数
void points(QPointF pts[]) const:返回矩形的四个顶点
QRectF boundingRect() const:返旋转矩形的正矩形boundingRect
QPointF center():返回矩形的中线点
QSizeF size():返回矩形的大小(宽和高)
bool isNull():判断矩形是否为空矩形
QRotatedRect operator+(QPointF pt):重载+运算符,实现矩形移动
QRotatedRect operator-(QPointF pt):重载-运算符,实现矩形移动
3、旋转矩形QRotatedRect的定义如下(QRotatedRect.h):
#define M_PI_180 (0.01745329)
struct QRotatedRect
{
float cx;
float cy;
float w;
float h;
float angle;
QRotatedRect(float cx = 0, float cy = 0, float w = 0, float h = 0, float angle = 0);
QRotatedRect(const QPointF& center, const QSizeF& size, float angle);
void points(QPointF pts[]) const;
QRectF boundingRect() const;
QPointF center() const {return QPointF(cx, cy);}
QSizeF size() const {return QSizeF(w, h);}
bool isNull() const {return qFuzzyIsNull(w) || qFuzzyIsNull(h);}
QRotatedRect operator+(QPointF pt){return QRotatedRect(this->center() + pt, this->size(), this->angle);}
QRotatedRect operator-(QPointF pt){return QRotatedRect(this->center() - pt, this->size(), this->angle);}
};
4、旋转矩形QRotatedRect的实现如下(QRotatedRect.cpp):
QRotatedRect::QRotatedRect(float cx, float cy, float w, float h, float angle)
{
this->cx = cx;
this->cy = cy;
this->w = w;
this->h = h;
this->angle = angle;
}
QRotatedRect::QRotatedRect(const QPointF ¢er, const QSizeF &size, float angle)
{
this->cx = center.x();
this->cy = center.y();
this->w = size.width();
this->h = size.height();
this->angle = angle;
}
// pts[0] ------------ pts[1]
// | |
// | |
// | --> O 箭头方向为正方向. 角度是逆时针为正(与Qt/Halcon方向一致, 与OpenCv方向相反)
// | |
// | |
// pts[3] ------------ pts[2]
void QRotatedRect::points(QPointF pts[]) const
{
float fAngle = -angle * M_PI_180;
float a = (float)sin(fAngle) * 0.5f;
float b = (float)cos(fAngle) * 0.5f;
pts[0].setX(cx + a * h - b * w);
pts[0].setY(cy - b * h - a * w);
pts[2].setX(2 * cx - pts[0].x());
pts[2].setY(2 * cy - pts[0].y());
pts[3].setX(cx - a * h - b * w);
pts[3].setY(cy + b * h - a * w);
pts[1].setX(2 * cx - pts[3].x());
pts[1].setY(2 * cy - pts[3].y());
}
QRectF QRotatedRect::boundingRect() const
{
QPointF pts[4];
this->points(pts);
float x1 = min(min(min(pts[3].x(), pts[0].x()), pts[1].x()), pts[2].x());
float y1 = min(min(min(pts[3].y(), pts[0].y()), pts[1].y()), pts[2].y());
float x2 = max(max(max(pts[3].x(), pts[0].x()), pts[1].x()), pts[2].x());
float y2 = max(max(max(pts[3].y(), pts[0].y()), pts[1].y()), pts[2].y());
QPointF topleft(x1, y1);
QPointF bottomRight(x2, y2);
return QRectF(topleft, bottomRight);
}