QBezier Class Reference

#include <qbezier_p.h>

List of all members.


Detailed Description

Definition at line 44 of file qbezier_p.h.

Public Member Functions

QPointF pointAt (qreal t) const
QPointF normalVector (qreal t) const
QPolygonF toPolygon () const
void addToPolygon (QPolygonF *p) const
QRectF bounds () const
QPointF pt1 () const
QPointF pt2 () const
QPointF pt3 () const
QPointF pt4 () const
QPointF midPoint () const
QLineF midTangent () const
void split (QBezier *firstHalf, QBezier *secondHalf) const
int shifted (QBezier *curveSegments, int maxSegmets, qreal offset, float threshold) const

Static Public Member Functions

static QBezier fromPoints (const QPointF &p1, const QPointF &p2, const QPointF &p3, const QPointF &p4)

Public Attributes

qreal x1
qreal y1
qreal x2
qreal y2
qreal x3
qreal y3
qreal x4
qreal y4


Member Function Documentation

QBezier QBezier::fromPoints ( const QPointF p1,
const QPointF p2,
const QPointF p3,
const QPointF p4 
) [static]

Definition at line 34 of file qbezier.cpp.

References b, QPointF::x(), and QPointF::y().

Referenced by QPainterPath::boundingRect(), QPainterPath::contains(), Q3PointArray::cubicBezier(), QOpenGLPaintEnginePrivate::curveTo(), QSubpathFlatIterator::next(), qt_painterpath_check_crossing(), qt_stroke_side(), shift(), and QPainterPath::toSubpathPolygons().

00035 {
00036     QBezier b;
00037     b.x1 = p1.x();
00038     b.y1 = p1.y();
00039     b.x2 = p2.x();
00040     b.y2 = p2.y();
00041     b.x3 = p3.x();
00042     b.y3 = p3.y();
00043     b.x4 = p4.x();
00044     b.y4 = p4.y();
00045     return b;
00046 }

Here is the call graph for this function:

QPointF QBezier::pointAt ( qreal  t  )  const [inline]

Definition at line 83 of file qbezier_p.h.

References a, b, c, d, x, x1, x2, x3, x4, y, y1, y2, y3, and y4.

Referenced by good_offset(), and midTangent().

00084 {
00085     Q_ASSERT(t >= 0);
00086     Q_ASSERT(t <= 1);
00087 #if 1
00088     qreal a, b, c, d;
00089     qreal m_t = 1. - t;
00090     b = m_t * m_t;
00091     c = t * t;
00092     d = c * t;
00093     a = b * m_t;
00094     b *= 3. * t;
00095     c *= 3. * m_t;
00096 
00097     return QPointF(a*x1 + b*x2 + c*x3 + d*x4, a*y1 + b*y2 + c*y3 + d*y4);
00098 #else
00099     // numerically more stable:
00100     qreal m_t = 1. - t;
00101     qreal a = x1*m_t + x2*t;
00102     qreal b = x2*m_t + x3*t;
00103     qreal c = x3*m_t + x4*t;
00104     a = a*m_t + b*t;
00105     b = b*m_t + c*t;
00106     qreal x = a*m_t + b*t;
00107     qreal a = y1*m_t + y2*t;
00108     qreal b = y2*m_t + y3*t;
00109     qreal c = y3*m_t + y4*t;
00110     a = a*m_t + b*t;
00111     b = b*m_t + c*t;
00112     qreal y = a*m_t + b*t;
00113     return QPointF(x, y);
00114 #endif
00115 }

QPointF QBezier::normalVector ( qreal  t  )  const [inline]

Definition at line 117 of file qbezier_p.h.

References a, b, c, x1, x2, x3, x4, y1, y2, y3, and y4.

Referenced by good_offset().

00118 {
00119     qreal m_t = 1. - t;
00120     qreal a = m_t * m_t;
00121     qreal b = t * m_t;
00122     qreal c = t * t;
00123 
00124     return QPointF((y2-y1) * a + (y3-y2) * b + (y4-y3) * c,  -(x2-x1) * a - (x3-x2) * b - (x4-x3) * c);
00125 }

QPolygonF QBezier::toPolygon (  )  const

Definition at line 51 of file qbezier.cpp.

References addToPolygon(), QVector< T >::append(), x1, and y1.

Referenced by Q3PointArray::cubicBezier().

00052 {
00053     // flattening is done by splitting the bezier until we can replace the segment by a straight
00054     // line. We split further until the control points are close enough to the line connecting the
00055     // boundary points.
00056     //
00057     // the Distance of a point p from a line given by the points (a,b) is given by:
00058     //
00059     // d = abs( (bx - ax)(ay - py) - (by - ay)(ax - px) ) / line_length
00060     //
00061     // We can stop splitting if both control points are close enough to the line.
00062     // To make the algorithm faster we use the manhattan length of the line.
00063 
00064     QPolygonF polygon;
00065     polygon.append(QPointF(x1, y1));
00066     addToPolygon(&polygon);
00067     return polygon;
00068 }

