Reputation: 199
I am doing a program to draw an arc and move/rotate it according to the position of the mouse cursor :
This image illustrates the scene when the program is first run. The following images illustrates what is displayed after a mouse click. The mouse click happened at the top right point of the line.
After getting the coordinates of the intersection point (between the line and the circle), I want to set the position of the center of the arc to the intersection point. But, as you can see, the arc is not where I wish it was. Strangely, when I draw a rectangle whose topLeft point is at the intersection point, it works :
I guess the problem has to be with scene/parent/item coordinates... But I can't find where :/
Here is a sample of the code : (DrawingScene inherits QGraphicsScene)
void DrawingScene::drawStates(){
m_ellipse = new QGraphicsEllipseItem(80.0, 80.0,120.0,120.0);
addItem(m_ellipse);
m_arc = new GraphicArcItem(62.0, 62.0,50.0,50.0);
m_arc->setParentItem(m_ellipse);
m_arc->setStartAngle(0);
m_arc->setSpanAngle(270 * 16);
QLineF line_vertical(140.0,80.0,140.0,200.0);
addLine(line_vertical);
QLineF line_horizontal(80.0,140.0,200.0,140.0);
addLine(line_horizontal);
QLineF line(QPointF(62.0,62.0), QPointF(140.0,140.0));
m_lineToCenter = new QGraphicsLineItem(line);
addItem(m_lineToCenter);
}
void DrawingScene::mousePressEvent(QGraphicsSceneMouseEvent *event){
p1 = event->scenePos();
QLineF lineToCenter(QPointF(140.0,140.0), p1);
m_lineToCenter->setLine(lineToCenter);
QLineF horizontalLine(QPointF(140.0,140.0),QPointF(200.0,140.0));
double angleBetweenLines = horizontalLine.angleTo(lineToCenter);
double x = 60.0 * cos(angleBetweenLines * 3.14 / 180.0);
double y = -60.0 * sin(angleBetweenLines * 3.14 / 180.0);
QPointF intersectionPoint(x,y);
QPointF topLeft = intersectionPoint + QPointF(140.0,140.0);
addRect(QRectF(topLeft, QSizeF(60.0,60.0)));
m_arc->setPos(topLeft);
}
Any help would be more than welcome :)
edit : Working code for moving the arc :
p1 = event->scenePos();
QLineF lineToCenter(QPointF(140.0,140.0), p1);//center of circle to mouse position
double angleBetweenPositions = lineToCenter.angleTo(m_lineToCenter->line());
m_lineToCenter->setLine(lineToCenter);
QLineF horizontalLine(QPointF(140.0,140.0),QPointF(200.0,140.0));
double angleBetweenLines = horizontalLine.angleTo(lineToCenter);
double x = 60.0 * cos(angleBetweenLines * 3.14 / 180.0);
double y = -60.0 * sin(angleBetweenLines * 3.14 / 180.0);
QPointF newPoint(x,y);
QPointF ellipse_center = m_ellipse->rect().center();
QPointF intersection_point = intersection_point + ellipse_center;
GraphicArcItem *arc2 = new GraphicArcItem(intersection_point.rx()- 25.0,
intersection_point.ry() - 25.0,50.0,50.0);
addItem(arc2);
m_arc->setPos(intersection_point.rx()-85.0, intersection_point.ry() - 85.0);//why 85 ??
Code for the rotation :
m_arc->setCurrentRotation(m_arc->getCurrentRotation() + angleBetweenPositions);
m_arc->setTransformOriginPoint(m_arc->getCenter());
m_arc->setRotation(m_arc->getCurrentRotation());
Edit : Here are the key parts of the code solving the problem :
/*Return the center point of the arc in the parent coordinates*/
QPointF GraphicArcItem::getCenter(){
int xCenter = rect().x() + rect().width()/2;
int yCenter = rect().y() + rect().height()/2;
QPointF center = /*mapToParent(*/QPointF(xCenter,yCenter)/*)*/;
return center;
}
p1 = event->scenePos();
QPointF ellipse_center = m_ellipse->rect().center();
QLineF lineToCenter(ellipse_center, p1);//center of circle to mouse position
double angleBetweenPositions = lineToCenter.angleTo(m_lineToCenter->line());
QLineF horizontalLine(ellipse_center,QPointF(200.0,140.0));
double angleBetweenLines = horizontalLine.angleTo(lineToCenter);
double x = 60.0 * cos(angleBetweenLines * 3.14 / 180.0);
double y = -60.0 * sin(angleBetweenLines * 3.14 / 180.0);
QPointF newPoint(x,y);
QPointF intersection_point = newPoint + ellipse_center;
m_arc->setPos(intersection_point.rx() - 85.0, intersection_point.ry() - 85.0);
m_arc->setCurrentRotation(angleBetweenPositions);
QPointF rotation_center = m_arc->mapFromItem(m_arc, m_arc->getCenter());
m_arc->setTransformOriginPoint(rotation_center);
m_arc->setRotation(m_arc->getCurrentRotation());
Upvotes: 2
Views: 271
Reputation: 8419
The rectangle and the arc have different parents (the scene is the parent of the rectangle and m_ellipse
of the arc, hence the references of their coordinates are different. To test it just add a new arc/circle (different from m_arc
and without using setParentItem(m_ellipse);
) to the scene - it should have the correct screen position. To achieve the desired result I would suggest you to play with mapTo<something>
/mapFrom<something>
methods. I presume that mapToParent will do the trick, but you should check it anyway.
Upvotes: 1