double BezierCalc::getTotalAngle(const QList<QPointF>& controllPoints) { int end = controllPoints.size() - 1; // compute first derivation QList<QPointF> derivation; for (int i = 0; i < end; ++i) { derivation.append(controllPoints[i + 1] - controllPoints[i]); } double totalAngle = 0.0; end = derivation.size() - 1; for (int i = 0; i < end; ++i) { const QLineF line1 = QLineF(QPointF(0, 0), derivation[i]); const QLineF line2 = QLineF(QPointF(0, 0), derivation[i + 1]); double tmpAngle = line1.angleTo(line2); if (tmpAngle > 180) { tmpAngle = 360 - tmpAngle; } totalAngle += tmpAngle; } return totalAngle; }
/** * This method aligns *this* Symbol to the line being * passed. That is, it ensures that the axis of this symbol aligns * exactly with the \a "to" line passed. * * Also this item is moved such that the second end point of the * SymbolEndPoints for the current symbol *collides* with the second end * point of \a "to" line. */ void Symbol::alignTo(const QLineF& to) { QLineF toMapped(mapFromParent(to.p1()), mapFromParent(to.p2())); QLineF origAxis = Symbol::symbolTable[m_symbolType].axisLine; QLineF translatedAxis = origAxis.translated(toMapped.p2() - origAxis.p2()); qreal angle = translatedAxis.angleTo(toMapped); rotate(-angle); QPointF delta = to.p2() - mapToParent(symbolEndPoints().second); moveBy(delta.x(), delta.y()); }
void CanvasMode_EditArc::mouseReleaseEvent(QMouseEvent *m) { m_canvas->m_viewMode.m_MouseButtonPressed = false; m_canvas->resetRenderMode(); m->accept(); PageItem *currItem = m_doc->m_Selection->itemAt(0); PageItem_Arc* item = currItem->asArc(); QPointF mPoint = item->PoLine.pointQF(0); if ((m_arcPoint == useControlStart) || (m_arcPoint == useControlSweep) || (m_arcPoint == useControlHeight) || (m_arcPoint == useControlWidth)) { QTransform bb; bb.scale(item->arcHeight / item->arcWidth, 1.0); QLineF inp = QLineF(QPointF(item->arcWidth / 2.0, item->arcHeight / 2.0), QPointF(item->arcWidth, item->arcHeight / 2.0)); double start = inp.angleTo(QLineF(QPointF(item->arcWidth / 2.0, item->arcHeight / 2.0),startPoint)); inp.setAngle(start); double end = inp.angleTo(QLineF(QPointF(item->arcWidth / 2.0, item->arcHeight / 2.0),endPoint)); double nWidth = mPoint.x() - widthPoint.x(); double nHeight = mPoint.y() - heightPoint.y(); applyValues(start,end + start, 2.0 * nHeight, 2.0 * nWidth); } QTransform itemMatrix = currItem->getTransform(); m_doc->regionsChanged()->update(itemMatrix.mapRect(QRectF(0, 0, currItem->width(), currItem->height())).adjusted(-currItem->width() / 2.0, -currItem->height() / 2.0, currItem->width(), currItem->height())); }
QPolygonF minigis::shiftPolygon(const QPolygonF &origin, qreal delta, bool direction, QList<int> *doubleDots) { if (doubleDots) doubleDots->clear(); delta = qAbs(delta); QVector<QLineF> lines; for (int i = 1; i < origin.size(); ++i) { QLineF l(origin.at(i - 1), origin.at(i)); QLineF norm = l.normalVector(); qreal len = lengthR2(l.p2() - l.p1()); QPointF normVect = (norm.p2() - norm.p1()) / len; lines.append(l.translated(normVect * (direction ? -delta : delta))); } QPolygonF path; QVectorIterator<QLineF> it(lines); QLineF base = it.next(); int pointNumber = 0; path.append(base.p1()); while (it.hasNext()) { QLineF next = it.next(); ++pointNumber; double ang = base.angleTo(next); bool side = ang < 180 ? direction : !direction; if (ang > 180) ang = 360 - ang; if (qFuzzyIsNull(ang)) { // "I" + // линия-продолжение path.append(base.p2()); base.setP2(next.p2()); } else if (qFuzzyIsNull(ang - 180)) { // "IV" ? // коллинеарная линия в обраную строную // TODO: mb we don't need this path.append(base.p2()); path.append(next.p1()); base = next; if (doubleDots) doubleDots->append(pointNumber); } else if (ang < 120) { // "II" QPointF p; base.intersect(next, &p); if (side) { // "A" + // линия снаружи path.append(p); base = next; } else { // "B" - // линия внутри // TODO: correct algo path.append(p); base = next; } } else { // "III" if (side) { // "A" + // линия снаружи с острым углом QPointF p; base.intersect(next, &p); QPointF start = origin.at(pointNumber); QPointF vect = p - start; vect *= delta / lengthR2(vect); QPointF norm(vect.y(), -vect.x()); QLineF tmp(start + vect, start + vect + norm); base.intersect(tmp, &p); path.append(p); next.intersect(tmp, &p); path.append(p); base = next; if (doubleDots) doubleDots->append(pointNumber); } else { // "B" - // линия внутри с острым углом // TODO: correct algo QPointF p; base.intersect(next, &p); path.append(p); base = next; } } } path.append(base.p2()); return path; }