profile: rewrite ProfileScene::pointOnProfile()

This function was used to check wether a screen-point
is located on the profile. Bizzarely, this was done by
transforming into local coordinates and checking
min/max value. Simply check the screen coordinates
directly. Moreover, make the function return whether
the point is inside the region, not outside the region,
to make logic more straight forward.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
This commit is contained in:
Berthold Stoeger 2021-10-26 16:37:38 +02:00 committed by Dirk Hohndel
parent 7df0adef64
commit 210660d057
6 changed files with 23 additions and 14 deletions

View file

@ -375,18 +375,31 @@ qreal DiveCartesianAxis::posAtValue(qreal value) const
return adjusted;
}
static std::pair<double, double> getLineFromTo(const QLineF &l, bool horizontal)
{
if (horizontal)
return std::make_pair(l.x1(), l.x2());
else
return std::make_pair(l.y1(), l.y2());
}
double DiveCartesianAxis::screenPosition(double pos) const
{
QLineF m = line();
double from = position == Position::Bottom ? m.x1() : m.y1();
double to = position == Position::Bottom ? m.x2() : m.y2();
if ((position == Position::Bottom) == inverted)
pos = 1.0 - pos;
auto [from, to] = getLineFromTo(line(), position == Position::Bottom);
return (to - from) * pos + from;
}
double DiveCartesianAxis::pointInRange(double pos) const
{
auto [from, to] = getLineFromTo(line(), position == Position::Bottom);
if (from > to)
std::swap(from, to);
return pos >= from && pos <= to;
}
double DiveCartesianAxis::maximum() const
{
return max;

View file

@ -40,6 +40,7 @@ public:
qreal posAtValue(qreal value) const;
void setPosition(const QRectF &rect);
double screenPosition(double pos) const; // 0.0 = begin, 1.0 = end of axis, independent of represented values
double pointInRange(double pos) const; // Point on screen is in range of axis
void setTextVisible(bool arg1);
void setLinesVisible(bool arg1);
void updateTicks(int animSpeed);

View file

@ -75,7 +75,7 @@ void DiveHandler::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
t.start();
ProfileWidget2 *view = qobject_cast<ProfileWidget2*>(scene()->views().first());
if(view->profileScene->isPointOutOfBoundaries(event->scenePos()))
if(!view->profileScene->pointOnProfile(event->scenePos()))
return;
QGraphicsEllipseItem::mouseMoveEvent(event);

View file

@ -313,14 +313,9 @@ void ProfileScene::updateAxes(bool diveHasHeartBeat, bool simplified)
temperatureAxis->setTransform(slope(mkelvin_to_F), intercept(mkelvin_to_F));
}
bool ProfileScene::isPointOutOfBoundaries(const QPointF &point) const
bool ProfileScene::pointOnProfile(const QPointF &point) const
{
double xpos = timeAxis->valueAt(point);
double ypos = profileYAxis->valueAt(point);
return xpos > timeAxis->maximum() ||
xpos < timeAxis->minimum() ||
ypos > profileYAxis->maximum() ||
ypos < profileYAxis->minimum();
return timeAxis->pointInRange(point.x()) && profileYAxis->pointInRange(point.y());
}
void ProfileScene::plotDive(const struct dive *dIn, int dcIn, DivePlannerPointsModel *plannerModel,

View file

@ -38,7 +38,7 @@ public:
void resize(QSizeF size);
void clear();
bool isPointOutOfBoundaries(const QPointF &point) const;
bool pointOnProfile(const QPointF &point) const;
// If a plannerModel is passed, the deco-information is taken from there.
void plotDive(const struct dive *d, int dc, DivePlannerPointsModel *plannerModel = nullptr, bool inPlanner = false,

View file

@ -332,7 +332,7 @@ void ProfileWidget2::mouseDoubleClickEvent(QMouseEvent *event)
{
if ((currentState == PLAN || currentState == EDIT) && plannerModel) {
QPointF mappedPos = mapToScene(event->pos());
if (profileScene->isPointOutOfBoundaries(mappedPos))
if (!profileScene->pointOnProfile(mappedPos))
return;
int minutes = lrint(profileScene->timeAxis->valueAt(mappedPos) / 60);