mirror of
https://github.com/UpsilonNumworks/Upsilon.git
synced 2026-03-29 19:49:58 +02:00
[apps/shared/curve_view] Clarify coordinates' conventions
This commit is contained in:
committed by
EmilieNumworks
parent
07474caf6c
commit
585b77c38f
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user