Circle.cc 4.54 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14
#include "Circle.h"



Circle::Circle(QObject *parent)
    :   QObject (parent)
    ,   _circleRadius(0)
    ,   _circleOrigin(QPointF(0,0))
{

}

Circle::Circle(double radius, QObject *parent)
    :   QObject (parent)
15
    ,   _circleRadius(radius >= 0 ? radius : 0)
16 17 18 19 20 21
    ,   _circleOrigin(QPointF(0,0))
{
}

Circle::Circle(double radius, QPointF origin, QObject *parent)
    :   QObject (parent)
22
    ,   _circleRadius(radius >= 0 ? radius : 0)
23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90
    ,   _circleOrigin(origin)
{
}

Circle::Circle(const Circle &other, QObject *parent)
    :   QObject (parent)
{
    *this = other;
}

Circle &Circle::operator=(const Circle &other)
{
    this->setRadius(other.radius());
    this->setOrigin(other.origin());

    return *this;
}

/*!
 * \fn void Circle::setRadius(double radius)
 * Sets the radius of the circle to \a radius
 */
void Circle::setRadius(double radius)
{
    if ( radius >= 0 && !qFuzzyCompare(_circleRadius, radius) ) {
        _circleRadius = radius;

        emit radiusChanged(_circleRadius);
    }
}

/*!
 * \fn void Circle::setOrigin(const QPointF &origin)
 * Sets the origin of the circle to \a origin
 *
 * \sa QPointF
 */
void Circle::setOrigin(const QPointF &origin)
{
    if (origin != _circleOrigin) {
        _circleOrigin = origin;

        emit originChanged(_circleOrigin);
    }
}

/*!
 * \fn double Circle::radius() const
 * Returns the radius of the circle.
 */
double Circle::radius() const
{
    return _circleRadius;
}

/*!
 * \fn QPointF Circle::origin() const
 * Returns the origin of the circle.
 *
 * \sa QPointF
 */
QPointF Circle::origin() const
{
    return _circleOrigin;
}


/*!
91
 * \fn QVector<QPointF> Circle::approximate(int numberOfCorners)
92 93 94 95
 * Returns a polygon with \a numberOfCorners corners which approximates the circle.
 *
 * \sa QPointF
 */
96
QVector<QPointF> Circle::approximate(int numberOfCorners) const
97 98
{
    if ( numberOfCorners < 3)
99
        return QVector<QPointF>();
100
    return approximateSektor(numberOfCorners+1, 0, 2*M_PI);
101 102
}

103
QVector<QPointF> Circle::approximate(double angleDiscretisation) const
104 105 106 107
{
    return approximateSektor(angleDiscretisation, 0, 2*M_PI);
}

108
QVector<QPointF> Circle::approximateSektor(int numberOfCorners, double alpha1, double alpha2) const
109
{
110 111
    if ( numberOfCorners < 2) {
        qWarning("numberOfCorners < 2");
112
        return QVector<QPointF>();
113 114
    }
    return approximateSektor(PlanimetryCalculus::truncateAngle(alpha2-alpha1)/double(numberOfCorners-1), alpha1, alpha2);
115 116
}

117
QVector<QPointF> Circle::approximateSektor(double angleDiscretisation, double alpha1, double alpha2) const
118
{
119
    using namespace PlanimetryCalculus;
120 121
    // check if input is valid
    if ( qFuzzyCompare(alpha1, alpha2) )
122
        return QVector<QPointF>();
123 124 125 126 127 128 129

    alpha1 = truncateAngle(alpha1);
    alpha2 = truncateAngle(alpha2);
    double deltaAlpha = fabs(alpha1 - alpha2);
    if (signum(angleDiscretisation*(alpha1 - alpha2)) == 1) {
        deltaAlpha = 2*M_PI - deltaAlpha;
    }
130

131
    // check if input is valid
132
    if (  qFuzzyIsNull(angleDiscretisation))
133
        return QVector<QPointF>();
134 135


136
    QVector<QPointF> sector;
137
    double currentAngle = alpha1;
138 139 140
    // how many nodes?
    int j = floor(fabs(deltaAlpha/angleDiscretisation));
    // rotate the vertex j+1 times add the origin and append to the sector.
141
    do {
142 143 144
        sector.append(toCoordinate(currentAngle));
        currentAngle = truncateAngle(currentAngle + angleDiscretisation);
    }while(j--);
145 146

    // append last point if necessarry
147 148 149 150
    QPointF vertex = toCoordinate(alpha2);
    if (   !qFuzzyIsNull(PlanimetryCalculus::distance(sector.first(), vertex))
        && !qFuzzyIsNull(PlanimetryCalculus::distance(sector.last(), vertex )) ){
        sector.append(vertex);
151 152
    }

153
    return sector;
154 155
}

156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183
/*!
 * \fn void Circle::toCoordinate(QPointF &coordinate, double alpha) const
 * Calculates the coordinates of a point on the circle with angle \a alpha.
 * Stores the result in \a coordiante.
 *
 * \sa QPointF
 */
void Circle::toCoordinate(QPointF &coordinate, double alpha) const
{
    using namespace PlanimetryCalculus;
    coordinate = QPointF(_circleRadius,0);
    rotateReference(coordinate, alpha);
    coordinate += _circleOrigin;
}

/*!
 * \overload QPointF Circle::toCoordinate(double alpha) const
 * Returns the coordinates of a point on the circle with angle \a alpha.
 *
 * \sa QPointF
 */
QPointF Circle::toCoordinate(double alpha) const
{
    QPointF coordinate;
    toCoordinate(coordinate, alpha);
    return coordinate;
}

184 185 186 187 188
bool Circle::isNull() const
{
    return _circleRadius <= 0 ? true : false;
}

189 190 191 192 193 194
/*!
 * \class Circle
 * \brief Provies a circle with radius and origin.
 *
 * \sa QPointF
 */