I want to implement arc in QGraphicsScene. I want that on clicking of three points my arc should be drawn such that on clicking of three points arc is drawn where first poin
This sounds like it could be solved with some relatively simple math:
https://www.google.com/search?q=define%20circle%20three%20points
https://math.stackexchange.com/a/213678
https://www.khanacademy.org/math/geometry/triangle-properties/perpendicular_bisectors/v/three-points-defining-a-circle
Here is my translation of the math into Qt goodness
// m_points is a QList
// use math to define the circle
QLineF lineBC(m_points.at(1), m_points.at(2));
QLineF lineAC(m_points.at(0), m_points.at(2));
QLineF lineBA(m_points.at(1), m_points.at(0));
qreal rad = qAbs(lineBC.length()/(2*qSin(qDegreesToRadians(lineAC.angleTo(lineBA)))));
QLineF bisectorBC(lineBC.pointAt(0.5), lineBC.p2());
bisectorBC.setAngle(lineBC.normalVector().angle());
QLineF bisectorBA(lineBA.pointAt(0.5), lineBA.p2());
bisectorBA.setAngle(lineBA.normalVector().angle());
QPointF center;
bisectorBA.intersect(bisectorBC, ¢er);
qDebug() << rad << center;
QT QGraphicsScene Drawing Arc
QPainterPath* path = new QPainterPath();
path->arcMoveTo(0,0,50,50,20);
path->arcTo(0,0,50,50,20, 90);
scene.addPath(*path);
Putting all of this together into a nice little project turns into this:
https://github.com/peteristhegreat/ThreePointsCircle

main.cpp
#include "mainwindow.h"
#include
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = 0);
~MainWindow();
};
#endif // MAINWINDOW_H
mainwindow.cpp
#include "mainwindow.h"
#include
#include
#include "graphicsscene.h"
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
QGraphicsView * view = new QGraphicsView;
GraphicsScene * scene = new GraphicsScene();
view->setScene(scene);
view->setSceneRect(-300,-300, 300, 300);
this->resize(600, 600);
this->setCentralWidget(view);
}
MainWindow::~MainWindow()
{
}
graphicsscene.h
#ifndef GRAPHICSSCENE_H
#define GRAPHICSSCENE_H
#include
#include
#include
#include
class GraphicsScene : public QGraphicsScene
{
Q_OBJECT
public:
explicit GraphicsScene(QObject *parent = 0);
virtual void mouseDoubleClickEvent(QGraphicsSceneMouseEvent * mouseEvent);
virtual void mouseMoveEvent(QGraphicsSceneMouseEvent * mouseEvent);
virtual void mousePressEvent(QGraphicsSceneMouseEvent * mouseEvent);
virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent * mouseEvent);
signals:
public slots:
private:
QList m_points;
};
#endif // GRAPHICSSCENE_H
graphicsscene.cpp
#include "graphicsscene.h"
#include
#include
#include
#include
#include "qmath.h"
GraphicsScene::GraphicsScene(QObject *parent) :
QGraphicsScene(parent)
{
this->setBackgroundBrush(Qt::gray);
}
void GraphicsScene::mouseDoubleClickEvent(QGraphicsSceneMouseEvent * mouseEvent)
{
qDebug() << Q_FUNC_INFO << mouseEvent->scenePos();
QGraphicsScene::mouseDoubleClickEvent(mouseEvent);
}
void GraphicsScene::mouseMoveEvent(QGraphicsSceneMouseEvent * mouseEvent)
{
qDebug() << Q_FUNC_INFO << mouseEvent->scenePos();
QGraphicsScene::mouseMoveEvent(mouseEvent);
}
void GraphicsScene::mousePressEvent(QGraphicsSceneMouseEvent * mouseEvent)
{
qDebug() << Q_FUNC_INFO << mouseEvent->scenePos();
QGraphicsScene::mousePressEvent(mouseEvent);
}
void GraphicsScene::mouseReleaseEvent(QGraphicsSceneMouseEvent * me)
{
qDebug() << Q_FUNC_INFO << me->scenePos();
int radius = 20;
QGraphicsEllipseItem * ellipse = this->addEllipse(me->scenePos().x() - radius, me->scenePos().y() - radius, radius*2, radius*2);
ellipse->setBrush(Qt::white);
m_points.append(me->scenePos());
if(m_points.size() == 3)
{
// use math to define the circle
QLineF lineBC(m_points.at(1), m_points.at(2));
QLineF lineAC(m_points.at(0), m_points.at(2));
QLineF lineBA(m_points.at(1), m_points.at(0));
qreal rad = qAbs(lineBC.length()/(2*qSin(qDegreesToRadians(lineAC.angleTo(lineBA)))));
QLineF bisectorBC(lineBC.pointAt(0.5), lineBC.p2());
bisectorBC.setAngle(lineBC.normalVector().angle());
QLineF bisectorBA(lineBA.pointAt(0.5), lineBA.p2());
bisectorBA.setAngle(lineBA.normalVector().angle());
QPointF center;
bisectorBA.intersect(bisectorBC, ¢er);
qDebug() << rad << center;
bool drawCircle = true;
QGraphicsEllipseItem * ellipse = new QGraphicsEllipseItem(center.x() - rad, center.y() - rad, rad*2, rad*2);
if(drawCircle)
this->addItem(ellipse);
// add arc
// this->addItem(path);
QPainterPath path;
QLineF lineOA(center, m_points.at(0));
QLineF lineOC(center, m_points.at(2));
path.arcMoveTo(ellipse->boundingRect(),lineOA.angle());
path.arcTo(ellipse->boundingRect(), lineOA.angle(), lineOC.angle() - lineOA.angle());
QGraphicsPathItem * pathItem = new QGraphicsPathItem(path);
pathItem->setPen(QPen(Qt::red,10));
this->addItem(pathItem);
if(!drawCircle)
delete ellipse;
m_points.clear();
}
QGraphicsScene::mouseReleaseEvent(me);
}