Here is the call graph for this function:

void QBezier::addToPolygon ( QPolygonF p  )  const

Definition at line 70 of file qbezier.cpp.

References QVector< T >::append(), b, d, and l.

Referenced by toPolygon().

00071 {
00072     QBezier beziers[32];
00073     beziers[0] = *this;
00074     QBezier *b = beziers;
00075     while (b >= beziers) {
00076         // check if we can pop the top bezier curve from the stack
00077         qreal l = qAbs(b->x4 - b->x1) + qAbs(b->y4 - b->y1);
00078         qreal d;
00079         if (l > 1.) {
00080             d = qAbs( (b->x4 - b->x1)*(b->y1 - b->y2) - (b->y4 - b->y1)*(b->x1 - b->x2) )
00081                 + qAbs( (b->x4 - b->x1)*(b->y1 - b->y3) - (b->y4 - b->y1)*(b->x1 - b->x3) );
00082         } else {
00083             d = qAbs(b->x1 - b->x2) + qAbs(b->y1 - b->y2) +
00084                 qAbs(b->x1 - b->x3) + qAbs(b->y1 - b->y3);
00085             l = 1.;
00086         }
00087         if (d < .5*l || b == beziers + 31) {
00088             // good enough, we pop it off and add the endpoint
00089             polygon->append(QPointF(b->x4, b->y4));
00090             --b;
00091         } else {
00092             // split, second half of the polygon goes lower into the stack
00093             b->split(b+1, b);
00094             ++b;
00095         }
00096     }
00097 }

Here is the call graph for this function:

QRectF QBezier::bounds (  )  const

Definition at line 124 of file qbezier.cpp.

References x1, x2, x3, x4, y1, y2, y3, and y4.

Referenced by qt_isect_curve_horizontal(), qt_isect_curve_vertical(), qt_painterpath_isect_curve(), and shift().

00125 {
00126     qreal xmin = x1;
00127     qreal xmax = x1;
00128     if (x2 < xmin)
00129         xmin = x2;
00130     else if (x2 > xmax)
00131         xmax = x2;
00132     if (x3 < xmin)
00133         xmin = x3;
00134     else if (x3 > xmax)
00135         xmax = x3;
00136     if (x4 < xmin)
00137         xmin = x4;
00138     else if (x4 > xmax)
00139         xmax = x4;
00140 
00141     qreal ymin = y1;
00142     qreal ymax = y1;
00143     if (y2 < ymin)
00144         ymin = y2;
00145     else if (y2 > ymax)
00146         ymax = y2;
00147     if (y3 < ymin)
00148         ymin = y3;
00149     else if (y3 > ymax)
00150         ymax = y3;
00151     if (y4 < ymin)
00152         ymin = y4;
00153     else if (y4 > ymax)
00154         ymax = y4;
00155     return QRectF(xmin, ymin, xmax-xmin, ymax-ymin);
00156 }

QPointF QBezier::pt1 (  )  const [inline]

Definition at line 56 of file qbezier_p.h.

Referenced by qt_painterpath_isect_curve(), and qt_stroke_side().

00056 { return QPointF(x1, y1); }

QPointF QBezier::pt2 (  )  const [inline]

Definition at line 57 of file qbezier_p.h.

00057 { return QPointF(x2, y2); }

QPointF QBezier::pt3 (  )  const [inline]

Definition at line 58 of file qbezier_p.h.

Referenced by qt_stroke_side().

00058 { return QPointF(x3, y3); }

QPointF QBezier::pt4 (  )  const [inline]

Definition at line 59 of file qbezier_p.h.

Referenced by qt_painterpath_isect_curve(), and qt_stroke_side().

00059 { return QPointF(x4, y4); }

QPointF QBezier::midPoint (  )  const [inline]

Definition at line 70 of file qbezier_p.h.

References x1, x2, x3, x4, y1, y2, y3, and y4.

Referenced by midTangent().

00071 {
00072     return QPointF((x1 + x4 + 3*(x2 + x3))/8., (y1 + y4 + 3*(y2 + y3))/8.);
00073 }

QLineF QBezier::midTangent (  )  const [inline]

Definition at line 75 of file qbezier_p.h.

References QLineF::dx(), QLineF::dy(), midPoint(), pointAt(), QPointF::x(), x1, x2, x3, x4, QPointF::y(), y1, y2, y3, and y4.

00076 {
00077     QPointF mid = midPoint();
00078     QLineF dir(QLineF(x1, y1, x2, y2).pointAt(0.5), QLineF(x3, y3, x4, y4).pointAt(0.5));
00079     return QLineF(mid.x() - dir.dx(), mid.y() - dir.dy(),
00080                   mid.x() + dir.dx(), mid.y() + dir.dy());
00081 }

Here is the call graph for this function:

void QBezier::split ( QBezier firstHalf,
QBezier secondHalf 
) const

Definition at line 99 of file qbezier.cpp.

References c, x1, x2, x3, x4, y1, y2, y3, and y4.

