#include "arrowitem.h"
{
}
{
double penwidth = 3.0;
double radius = 5.0;
//Point which lies on line which indicates begining of the Arrow
// ---|>
QPointF onLine
= 19.0/20.0*(end
-start
)+start;
double width;
double height;
double top;
double left;
if((start.x() != end.x()) && (start.y() != end.y()))
{
double m = (end.y()-start.y())/(end.x()-start.x());
double mRect = -1/m;
double b = onLine.y()- mRect*onLine.x();
double c = qPow(mRect,2)+1.0;
double d = 2.0*b*mRect -2.0*onLine.x() -2.0*mRect*onLine.y();
double e = qPow(b,2) + qPow(onLine.x(),2) + qPow(onLine.y(),2) -2.0*b*onLine.y() -qPow(radius,2);
double xOne = (-d + qSqrt(d*d-4.0*c*e))/(2.0*c);
double yOne = xOne*mRect + b;
double xTwo = (-d - qSqrt(d*d-4.0*c*e))/(2.0*c);
double yTwo = xTwo*mRect + b;
double distanceX;
double distanceY;
//get width & left
if(start.x() < end.x())
{
if(pointOne.x() > pointTwo.x())
{
distanceX = pointOne.x();
}else{
distanceX = pointTwo.x();
}
if(end.x() > distanceX)
{
distanceX = end.x();
}
width = distanceX - start.x();
left = start.x();
}else{
if(pointOne.x() < pointTwo.x())
{
distanceX = pointOne.x();
}else{
distanceX = pointTwo.x();
}
if(end.x() < distanceX)
{
distanceX = end.x();
}
width = start.x() - distanceX;
left = distanceX;
}
//get height & top
if(start.y() > end.y())
{
if(pointOne.y() < pointTwo.y())
{
distanceY = pointOne.y();
}else{
distanceY = pointTwo.y();
}
if(end.y() < distanceY)
{
distanceY = end.y();
}
height = start.y() - distanceY;
top = distanceY;
}else{
if(pointOne.y() > pointTwo.y())
{
distanceY = pointOne.y();
}else{
distanceY = pointTwo.y();
}
if(end.y() > distanceY)
{
distanceY = end.y();
}
height = distanceY - start.y();
top = start.y();
}
}else{
if(start.x() == end.x())
{
pointOne
= QPointF(onLine.
x() + radius, onLine.
y());
pointTwo
= QPointF(onLine.
x() - radius, onLine.
y());
width = 2.0*radius;
left = pointTwo.x();
if(start.y() > end.y())
{
height = start.y()-end.y();
top = end.y();
}else{
height= end.y()-start.y();
top = start.y();
}
}else{
pointOne
= QPointF(onLine.
x(), onLine.
y() + radius
);
pointTwo
= QPointF(onLine.
x(), onLine.
y() - radius
);
height = 2.0*radius;
top = pointTwo.y();
if(start.x() < end.x())
{
left = start.x();
width = end.x()-start.x();
}else{
left = end.x();
width = start.x()-end.x();
}
}
}
triangle << pointOne << pointTwo << end << pointOne;
line.setPoints(start, end);
prepareGeometryChange();
rect
= QRectF(left
-penwidth
/2,top
-penwidth
/2,width
+ penwidth,height
+ penwidth
);
update();
}
QRectF ArrowItem
::boundingRect() const {
return rect;
}
{
painter
->setPen
(QPen(Qt
::black,
3, Qt
::SolidLine, Qt
::FlatCap, Qt
::RoundJoin));
painter->drawLine(line);
//painter->setBrush(QBrush(Qt::black));
painter->drawPolygon(triangle);
}
#include "arrowitem.h"
ArrowItem::ArrowItem(QGraphicsItem *parent)
:QGraphicsItem(parent)
{
}
void ArrowItem::changeLine(QPointF start, QPointF end)
{
double penwidth = 3.0;
double radius = 5.0;
//Point which lies on line which indicates begining of the Arrow
// ---|>
QPointF onLine = 19.0/20.0*(end-start)+start;
QPointF pointOne;
QPointF pointTwo;
double width;
double height;
double top;
double left;
if((start.x() != end.x()) && (start.y() != end.y()))
{
double m = (end.y()-start.y())/(end.x()-start.x());
double mRect = -1/m;
double b = onLine.y()- mRect*onLine.x();
double c = qPow(mRect,2)+1.0;
double d = 2.0*b*mRect -2.0*onLine.x() -2.0*mRect*onLine.y();
double e = qPow(b,2) + qPow(onLine.x(),2) + qPow(onLine.y(),2) -2.0*b*onLine.y() -qPow(radius,2);
double xOne = (-d + qSqrt(d*d-4.0*c*e))/(2.0*c);
double yOne = xOne*mRect + b;
double xTwo = (-d - qSqrt(d*d-4.0*c*e))/(2.0*c);
double yTwo = xTwo*mRect + b;
pointOne = QPointF(xOne,yOne);
pointTwo = QPointF(xTwo,yTwo);
double distanceX;
double distanceY;
//get width & left
if(start.x() < end.x())
{
if(pointOne.x() > pointTwo.x())
{
distanceX = pointOne.x();
}else{
distanceX = pointTwo.x();
}
if(end.x() > distanceX)
{
distanceX = end.x();
}
width = distanceX - start.x();
left = start.x();
}else{
if(pointOne.x() < pointTwo.x())
{
distanceX = pointOne.x();
}else{
distanceX = pointTwo.x();
}
if(end.x() < distanceX)
{
distanceX = end.x();
}
width = start.x() - distanceX;
left = distanceX;
}
//get height & top
if(start.y() > end.y())
{
if(pointOne.y() < pointTwo.y())
{
distanceY = pointOne.y();
}else{
distanceY = pointTwo.y();
}
if(end.y() < distanceY)
{
distanceY = end.y();
}
height = start.y() - distanceY;
top = distanceY;
}else{
if(pointOne.y() > pointTwo.y())
{
distanceY = pointOne.y();
}else{
distanceY = pointTwo.y();
}
if(end.y() > distanceY)
{
distanceY = end.y();
}
height = distanceY - start.y();
top = start.y();
}
}else{
if(start.x() == end.x())
{
pointOne = QPointF(onLine.x() + radius, onLine.y());
pointTwo = QPointF(onLine.x() - radius, onLine.y());
width = 2.0*radius;
left = pointTwo.x();
if(start.y() > end.y())
{
height = start.y()-end.y();
top = end.y();
}else{
height= end.y()-start.y();
top = start.y();
}
}else{
pointOne = QPointF(onLine.x(), onLine.y() + radius);
pointTwo = QPointF(onLine.x(), onLine.y() - radius);
height = 2.0*radius;
top = pointTwo.y();
if(start.x() < end.x())
{
left = start.x();
width = end.x()-start.x();
}else{
left = end.x();
width = start.x()-end.x();
}
}
}
triangle << pointOne << pointTwo << end << pointOne;
line.setPoints(start, end);
prepareGeometryChange();
rect = QRectF(left -penwidth/2,top -penwidth/2,width + penwidth,height + penwidth);
update();
}
QRectF ArrowItem::boundingRect() const
{
return rect;
}
void ArrowItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *)
{
painter->setPen(QPen(Qt::black, 3, Qt::SolidLine, Qt::FlatCap, Qt::RoundJoin));
painter->drawLine(line);
//painter->setBrush(QBrush(Qt::black));
painter->drawPolygon(triangle);
}
To copy to clipboard, switch view to plain text mode
That shouldn't make a difference but I'm using the Item as a child of a bigger item.
Bookmarks