void DiveCalculatedCeiling::modelDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight) { // We don't have enougth data to calculate things, quit. if (!shouldCalculateStuff(topLeft, bottomRight)) return; AbstractProfilePolygonItem::modelDataChanged(topLeft, bottomRight); // Add 2 points to close the polygon. QPolygonF poly = polygon(); if (poly.isEmpty()) return; QPointF p1 = poly.first(); QPointF p2 = poly.last(); poly.prepend(QPointF(p1.x(), vAxis->posAtValue(0))); poly.append(QPointF(p2.x(), vAxis->posAtValue(0))); setPolygon(poly); QLinearGradient pat(0, polygon().boundingRect().top(), 0, polygon().boundingRect().bottom()); pat.setColorAt(0, getColor(CALC_CEILING_SHALLOW)); pat.setColorAt(1, getColor(CALC_CEILING_DEEP)); setPen(QPen(QBrush(Qt::NoBrush), 0)); setBrush(pat); gradientFactor->setX(poly.boundingRect().width() / 2 + poly.boundingRect().x()); DivePlannerPointsModel *plannerModel = DivePlannerPointsModel::instance(); if (plannerModel->isPlanner()) { struct diveplan &diveplan = plannerModel->getDiveplan(); gradientFactor->setText(QString("GF %1/%2").arg(diveplan.gflow).arg(diveplan.gfhigh)); } else { gradientFactor->setText(QString("GF %1/%2").arg(prefs.gflow).arg(prefs.gfhigh)); } }
int Polygon::prepend(lua_State * L) // ( const T & ) { QPolygonF* obj = ValueInstaller2<QPolygonF>::check( L, 1 ); QPointF* p = ValueInstaller2<QPointF>::check( L, 2 ); obj->prepend( *p ); return 0; }
static PyObject *meth_QPolygonF_prepend(PyObject *sipSelf, PyObject *sipArgs) { PyObject *sipParseErr = NULL; { const QPointF* a0; int a0State = 0; QPolygonF *sipCpp; if (sipParseArgs(&sipParseErr, sipArgs, "BJ1", &sipSelf, sipType_QPolygonF, &sipCpp, sipType_QPointF, &a0, &a0State)) { sipCpp->prepend(*a0); sipReleaseType(const_cast<QPointF *>(a0),sipType_QPointF,a0State); Py_INCREF(Py_None); return Py_None; } } /* Raise an exception if the arguments couldn't be parsed. */ sipNoMethod(sipParseErr, sipName_QPolygonF, sipName_prepend, doc_QPolygonF_prepend); return NULL; }
QPainterPath ArtisticTextToolSelection::outline() { if (!hasSelection()) return QPainterPath(); CharIndex charPos = m_currentShape->indexOfChar(m_selectionStart); if (charPos.first < 0) return QPainterPath(); QPainterPath outline; QPolygonF polygon; QList<ArtisticTextRange> ranges = m_currentShape->text(); if (ranges.size() == 0) return outline; int globalCharIndex = m_selectionStart; int remainingChars = m_selectionCount; while (remainingChars) { const ArtisticTextRange ¤tRange = ranges[charPos.first]; int currentTextLength = currentRange.text().length(); while (charPos.second < currentTextLength && remainingChars > 0) { const QPointF pos = m_currentShape->charPositionAt(globalCharIndex); const qreal angle = m_currentShape->charAngleAt(globalCharIndex); QTransform charTransform; charTransform.translate( pos.x() - 1, pos.y() ); charTransform.rotate( 360. - angle ); QFontMetricsF metrics(currentRange.font()); polygon.prepend(charTransform.map(QPointF(0.0, -metrics.ascent()))); polygon.append(charTransform.map(QPointF(0.0, metrics.descent()))); // advance to next character charPos.second++; globalCharIndex++; remainingChars--; // next character has y-offset or we are at the end of this text range const bool hasYOffset = currentRange.hasYOffset(charPos.second); const bool atRangeEnd = charPos.second == currentTextLength; const bool atSelectionEnd = remainingChars == 0; if (hasYOffset || atRangeEnd || atSelectionEnd) { if (hasYOffset || atRangeEnd) { const QChar c = currentRange.text().at(charPos.second-1); const qreal w = metrics.width(c); polygon.prepend(charTransform.map(QPointF(w, -metrics.ascent()))); polygon.append(charTransform.map(QPointF(w, metrics.descent()))); } else { const QPointF pos = m_currentShape->charPositionAt(globalCharIndex); const qreal angle = m_currentShape->charAngleAt(globalCharIndex); charTransform.reset(); charTransform.translate( pos.x() - 1, pos.y() ); charTransform.rotate( 360. - angle ); polygon.prepend(charTransform.map(QPointF(0.0, -metrics.ascent()))); polygon.append(charTransform.map(QPointF(0.0, metrics.descent()))); } QPainterPath p; p.addPolygon(polygon); outline = outline.united(p); polygon.clear(); } } // go to first character of next text range charPos.first++; charPos.second = 0; } // transform to document coordinates return m_currentShape->absoluteTransformation(0).map(outline); }
QPolygonF minigis::shiftPolygonSimple(const QPolygonF &origin, qreal delta, bool closed) { QPolygonF path = origin; QPolygonF norm; // ----------------- Поиск нормалей к оригинальному полигону int N = path.size(); for (int i = 1; i < N; ++i) { QPointF vect = path.at(i) - path.at(i-1); double len = lengthR2(vect); if (qFuzzyIsNull(len)) { path.remove(i); --N; --i; continue; } vect /= len; norm.append(QPointF(vect.y() * delta, -vect.x() * delta)); } // ---- if (closed) { QPointF vect = path.first() - path.last(); double len = lengthR2(vect); if (qFuzzyIsNull(len)) path.remove(path.size() - 1); else { vect /= len; norm.append(QPointF(vect.y() * delta, -vect.x() * delta)); } } // ------------------ QVector<QLineF> lines; // -------------------------- Построение смещенных линий for (int i = 1; i < path.size(); ++i) lines.append(QLineF(path.at(i) + norm.at(i-1), path.at(i-1) + norm.at(i-1))); // ---- if (closed) lines.append(QLineF(path.first() + norm.last(), path.last() + norm.last())); // ------------------ QPolygonF shell; if (lines.isEmpty()) return shell; // -------------------------- Построение смещенного полигона N = lines.size(); for (int i = 1; i < N; ++i) { QPointF tmp; QLineF::IntersectType type = lines.at(i-1).intersect(lines.at(i), &tmp); double ang = lines.at(i-1).angleTo(lines.at(i)); if (type != QLineF::NoIntersection) shell.append(tmp); else { if (qFuzzyCompare(ang, 180.)) shell.append(lines.at(i).p2() - 2 * norm.at(i)); shell.append(lines.at(i).p2()); } } // ---- if (closed) { QPointF tmp; QLineF::IntersectType type = lines.last().intersect(lines.first(), &tmp); double ang = lines.last().angleTo(lines.first()); if (type != QLineF::NoIntersection) shell.append(tmp); else { if (qFuzzyCompare(ang, 180.)) shell.append(lines.first().p2() - 2 * norm.first()); shell.append(lines.first().p2()); } shell.append(shell.first()); } else { shell.prepend(lines.first().p2()); shell.append(lines.last().p1()); } // ------------------ return shell; }
QPolygonF minigis::shiftPolygonDifficult(const QPolygonF &origin, qreal delta, bool closed) { if (qFuzzyIsNull(delta)) return origin; QPolygonF path = origin; QPolygonF norm; // ----------------- Поиск нормалей к оригинальному полигону int N = path.size(); for (int i = 1; i < N; ++i) { QPointF vect = path.at(i) - path.at(i-1); double len = lengthR2(vect); if (qFuzzyIsNull(len)) { path.remove(i); --N; --i; continue; } vect /= len; norm.append(QPointF(vect.y() * delta, -vect.x() * delta)); } // ---- if (closed) { QPointF vect = path.first() - path.last(); double len = lengthR2(vect); if (qFuzzyIsNull(len)) path.remove(path.size() - 1); else { vect /= len; norm.append(QPointF(vect.y() * delta, -vect.x() * delta)); } } // ------------------ QVector<QLineF> lines; // -------------------------- Построение смещенных линий for (int i = 1; i < path.size(); ++i) lines.append(QLineF(path.at(i) + norm.at(i-1), path.at(i-1) + norm.at(i-1))); // ---- if (closed) lines.append(QLineF(path.first() + norm.last(), path.last() + norm.last())); // ------------------ QPolygonF shell; if (lines.isEmpty()) return shell; // -------------------------- Построение смещенного полигона N = lines.size(); for (int i = 1; i < N; ++i) { QPointF tmp; QLineF::IntersectType type = lines.at(i-1).intersect(lines.at(i), &tmp); qreal ang = lines.at(i-1).angleTo(lines.at(i)); if (type != QLineF::NoIntersection) shell.append(tmp); else { if (qFuzzyCompare(ang, qreal(180))) shell.append(lines.at(i).p2() - 2 * norm.at(i)); shell.append(lines.at(i).p2()); } } // ---- if (closed) { QPointF tmp; QLineF::IntersectType type = lines.last().intersect(lines.first(), &tmp); qreal ang = lines.last().angleTo(lines.first()); if (type != QLineF::NoIntersection) shell.append(tmp); else { if (qFuzzyCompare(ang, qreal(180))) shell.append(lines.first().p2() - 2 * norm.first()); shell.append(lines.first().p2()); } shell.append(shell.first()); } else { shell.prepend(lines.first().p2()); shell.append(lines.last().p1()); } // ------------------ // -------------------------- обрезание острых углов int k = 0; N = lines.size(); for (int i = 1; i < N; ++i) { double ang = lines.at(i-1).angleTo(lines.at(i)); bool first = (120 < ang && ang < 180 && delta < 0) || (180 < ang && ang < 240 && delta > 0); bool second = (120 < ang && ang < 180 && delta > 0) || (180 < ang && ang < 240 && delta < 0); if (first) { int num = closed ? 1 : 0; QPointF v = shell.at(i + k - num) - path.at(i); v /= lengthR2(v); QPointF start = path.at(i) + v * qAbs(delta); QLineF tmp(start, start + QPointF(-v.y(), v.x())); QPointF a; if (tmp.intersect(lines.at(i ), &a) != QLineF::NoIntersection) shell.replace(i + k - num, a); if (tmp.intersect(lines.at(i-1), &a) != QLineF::NoIntersection) shell.insert(i + k - num, a); ++k; } else if (second) { // TODO: cut corner } } // ---- if (closed) { double ang = lines.last().angleTo(lines.first()); int num = lines.size(); int shellNum = (num + k - 1) % shell.size(); bool first = (120 < ang && ang < 180 && delta < 0) || (180 < ang && ang < 240 && delta > 0); bool second = (180 < ang && ang < 240 && delta < 0) || (120 < ang && ang < 180 && delta > 0); if (first) { QPointF v = shell.at(shellNum) - path.at(num % path.size()); v /= lengthR2(v); QPointF start = path.at(num % path.size()) + v * qAbs(delta); QLineF tmp(start, start + QPointF(-v.y(), v.x())); QPointF a; if (tmp.intersect(lines.first(), &a) != QLineF::NoIntersection) shell.replace(shellNum, a); if (tmp.intersect(lines.last() , &a) != QLineF::NoIntersection) shell.insert(shellNum, a); } else if (second) { // TODO: cut corner } } // ------------------ return shell; }