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<QPointF>
// 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 <QApplication>
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 <QMainWindow>
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = 0);
~MainWindow();
};
#endif // MAINWINDOW_H
mainwindow.cpp
#include "mainwindow.h"
#include <QGraphicsView>
#include <QGraphicsScene>
#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 <QGraphicsScene>
#include <QGraphicsSceneMouseEvent>
#include <QPointF>
#include <QList>
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 <QPointF> m_points;
};
#endif // GRAPHICSSCENE_H
graphicsscene.cpp
#include "graphicsscene.h"
#include <QDebug>
#include <QGraphicsEllipseItem>
#include <QGraphicsPathItem>
#include <QPainterPath>
#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);
}