/** * Calcul le point sur la fleche le plus près du point donné en parametre * @brief Fleche::PointLePlusPres * @param Position La osition à analyser * @return La position sur la fleche la plus proche */ QPointF Fleche::PointLePlusPres(QPointF Position) { //Calcul de la projection orthogonale de la position de la souris sur les segments verticaux de la flèche. QPointF Retour ; QPointF Projection ; qreal Distance (0); qreal DistanceMini(INFINITY) ; QLineF LigneBase ; QLineF LigneSourisProj ; LigneSourisProj.setPoints(Position, Projection); //Pour tout les segments for(register int i = 0; i < this->ListePoints.length() -1; i++) { LigneBase.setPoints(this->ListePoints[i], this->ListePoints[i+1]); //S'il sont verticaux if(LigneBase.dx() == 0) { //On calcul les coordonnées du point Projection.setX(this->ListePoints[i].x()); Projection.setY(Position.y()); //Si le point sort du segment if(Projection.y() < this->ListePoints[i].y() || Projection.y() > this->ListePoints[i+1].y()) { QLineF LigneSourisP1 ; QLineF LigneSourisP2 ; LigneSourisP1.setPoints(Position, this->ListePoints[i]); LigneSourisP2.setPoints(Position, this->ListePoints[i+1]); //On le recale sur l'extrémité la plus proche if(LigneSourisP1.length() < LigneSourisP2.length()) { Projection = this->ListePoints[i] ; } else { Projection = this->ListePoints[i+1] ; } } //On renvois le point le plus proche de la souris Distance = LigneSourisProj.length() ; if(Distance < DistanceMini) { Retour = Projection ; DistanceMini = Distance ; } } } return Retour; }
void tst_QLine::testSet() { { QLine l; l.setP1(QPoint(1, 2)); l.setP2(QPoint(3, 4)); QCOMPARE(l.x1(), 1); QCOMPARE(l.y1(), 2); QCOMPARE(l.x2(), 3); QCOMPARE(l.y2(), 4); l.setPoints(QPoint(5, 6), QPoint(7, 8)); QCOMPARE(l.x1(), 5); QCOMPARE(l.y1(), 6); QCOMPARE(l.x2(), 7); QCOMPARE(l.y2(), 8); l.setLine(9, 10, 11, 12); QCOMPARE(l.x1(), 9); QCOMPARE(l.y1(), 10); QCOMPARE(l.x2(), 11); QCOMPARE(l.y2(), 12); } { QLineF l; l.setP1(QPointF(1, 2)); l.setP2(QPointF(3, 4)); QCOMPARE(l.x1(), 1.0); QCOMPARE(l.y1(), 2.0); QCOMPARE(l.x2(), 3.0); QCOMPARE(l.y2(), 4.0); l.setPoints(QPointF(5, 6), QPointF(7, 8)); QCOMPARE(l.x1(), 5.0); QCOMPARE(l.y1(), 6.0); QCOMPARE(l.x2(), 7.0); QCOMPARE(l.y2(), 8.0); l.setLine(9.0, 10.0, 11.0, 12.0); QCOMPARE(l.x1(), 9.0); QCOMPARE(l.y1(), 10.0); QCOMPARE(l.x2(), 11.0); QCOMPARE(l.y2(), 12.0); } }
void GridFitting::paint(QPainter * painter, const QStyleOptionGraphicsItem *option, QWidget *widget) { Axis t(0, ylabel->getNpoints(), 0, xlabel->getNpoints()); axis = t; if (!cw) { cw = widget->rect().width(); } if (!ch) { ch = widget->rect().height(); } painter->setFont(*textFont); painter->fillRect(widget->rect(), background); double w1 = 0, h1 = 0; offset = 30; w1 = offset; if (widget->rect().width() != w) { if (w) { rW = (double) (cw / widget->rect().width()); } else { rW = 1; } } if (widget->rect().height() != h) { if (h) { rH = (double) (ch / widget->rect().height()); } else { rH = 1; } } w = widget->rect().width(); h = widget->rect().height(); h1 = h - offset; painter->drawLine(QLineF(QPointF(0, h1), QPointF(w, h1))); painter->drawLine(QLineF(QPointF(offset, 0), QPointF(offset, h))); w1 = w - offset; h1 = h - offset; int k = 1, k1 = 1; Xintervalsw = w1 / axis.x; double stepx =rW * sX*Xintervalsw; double ticksw = tX*stepx; for (double i = 0; i < w; i += Xintervalsw) { QLineF a; if (i >= k * (ticksw)) { a.setPoints(QPointF(offset + i, h1), QPointF(offset + i, h1 - offset / 5)); QRectF text; text.setX(offset + i - ticksw / 2); text.setY(h1); text.setWidth(ticksw); text.setHeight(20); QTextOption fmt(Qt::AlignTop | Qt::AlignCenter); double t = i / Xintervalsw; painter->drawText(text, QString::number(xlabel->getElement(t-1), 10, 2), fmt); k++; k1++; painter->drawLine(a); } else if (i >= k1 * stepx) { a.setPoints(QPointF(i + offset, h1), QPointF(i + offset, h1 - offset / 10)); painter->drawLine(a); k1++; } } k = 1; k1 = 1; Yintervalsh = h1 / axis.y; ZeroPoint = axis.Hy*Yintervalsh; double stepy = rH * sY*Yintervalsh; double ticksh = tY*stepy; for (double i = 0,j=0; i < h1; i += Yintervalsh,j++) { QLineF a; if (i >= (k * ticksh)) { a.setPoints(QPointF(offset, i), QPointF(offset + offset / 5, i)); QRectF text; text.setX(0); text.setY(i - ticksh / 2); text.setWidth(offset); QTextOption fmt(Qt::AlignHCenter | Qt::AlignCenter); text.setHeight(ticksh); QString str = QString::number(ylabel->getElement(i / Yintervalsh-1), 10, 2); painter->drawText(text, str, fmt); k++; k1++; painter->drawLine(a); } else if (i >= k1 * stepy) { a.setPoints(QPointF(offset, i), QPointF(offset + offset / 10, i)); painter->drawLine(a); k1++; } } if (isGridOn()) { painter->setPen(gridpen); k = 1; for (float i = 0; i < axis.y; i++) { QLineF a; if (i >= k * sY * tY) { a.setPoints(QPointF(offset, i * Yintervalsh), QPointF(w, i * Yintervalsh)); painter->drawLine(a); k++; } } k = 1; for (double i = 0; i < w; i += Xintervalsw) { QLineF a; if (i >= k * ticksw) { a.setPoints(QPointF(offset + i, 0), QPointF(offset + i, h1)); painter->drawLine(a); k++; } } } }
/** * Determine the approximate closest points of two polygons. * @param self First QPolygonF. * @param other Second QPolygonF. * @return QLineF::p1() returns point of \a self; * QLineF::p2() returns point of \a other. */ QLineF closestPoints(const QPolygonF& self, const QPolygonF& other) { const QRectF& selfRect = self.boundingRect(); const QRectF& otherRect = other.boundingRect(); Uml::Region::Enum region = findRegion(selfRect, otherRect); if (region == Uml::Region::Center) return QLineF(); if (self.size() < 3 || other.size() < 3) return QLineF(); QLineF result; const int selfLastIndex = self.size() - 1 - (int)self.isClosed(); const int otherLastIndex = other.size() - 1 - (int)other.isClosed(); QPointF selfPoint(self.at(selfLastIndex)); QPointF otherPoint(other.at(otherLastIndex)); QLineF selfLine, otherLine; int i; switch (region) { case Uml::Region::North: // Find other's line with largest Y values otherLine = findLine(other, Y, Largest, selfRect); // Find own line with smallest Y values selfLine = findLine(self, Y, Smallest, otherRect); // Use the middle value of the X values result.setLine(middle(selfLine.p2().x(), selfLine.p1().x()), selfLine.p1().y(), middle(otherLine.p2().x(), otherLine.p1().x()), otherLine.p1().y()); break; case Uml::Region::South: // Find other's line with smallest Y values otherLine = findLine(other, Y, Smallest, selfRect); // Find own line with largest Y values selfLine = findLine(self, Y, Largest, otherRect); // Use the middle value of the X values result.setLine(middle(selfLine.p2().x(), selfLine.p1().x()), selfLine.p1().y(), middle(otherLine.p2().x(), otherLine.p1().x()), otherLine.p1().y()); break; case Uml::Region::West: // Find other's line with largest X values otherLine = findLine(other, X, Largest, selfRect); // Find own line with smallest X values selfLine = findLine(self, X, Smallest, otherRect); // Use the middle value of the Y values result.setLine(selfLine.p1().x(), middle(selfLine.p2().y(), selfLine.p1().y()), otherLine.p1().x(), middle(otherLine.p2().y(), otherLine.p1().y())); break; case Uml::Region::East: // Find other's line with smallest X values otherLine = findLine(other, X, Smallest, selfRect); // Find own line with largest X values selfLine = findLine(self, X, Largest, otherRect); // Use the middle value of the Y values result.setLine(selfLine.p1().x(), middle(selfLine.p2().y(), selfLine.p1().y()), otherLine.p1().x(), middle(otherLine.p2().y(), otherLine.p1().y())); break; case Uml::Region::NorthWest: // Find other's point with largest X and largest Y value for (i = 0; i < otherLastIndex; ++i) { QPointF current(other.at(i)); if (current.x() + current.y() >= otherPoint.x() + otherPoint.y()) { otherPoint = current; } } // Find own point with smallest X and smallest Y value for (i = 0; i < selfLastIndex; ++i) { QPointF current(self.at(i)); if (current.x() + current.y() <= selfPoint.x() + selfPoint.y()) { selfPoint = current; } } result.setPoints(selfPoint, otherPoint); break; case Uml::Region::SouthWest: // Find other's point with largest X and smallest Y value for (i = 0; i < otherLastIndex; ++i) { QPointF current(other.at(i)); if (current.x() >= otherPoint.x() && current.y() <= otherPoint.y()) { otherPoint = current; } } // Find own point with smallest X and largest Y value for (i = 0; i < selfLastIndex; ++i) { QPointF current(self.at(i)); if (current.x() <= selfPoint.x() && current.y() >= selfPoint.y()) { selfPoint = current; } } result.setPoints(selfPoint, otherPoint); break; case Uml::Region::NorthEast: // Find other's point with smallest X and largest Y value for (i = 0; i < otherLastIndex; ++i) { QPointF current(other.at(i)); if (current.x() <= otherPoint.x() && current.y() >= otherPoint.y()) { otherPoint = current; } } // Find own point with largest X and smallest Y value for (i = 0; i < selfLastIndex; ++i) { QPointF current(self.at(i)); if (current.x() >= selfPoint.x() && current.y() <= selfPoint.y()) { selfPoint = current; } } result.setPoints(selfPoint, otherPoint); break; case Uml::Region::SouthEast: // Find other's point with smallest X and smallest Y value for (i = 0; i < otherLastIndex; ++i) { QPointF current(other.at(i)); if (current.x() + current.y() <= otherPoint.x() + otherPoint.y()) { otherPoint = current; } } // Find own point with largest X and largest Y value for (i = 0; i < selfLastIndex; ++i) { QPointF current(self.at(i)); if (current.x() + current.y() >= selfPoint.x() + selfPoint.y()) { selfPoint = current; } } result.setPoints(selfPoint, otherPoint); break; default: // Error break; } return result; }