QGraphicsView: Snake-Line и Line анимация - PullRequest
1 голос
/ 13 сентября 2011

У меня есть два вопроса относительно QGraphicsView Framework .

Первый вопрос касается специальной линии: я хотел спросить, можно ли нарисовать Snake- или Wave-Line (как на связанном изображении)? Я был бы благодарен за любое решение, потому что я не имею ни малейшего представления, как получить синусоидальную линию.

Изображение: линия змеи

Мой второй вопрос о QGraphicsItemAnimation - я хочу оживить QGraphicsLineItem. Прямо сейчас я использую метод setPosAt() из QGraphicsItemAnimation. Проблема в том, что линия отверстия сдвинута. Моя цель - переместить только начало или конечную точку из QGraphicsLineItem с помощью QGraphicsItemAnimation. Поэтому я хочу спросить, возможно ли это или есть какой-то другой способ сделать что-то подобное?

Заранее спасибо!

С уважением - PhiGamma

Ответы [ 2 ]

1 голос
/ 14 сентября 2011

Для первой части вашего вопроса: Вероятно, двумя способами:

а. Используйте QPainterPath и метод cubicTo() для создания «пути», затем используйте QGraphicsPath с созданным вами путем. Чтобы сделать это, вам нужно аппроксимировать синусоидальные волны, используя кривые Безье. Некоторая информация об этом здесь , и документация QPainterPath здесь

б. Подкласс QGraphicsItem() и переопределите событие paint(), чтобы нарисовать свой путь, используя QPainter.

Sinewave::Sinewave( QGraphicsItem* pParent ) : QGraphicsObject( pParent)
{
    m_bounds = QRectF(0,0,150,100);
}

QRectF Sinewave::boundingRect() const
{
    return m_bounds;
}

void Sinewave::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
    unsigned int i;
    QPointF last(0,50);
    const int numberOfCycles = 4.0;
    painter->setRenderHint(QPainter::Antialiasing);

    for (int i = 0; i < boundingRect().width(); i++)
    {
        double radians = numberOfCycles * 2.0 * PI * static_cast<double>(i) / boundingRect().width();
        double y = sin(radians);
        QPointF next(i, 50 + y*50);
        painter->drawLine(last, next);
        last = next;
    }
}

Какой из них вы будете использовать, зависит от того, что вы хотите, чтобы объект делал (например, вам нужно изменить его форму во время выполнения?).

На ваш вопрос об анимации - нет, вы можете применять преобразования только с QGraphcisItemAnimation. Я бы сделал это, используя QTimer, чтобы внести необходимые изменения в ваши элементы в слот timeout ().

1 голос
/ 14 сентября 2011

Попробуйте следующий алгоритм отображения синусоидальной волны:

const double PI = 3.14159267;
unsigned int i;
for (unsigned int i = 0; i < 400; ++i)
{
    double radians = static_cast<double>(i) / 100.0;
    double y = sin(radians);
    set_point(radians, y);
}

Добавив смещение к значению 'y', вы можете перемещать синусоидальную волну вверх или вниз.Добавление константы к «радианам» (или ординате X) переместит синусоидальную волну влево или вправо.

...