[apps/shared/curve_view] Clarify coordinates' conventions

This commit is contained in:
Ruben Dashyan
2019-07-12 12:02:22 +02:00
committed by EmilieNumworks
parent 07474caf6c
commit 585b77c38f
4 changed files with 52 additions and 34 deletions

View File

@@ -87,8 +87,53 @@ void CurveView::setOkView(View * okView) {
layoutSubviews();
}
/* We need to locate physical points on the screen more precisely than pixels,
* hence by floating-point coordinates. We agree that the coordinates of the
* center of a pixel corresponding to KDPoint(x,y) are precisely (x,y). In
* particular, the coordinates of a pixel's corners are not integers but half
* integers. Finally, a physical point with floating-point coordinates (x,y)
* is located in the pixel with coordinates (std::round(x), std::round(y)).
*
* Translating CurveViewRange coordinates to pixel coordinates on the screen:
* Along the horizontal axis
* Pixel / physical coordinate CurveViewRange coordinate
* 0 xMin()
* m_frame.width() - 1 xMax()
* Along the vertical axis
* Pixel / physical coordinate CurveViewRange coordinate
* 0 yMax()
* m_frame.height() - 1 yMin()
*/
const float CurveView::pixelWidth() const {
return (m_curveViewRange->xMax() - m_curveViewRange->xMin()) / m_frame.width();
return (m_curveViewRange->xMax() - m_curveViewRange->xMin()) / (m_frame.width() - 1);
}
const float CurveView::pixelHeight() const {
return (m_curveViewRange->yMax() - m_curveViewRange->yMin()) / (m_frame.height() - 1);
}
float CurveView::pixelToFloat(Axis axis, KDCoordinate p) const {
return (axis == Axis::Horizontal) ?
m_curveViewRange->xMin() + p * pixelWidth() :
m_curveViewRange->yMax() - p * pixelHeight();
}
float CurveView::floatToPixel(Axis axis, float f) const {
float result = (axis == Axis::Horizontal) ?
(f - m_curveViewRange->xMin()) / pixelWidth() :
(m_curveViewRange->yMax() - f) / pixelHeight();
/* Make sure that the returned value is between the maximum and minimum
* possible values of KDCoordinate. */
if (result == NAN) {
return NAN;
} else if (result < KDCOORDINATE_MIN) {
return KDCOORDINATE_MIN;
} else if (result > KDCOORDINATE_MAX) {
return KDCOORDINATE_MAX;
} else {
return result;
}
}
void CurveView::drawGridLines(KDContext * ctx, KDRect rect, Axis axis, float step, KDColor boldColor, KDColor lightColor) const {
@@ -118,11 +163,6 @@ float CurveView::gridUnit(Axis axis) const {
return (axis == Axis::Horizontal ? m_curveViewRange->xGridUnit() : m_curveViewRange->yGridUnit());
}
KDCoordinate CurveView::pixelLength(Axis axis) const {
assert(axis == Axis::Horizontal || axis == Axis::Vertical);
return (axis == Axis::Horizontal ? m_frame.width() : m_frame.height());
}
int CurveView::numberOfLabels(Axis axis) const {
float labelStep = 2.0f * gridUnit(axis);
float minLabel = std::ceil(min(axis)/labelStep);
@@ -130,28 +170,6 @@ int CurveView::numberOfLabels(Axis axis) const {
return maxLabel - minLabel + 1;
}
float CurveView::pixelToFloat(Axis axis, KDCoordinate p) const {
float pixelLen = pixelLength(axis);
float minA = min(axis);
KDCoordinate pixels = axis == Axis::Horizontal ? p : pixelLen - p;
return minA + pixels*(max(axis)-minA)/pixelLen;
}
float CurveView::floatToPixel(Axis axis, float f) const {
float fraction = (f-min(axis))/(max(axis)-min(axis));
fraction = axis == Axis::Horizontal ? fraction : 1.0f - fraction;
/* Fraction is a float that translates the relative position of f on the axis.
* When fraction is between 0 and 1, f is visible. Otherwise, f is out of the
* visible window. We need to clip fraction to avoid big float issue (often
* due to float to int transformation). However, we cannot clip fraction
* between 0 and 1 because drawing a sized stamp on the extern boarder of the
* window should still be visible. We thus arbitrarily clip fraction between
* -10 and 10. */
fraction = fraction < -10.0f ? -10.0f : fraction;
fraction = fraction > 10.0f ? 10.0f : fraction;
return pixelLength(axis)*fraction;
}
void CurveView::computeLabels(Axis axis) {
float step = gridUnit(axis);
int axisLabelsCount = numberOfLabels(axis);

View File

@@ -37,6 +37,7 @@ public:
void setOkView(View * okView);
void setForceOkDisplay(bool force) { m_forceOkDisplay = force; }
const float pixelWidth() const;
const float pixelHeight() const;
protected:
CurveViewRange * curveViewRange() const { return m_curveViewRange; }
void setCurveViewRange(CurveViewRange * curveViewRange);
@@ -78,7 +79,6 @@ private:
float min(Axis axis) const;
float max(Axis axis) const;
float gridUnit(Axis axis) const;
KDCoordinate pixelLength(Axis axis) const;
virtual char * label(Axis axis, int index) const = 0;
int numberOfLabels(Axis axis) const;
/* Recursively join two dots (dichotomy). The method stops when the

View File

@@ -276,7 +276,7 @@ int InteractiveCurveViewController::closestCurveIndexVertically(bool goingUp, in
}
float InteractiveCurveViewController::cursorBottomMarginRatio() {
return (curveView()->cursorView()->minimalSizeForOptimalDisplay().height()/2+estimatedBannerHeight())/k_viewHeight;
return (curveView()->cursorView()->minimalSizeForOptimalDisplay().height()/2+estimatedBannerHeight())/(k_viewHeight-1);
}
float InteractiveCurveViewController::estimatedBannerHeight() const {

View File

@@ -20,10 +20,10 @@ public:
bool textFieldDidAbortEditing(TextField * textField) override;
bool textFieldDidReceiveEvent(TextField * textField, Ion::Events::Event event) override;
protected:
constexpr static float k_cursorRightMarginRatio = 0.04f; // (cursorWidth/2)/graphViewWidth
constexpr static float k_cursorLeftMarginRatio = 0.04f; // (cursorWidth/2)/graphViewWidth
virtual float cursorTopMarginRatio() { return 0.07f; } // (cursorHeight/2)/graphViewHeight
virtual float cursorBottomMarginRatio() = 0; // (cursorHeight/2+bannerHeight)/graphViewHeight
constexpr static float k_cursorRightMarginRatio = 0.04f; // (cursorWidth/2)/(graphViewWidth-1)
constexpr static float k_cursorLeftMarginRatio = 0.04f; // (cursorWidth/2)/(graphViewWidth-1)
virtual float cursorTopMarginRatio() { return 0.07f; } // (cursorHeight/2)/(graphViewHeight-1)
virtual float cursorBottomMarginRatio() = 0; // (cursorHeight/2+bannerHeight)/(graphViewHeight-1)
constexpr static float k_numberOfCursorStepsInGradUnit = 5.0f;
virtual bool handleZoom(Ion::Events::Event event);
virtual bool handleLeftRightEvent(Ion::Events::Event event);