2

I want to draw an arc between two points. I know position of the two points and the angle in radians. I succeeded to wrote a little program to calculate the centre of the circle before to effective draw the arc. But when I draw a circle to verify, when I use small values for radians, the circle line do not cross the two points given.

#include <QApplication>
#include <QGraphicsEllipseItem>
#include <QGraphicsScene>
#include <QGraphicsView>
#include <QDebug>
#include <cmath>
#include <QPainter>

void cross(QPainterPath* path, double x, double y);

int main( int argc, char **argv )
{
    QApplication app(argc, argv);
    QGraphicsScene scene;
    scene.setSceneRect( 0.0, 0.0, 500.0, 500.0 );
    QPainterPath* path = new QPainterPath();

    double x1, x2, y1, y2, l, rad, r;
    double x3, y3, xx, yy;
    const double PI = 3.14159265358979323846;

    //first point
    x1=250;
    y1=250;
    //second point
    x2=350;
    y2=300;
    //radians - play with it. This is low value - this is buggy
    rad=0.002;

    l=sqrt (pow((x1-x2),2) + pow((y1-y2),2)); //distance between (x1,y) and (x2,y2)
    u=180.0 * rad / PI; //transform radians in angle
    r=(l/2.0)/sin(rad/2.0); //this is radius

    //point in the middle of (x1,y) and (x2,y2)... half of l
    x3 = (x1+x2)/2;
    y3 = (y1+y2)/2;

    //find center of circle
    if(rad>0){
        xx = x3 + sqrt(pow(r,2)-pow((l/2),2))*(y1-y2)/l;
        yy = y3 + sqrt(pow(r,2)-pow((l/2),2))*(x2-x1)/l;
    }else{
        xx = x3 - sqrt(pow(r,2)-pow((l/2),2))*(y1-y2)/l;
        yy = y3 - sqrt(pow(r,2)-pow((l/2),2))*(x2-x1)/l;
    }


    //draw circle to verify
    path->moveTo(xx, yy);
    path->addEllipse(QRectF(xx-r,yy-r,r*2,r*2));

    cross(path, x3,y3);
    cross(path, xx,yy);
    cross(path, x1,y1);
    cross(path, x2,y2);


    qDebug() << "r =" << r << " xx =" << xx << " yy =" << yy ;
    qDebug() << "Verify r - distance from (x1,y1) to center of circle" << sqrt (pow((x1-xx),2) + pow((y1-yy),2));
    qDebug() << "Verify r - distance from (x2,y2) to center of circle" << sqrt (pow((x2-xx),2) + pow((y2-yy),2));

    scene.addPath(*path);

    QGraphicsView view( &scene );
    view.show();
    return app.exec();
}

void cross(QPainterPath* path, double x, double y){
    path->moveTo(x, y-5);
    path->lineTo(x, y+5);
    path->moveTo(x-5, y);
    path->lineTo(x+5, y);
}

radians = 1.0 radians = 0.002

However, the distance from the two points to the circle center is equal to the calculated radius. where am I wrong?

Junior
  • 507
  • 5
  • 19
  • Just an aside: a more convenient way to compute cartesian distance between 2 points `(x1,y1)` and `(x2,y2)` is via [`std::hypot`](http://en.cppreference.com/w/cpp/numeric/math/hypot) - in this case `std::hypot(x2-x1, y2-y1)`. – sjrowlinson Aug 22 '16 at 17:08

1 Answers1

0

I know this post is old, but since it's been viewed 1K times and not been answered I thought I'd weigh in.

I believe the draw ellipse function in QT is using 4 bezier curves to create the shape. There is no perfect way to represent a circle using bezier curves, instead you need to aim for the closest approximation you can get.

For my purposes, I found this bezier curve circle approximation Stack Overflow post incredibly helpful. The solution I settled on was to approximate the circle with a high quantity of arcs starting at the point itself to guarantee that my circle appeared to go through it.

Another option is to write your own bresenham's circle drawing function using the QT painter "drawPoint" function to put the individual pixels. I found that this solution was too slow at increasing zoom levels in my QT app, however, it was incredibly accurate.

Hopefully this helps someone next time this crops up.

Ben
  • 116
  • 1
  • 7