Referenced by qt_isect_curve_horizontal(), qt_isect_curve_vertical(), and qt_painterpath_isect_curve().

00100 {
00101     Q_ASSERT(firstHalf);
00102     Q_ASSERT(secondHalf);
00103 
00104     qreal c = (x2 + x3)/2;
00105     firstHalf->x2 = (x1 + x2)/2;
00106     secondHalf->x3 = (x3 + x4)/2;
00107     firstHalf->x1 = x1;
00108     secondHalf->x4 = x4;
00109     firstHalf->x3 = (firstHalf->x2 + c)/2;
00110     secondHalf->x2 = (secondHalf->x3 + c)/2;
00111     firstHalf->x4 = secondHalf->x1 = (firstHalf->x3 + secondHalf->x2)/2;
00112 
00113     c = (y2 + y3)/2;
00114     firstHalf->y2 = (y1 + y2)/2;
00115     secondHalf->y3 = (y3 + y4)/2;
00116     firstHalf->y1 = y1;
00117     secondHalf->y4 = y4;
00118     firstHalf->y3 = (firstHalf->y2 + c)/2;
00119     secondHalf->y2 = (secondHalf->y3 + c)/2;
00120     firstHalf->y4 = secondHalf->y1 = (firstHalf->y3 + secondHalf->y2)/2;
00121 }

int QBezier::shifted ( QBezier curveSegments,
int  maxSegmets,
qreal  offset,
float  threshold 
) const

Definition at line 386 of file qbezier.cpp.

References addCircle(), b, Circle, Discard, o, Ok, shift(), x1, x2, x3, x4, y1, y2, y3, and y4.

Referenced by qt_stroke_side().

00387 {
00388     Q_ASSERT(curveSegments);
00389     Q_ASSERT(maxSegments > 0);
00390 
00391     if (x1 == x2 && x1 == x3 && x1 == x4 &&
00392         y1 == y2 && y1 == y3 && y1 == y4)
00393         return 0;
00394 
00395     --maxSegments;
00396     QBezier beziers[10];
00397 redo:
00398     beziers[0] = *this;
00399     QBezier *b = beziers;
00400     QBezier *o = curveSegments;
00401 
00402     while (b >= beziers) {
00403         if (b - beziers == 9 || o - curveSegments == maxSegments) {
00404             threshold *= 1.5;
00405             if (threshold > 2.)
00406                 goto give_up;
00407             goto redo;
00408         }
00409         ShiftResult res = shift(b, o, offset, threshold);
00410         if (res == Discard) {
00411             --b;
00412         } else if (res == Ok) {
00413             ++o;
00414             --b;
00415             continue;
00416         } else if (res == Circle && maxSegments - (o - curveSegments) >= 2) {
00417             // add semi circle
00418             addCircle(b, offset, o);
00419             --b;
00420             o += 2;
00421         } else {
00422             b->split(b+1, b);
00423             ++b;
00424         }
00425     }
00426 
00427 give_up:
00428     while (b >= beziers) {
00429         shift(b, o, offset, threshold);
00430         ++o;
00431         --b;
00432     }
00433 
00434     Q_ASSERT(o - curveSegments <= maxSegments);
00435     return o - curveSegments;
00436 }

Here is the call graph for this function:


Member Data Documentation

qreal QBezier::x1

Definition at line 67 of file qbezier_p.h.

Referenced by bounds(), midPoint(), midTangent(), normalVector(), pointAt(), shift(), shifted(), split(), and toPolygon().

qreal QBezier::y1

Definition at line 67 of file qbezier_p.h.

Referenced by bounds(), midPoint(), midTangent(), normalVector(), pointAt(), shift(), shifted(), split(), and toPolygon().

qreal QBezier::x2

Definition at line 67 of file qbezier_p.h.

Referenced by bounds(), midPoint(), midTangent(), normalVector(), pointAt(), shift(), shifted(), and split().

qreal QBezier::y2

Definition at line 67 of file qbezier_p.h.

Referenced by bounds(), midPoint(), midTangent(), normalVector(), pointAt(), shift(), shifted(), and split().

qreal QBezier::x3

Definition at line 67 of file qbezier_p.h.

Referenced by bounds(), midPoint(), midTangent(), normalVector(), pointAt(), shift(), shifted(), and split().

qreal QBezier::y3

Definition at line 67 of file qbezier_p.h.

Referenced by bounds(), midPoint(), midTangent(), normalVector(), pointAt(), shift(), shifted(), and split().

qreal QBezier::x4

Definition at line 67 of file qbezier_p.h.

Referenced by bounds(), midPoint(), midTangent(), normalVector(), pointAt(), shift(), shifted(), and split().

qreal QBezier::y4

Definition at line 67 of file qbezier_p.h.

Referenced by bounds(), midPoint(), midTangent(), normalVector(), pointAt(), shift(), shifted(), and split().


The documentation for this class was generated from the following files:
Generated on Thu Mar 15 16:51:51 2007 for Qt 4.2 User's Guide by  doxygen 1.5.1