как получить конечную точку переведенного QPolygon

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

http://doc.qt.io/qt-5/qtwidgets-graphicsview-elasticnodes-edge-cpp.html

Я решил рисовать по той же формуле и попробовал так:

theCurrentLine->setP1(QPointF(0, 0)  );
theCurrentLine->setP2((theLineVector));
p->drawLine(*theCurrentLine);

double angle = ::acos(theCurrentLine->dx() / theCurrentLine->length());
if (theCurrentLine->dy() >= 0)
    angle = TwoPi - angle;

QPointF sourcePoint = QPointF(0,0);

QPointF sourceArrowP1 = sourcePoint + QPointF(sin(angle + Pi / 3) * theArrowSize,
                                              cos(angle + Pi / 3) * theArrowSize);
QPointF sourceArrowP2 = sourcePoint + QPointF(sin(angle + Pi - Pi / 3) * theArrowSize,
                                              cos(angle + Pi - Pi / 3) * theArrowSize);

p->drawPolygon(QPolygonF() << theCurrentLine->p1() << sourceArrowP1 << sourceArrowP2);

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

Как я могу изменить значение P1() для theCurrentLine, которое может начинаться после многоугольника, поскольку в настоящее время polygon(arrowHead) и линия начинаются в одной и той же точке? Мне нужно начать линию после того, как нарисован наконечник стрелки. Причина в том, что иногда при увеличении ширины пера наконечник стрелки выглядит меньше, чем линия.


person Wagmare    schedule 05.02.2015    source источник


Ответы (2)


Вы можете получить точку по индексу в QPolygon.

 QPoint QPolygon::point ( int index ) const

Было бы легко, если бы вы знали, сколько очков есть. А документация Qt — ваш друг.

И вы можете использовать count(), например:

 QPoint lastPoint = myPolygon.point(myPolygon.count() - 1);

Просто дайте имя своему полигону, и все будет в порядке.

Изменить: Последняя версия этих кодов должна решить вашу проблему. Я подумал, что мне нужно привести пример. Вам нужно добавить точки в следующем порядке:

 QPolygon myPolygon;
 myPolygon.setPoint(0, sourceArrowP1);
 myPolygon.setPoint(1, theCurrentLine->p1());
 myPolygon.setPoint(2, sourceArrowP2);
 p->drawPolygon(myPolygon);
 QPoint lastPoint;
 lastPoint = myPolygon.point(myPolygon.count() - 1);

Вам нужно провести линию между последней и первой точками. Здесь:

 p->drawLine(myPolygon.point(0, myPolygon.point(myPolygon.count() - 1));

Если вы хотите, чтобы ваша стрелка была заполнена цветом, вам нужно использовать QPainterPath вместо QPolygon:

 QPen pen(Qt::black); //Or whatever color you want
 pen.setWidthF(10); //Or whatever size you want your lines to be
 QBrush brush(Qt::red); //Or whatever color you want to fill the arrow head
 p->setPen(pen);
 p->setBrush(brush);
 QPainterPath arrow(sourceArrowP1);
 arrow.lineTo(theCurrentLine->p1());
 arrow.lineTo(sourceArrowP2);
 arrow.lineTo(sourceArrowP1); //This returns to the first point. You might eliminate this line if you want to.
 p->drawPath(arrow);
person Community    schedule 06.02.2015
comment
Спасибо за полезный пост . у меня есть еще одна задача. мне нужно провести линию между последней точкой и предыдущей до последней точки. как середина наконечника стрелки. - person Wagmare; 06.02.2015
comment
@Wagmare Нет проблем. Просто не забывайте часто просматривать документацию Qt для получения ответов. Это лучшая документация, которую я видел. - person ; 06.02.2015

Моя фактическая реализация:

theCurrentLine->setP1(QPointF(0, 0)  );  // arrow line coordinates
theCurrentLine->setP2((theLineVector));
double angle = ::acos(theCurrentLine->dx() / theCurrentLine->length());  // angle of the current Line
if (theCurrentLine->dy() >= 0)
    angle = TwoPi - angle;

// getting arrow head points to be drawn
QPointF sourcePoint = QPointF(0,0);

QPointF sourceArrowP1 = sourcePoint + QPointF(sin(angle + Pi / 3) * theArrowSize,
                                              cos(angle + Pi / 3) * theArrowSize);
QPointF sourceArrowP2 = sourcePoint + QPointF(sin(angle + Pi - Pi / 3) * theArrowSize,
                                              cos(angle + Pi - Pi / 3) * theArrowSize);

p->drawPolygon(QPolygonF() << theCurrentLine->p1() << sourceArrowP1 << sourceArrowP2);

// to find the center point in the arrow head right
QLineF perpLine = QLineF(theCurrentLine->p1(), theCurrentLine->p2());
QLineF arrowheadWidth = QLineF(sourceArrowP1, sourceArrowP2);

QPointF originPoint;
QLineF::IntersectType res = perpLine.intersect(arrowheadWidth, &originPoint);

theCurrentLine->setP1(originPoint);
p->drawLine(*theCurrentLine);

Если кто-нибудь знает гораздо лучший способ реализовать это (я уверен, что он будет), пожалуйста, поправьте меня.

person Wagmare    schedule 06.02.2015
comment
Я отредактировал свой ответ, чтобы ответить на ваш комментарий, но я думаю, вы его не видели. - person ; 06.02.2015
comment
Проблема с моим ответом в том, что я добавил очки в указанном вами порядке. Что мне нужно сделать, так это добавить currentLine->p1() в качестве второй точки. Тогда мой ответ будет применим к вашей ситуации. Я отредактирую первый код. - person ; 06.02.2015
comment
Смотрите мой ответ сейчас и, пожалуйста, прокомментируйте, если есть проблема. - person ; 06.02.2015
comment
Я также добавил пример с QPainterPath. Возможно, вы захотите проверить это. - person ; 06.02.2015