2015-06-14 5 views
1

Мне нужно разместить объект верхнего уровня, чтобы он всегда оставался в позиции относительно другого объекта верхнего уровня. В качестве примера, прямоугольник в изображении ниже должны придерживаться «фронт» эллипса:Позиционирование объекта верхнего уровня относительно другого

correct positioning example

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

correct positioning example rotated 180 degrees

Вместо этого, положение прямоугольника неправильно:

incorrect positioning

Пожалуйста, запустите приведенный ниже пример (использование QGraphicsScene предназначено только для демонстрации, так как фактическое использование используется в физике).

#include <QtWidgets> 

class Scene : public QGraphicsScene 
{ 
    Q_OBJECT 
public: 
    Scene() 
    { 
     mEllipse = addEllipse(0, 0, 25, 25); 
     mEllipse->setTransformOriginPoint(QPointF(12.5, 12.5)); 

     QGraphicsLineItem *line = new QGraphicsLineItem(QLineF(0, 0, 0, -12.5), mEllipse); 
     line->setPos(12.5, 12.5); 

     mRect = addRect(0, 0, 10, 10); 
     mRect->setTransformOriginPoint(QPointF(5, 5)); 

     line = new QGraphicsLineItem(QLineF(0, 0, 0, -5), mRect); 
     line->setPos(5, 5); 

     connect(&mTimer, SIGNAL(timeout()), this, SLOT(timeout())); 
     mTimer.start(5); 
    } 

public slots: 
    void timeout() 
    { 
     mEllipse->setRotation(mEllipse->rotation() + 0.5); 

     QTransform t; 
     t.rotate(mEllipse->rotation()); 

     qreal relativeX = mEllipse->boundingRect().width()/2 - mRect->boundingRect().width()/2; 
     qreal relativeY = -mRect->boundingRect().height(); 

     mRect->setPos(mEllipse->pos() + t.map(QPointF(relativeX, relativeY))); 
     mRect->setRotation(mEllipse->rotation()); 
    } 

public: 
    QTimer mTimer; 
    QGraphicsEllipseItem *mEllipse; 
    QGraphicsRectItem *mRect; 
}; 

int main(int argc, char** argv) 
{ 
    QApplication app(argc, argv); 

    QGraphicsView view; 
    view.setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); 
    view.setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); 
    view.setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform); 
    view.setScene(new Scene); 
    view.resize(200, 200); 
    view.show(); 

    return app.exec(); 
} 

#include "main.moc" 

Обратите внимание, что положение прямоугольника не всегда то же самое, но она всегда должна оставаться в том же положении по отношению к эллипсу. Например, он может начать в этом положении:

alternative positioning example

Но он должен оставаться в этом относительном положении при повороте:

alternative positioning example rotated 180 degrees

ответ

2

Если вы хотите, чтобы два объекта, чтобы сохранить то же самое относительное положение, они должны вращаться вокруг одной и той же начальной точки.

Здесь ваш круг вращается вокруг его центра (точка 12.5, 12.5), но ваш прямоугольник вращается вокруг другого источника (5,5) вместо центра круга (12.5, 12.5).

Если зафиксировать происхождение, она будет работать, как вы ожидаете:

mRect->setTransformOriginPoint(QPointF(12.5, 12.5)); 

Даже если прямоугольник начинается со смещением:

mRect = addRect(-10, 0, 10, 10); // Start 10 units to the left 

Screenshot of the result

+0

Спасибо за быстрый ответ. Я упомянул в своем вопросе, что я не буду использовать 'QGraphicsScene' в фактическом коде. Мои объекты физики имеют положение и вращение, хотя это и действует. С учетом этого вы можете придумать решение, которое не использует 'setTransformOriginPoint()', и просто 'QPointF' /' QTransform' и т. Д.? Хороший GIF, кстати. Как вы сделали это? – Mitch

+0

Я не знаю, что ваш реальный код использует, поэтому я не уверен, какое решение вы хотите. Но [принцип тот же] (https://en.wikipedia.org/wiki/Rotation_%28mathematics%29#Two_dimensions), вам просто нужно делать ваши вращения вокруг одной и той же начальной точки. И gif сделан с [byzanz] (https://github.com/GNOME/byzanz). – tux3

+0

Я думал об одном и том же подходе просто без 'setTransformOriginPoint()'; пока решение работает только с 'position()' и 'rotation()', это достаточно общее для работы с моими физическими материалами. Если это невозможно, я, вероятно, смогу понять что-то, используя ваш ответ. – Mitch

Смежные вопросы