Я использую QGraphicsView
вместе с пользовательской реализацией QAbstractGraphicsItem
для рисования стрелки и эллипса, которые могут вращаться вокруг центральной точки графического элемента (по этой причине в примере отсутствует часть перевода) , Желаемое поведение, которое я хочу, это иметь возможность рисовать синюю линию, которая идет от центра эллипса к его краю под углом стрелки (реальное приложение будет показывать круглое сечение вместо линии). Кроме того, для облегчения понимания того, что происходит на чертеже, две основные оси эллипса изображены красным и зеленым. Вот мой товар:
Заголовок
#include <QAbstractGraphicsShapeItem>
class EllipseItem : public QAbstractGraphicsShapeItem
{
public:
double ellipse_x;
double ellipse_y;
double ellipse_rot;
double arrow_angle;
double arrow_scale;
virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
virtual QRectF boundingRect() const;
};
Осуществление
#include "ellipseitem.h"
#include <QPainter>
void EllipseItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
Q_UNUSED(option);
Q_UNUSED(widget);
painter->setPen(pen());
painter->setBrush(brush());
QPolygonF arrow;
arrow.append(QPointF(0, -arrow_scale / 2));
arrow.append(QPointF(arrow_scale * 3 / 4, 0));
arrow.append(QPointF(0, arrow_scale / 2));
arrow.append(QPointF(-arrow_scale / 4, 0));
painter->save();
painter->rotate(arrow_angle);
painter->drawPolygon(arrow);
painter->restore();
painter->save();
painter->rotate(ellipse_rot);
painter->drawEllipse(QPointF(0, 0), ellipse_x, ellipse_y);
painter->setPen(QPen(Qt::red));
painter->drawPie(QRectF(-ellipse_x, -ellipse_y, 2 * ellipse_x, 2 * ellipse_y), 0, 0);
painter->setPen(QPen(Qt::green));
painter->drawPie(QRectF(-ellipse_x, -ellipse_y, 2 * ellipse_x, 2 * ellipse_y), 90 * 16, 0);
painter->setPen(QPen(Qt::blue));
double angle = arrow_angle - ellipse_rot;
painter->drawPie(QRectF(-ellipse_x, -ellipse_y, 2 * ellipse_x, 2 * ellipse_y), -(angle)*16, 0);
painter->restore();
}
QRectF EllipseItem::boundingRect() const
{
double mx = std::max(ellipse_x, std::max(ellipse_y, arrow_scale * 3 / 4));
return QRectF(-mx, -mx, 2 * mx, 2 * mx);
}
Моя проблема в том, что, когда я поворачиваюсь вокруг своей стрелки, линия, которую я рисую на эллипсе, совпадает только тогда, когда стрелка совмещена с осью эллипса (либо x
, либо у), как вы можете видеть на приложенных изображениях , Есть идеи, что я делаю не так?
В этом репо содержится минимально полный проверяемый пример.
На следующих изображениях показаны 5 основных параметров:
- Угол стрелки (град): это поворот стрелки от оси x в градусах с положительным направлением по часовой стрелке
- Эллипс x: размер радиусов x эллипса
- Ellipse y: размерность радиусов y эллипса
- Ellipse rot: вращение эллипса от оси x в градусах с положительным направлением по часовой стрелке
- Масштаб: масштаб нарисованной стрелки.
На изображении выше показана стрелка, указывающая вправо под углом 0, и направление y (зеленая линия) эллипса, направленное вверх под углом 90, указывающее, что эллипс имеет вращение 0. Синяя линия и наконечник стрелки совпадают , Желаемое поведение.
На изображении выше показана стрелка, указывающая «юго-восток» под углом 45 градусов, и направление x (красная линия) эллипса, направленное вправо на угол 0 (эллипс не вращается). Синяя линия не совпадает с наконечником стрелки, хотя она была нарисована под тем же углом, который использовался для рисования стрелки. Не желаемое поведение.
На изображении выше показана стрелка, указывающая «юг-юго-восток» под углом 80 градусов, и направление х (красная линия) эллипса, направленное вправо на угол 0 (эллипс не вращается). Синяя линия не совпадает с наконечником стрелки, хотя она была нарисована под тем же углом, который использовался для рисования стрелки. Не желаемое поведение.
На изображении выше показана стрелка, указывающая «на юг» под углом 90 градусов, и направление x (красная линия) эллипса, направленное вправо на угол 0 (эллипс не вращается). Синяя линия совпадает с наконечником стрелки. Желаемое поведение.
На изображении выше показана стрелка, указывающая «восток-юго-восток» под углом 20 градусов, и направление х (красная линия) эллипса, направленное вправо на угол 0 (эллипс не вращается). Синяя линия не совпадает с наконечником стрелки, хотя она была нарисована под тем же углом, который использовался для рисования стрелки. Не желаемое поведение.
На изображении выше показана стрелка, указывающая «восток-юго-восток» под углом 20 градусов, и направление x (красная линия) эллипса, указывающее «восток-юго-восток» под углом 20 (эллипс повернут на 20 градусов). Синяя линия совпадает с наконечником стрелки. Желаемое поведение.
На изображении выше показана стрелка, указывающая «восток-юго-восток» под углом 20 градусов, и направление х (красная линия) эллипса, указывающее «юго-восток» под углом 60 (эллипс повернут на 60 градусов). Синяя линия не совпадает с наконечником стрелки. Не желаемое поведение.
На изображении выше показана стрелка, указывающая «восток-юго-восток» под углом 20 градусов, и направление х (красная линия) эллипса, указывающее «юго-восток» под углом 95 (эллипс повернут на 95 градусов).Синяя линия не совпадает с наконечником стрелки.Не желаемое поведение. На приведенном выше рисунке показана стрелка, указывающая «восток-юго-восток» под углом 20 градусов, и направление х (красная линия) эллипса, указывающее «юго-восток» под углом 110 (эллипсповорачивается на 110 градусов).Синяя линия совпадает с наконечником стрелки.Желаемое поведение.
Из этих изображений выглядит, как художник (после поворота для рисования) сначала рисует круг и линию, а затем масштабирует две оси, чтобы сделать его эллипсом.Это то, что делает угол синей линии не таким, как угол стрелки.