Fix crash

Fix crash for a special case (the first time since qet exist) when a
conductor have all segments to 0 in the .qet file.
See https://qelectrotech.org/forum/viewtopic.php?id=1964
This commit is contained in:
joshua
2021-03-06 15:17:10 +01:00
parent 153aecbbf3
commit 4b82c3a0c4

View File

@@ -1974,53 +1974,70 @@ void Conductor::deleteSegments()
} }
/** /**
@param point Un point situe a l'exterieur du polygone * @brief Conductor::movePointIntoPolygon
@param polygon Le polygone dans lequel on veut rapatrier le point * @param point : A point located outside the polygon
@return la position du point, une fois ramene dans le polygone, ou plus * @param polygon : The polygon in which we want to move the point
exactement sur le bord du polygone * @return the position of the point, once brought back into the polygon,
*/ * or more exactly on the edge of the polygon
QPointF Conductor::movePointIntoPolygon(const QPointF &point, const QPainterPath &polygon) { */
// decompose le polygone en lignes et points QPointF Conductor::movePointIntoPolygon(const QPointF &point, const QPainterPath &polygon)
QList<QPolygonF> polygons = polygon.simplified().toSubpathPolygons(); {
// decomposes the polygon into lines and points
const QList<QPolygonF> polygons = polygon.simplified().toSubpathPolygons();
QList<QLineF> lines; QList<QLineF> lines;
QList<QPointF> points; QList<QPointF> points;
foreach(QPolygonF polygon, polygons) {
if (polygon.count() <= 1) continue;
// on recense les lignes et les points for (QPolygonF polygon : polygons)
{
if (polygon.count() <= 1)
continue;
// lines and points are counted
for (int i = 1 ; i < polygon.count() ; ++ i) { for (int i = 1 ; i < polygon.count() ; ++ i) {
lines << QLineF(polygon.at(i - 1), polygon.at(i)); lines << QLineF(polygon.at(i - 1), polygon.at(i));
points << polygon.at(i -1); points << polygon.at(i -1);
} }
} }
// on fait des projetes orthogonaux du point sur les differents segments du // we make orthogonal projections of the point on the different
// polygone, en les triant par longueur croissante // segments of the polygon, sorting them by increasing length
QMap<qreal, QPointF> intersections; QMap<qreal, QPointF> intersections;
foreach (QLineF line, lines) { for (QLineF line : lines)
{
QPointF intersection_point; QPointF intersection_point;
if (QET::orthogonalProjection(point, line, &intersection_point)) { if (QET::orthogonalProjection(point, line, &intersection_point)) {
intersections.insert(QLineF(intersection_point, point).length(), intersection_point); intersections.insert(QLineF(intersection_point, point).length(), intersection_point);
} }
} }
if (intersections.count()) {
// on determine la plus courte longueur pour un projete orthogonal if (intersections.count())
{
// the shortest length for an orthogonal project is determined
QPointF the_point = intersections[intersections.keys().first()]; QPointF the_point = intersections[intersections.keys().first()];
return(the_point); return(the_point);
} else { }
// determine le coin du polygone le plus proche du point exterieur else
qreal minimum_length = -1; {
int point_index = -1; // determines the corner of the polygon closest to the outer point
for (int i = 0 ; i < points.count() ; ++ i) { qreal minimum_length = -1;
qreal length = qAbs(QLineF(points.at(i), point).length()); int point_index = -1;
if (minimum_length < 0 || length < minimum_length) { for (int i = 0 ; i < points.count() ; ++ i)
minimum_length = length; {
point_index = i; qreal length = qAbs(QLineF(points.at(i), point).length());
} if (minimum_length < 0 || length < minimum_length) {
minimum_length = length;
point_index = i;
} }
// on connait desormais le coin le plus proche du texte }
// we now know the closest corner of the text
// aucun projete orthogonal n'a donne quoi que ce soit, on met le texte sur un des coins du polygone
if (point_index == -1 ||
point_index+1 > points.size()) {
return QPointF(0,0);
}
// no orthogonal projection gave anything, we put the text on one of the corners of the polygon
return(points.at(point_index)); return(points.at(point_index));
} }
} }