mirror of
https://github.com/UpsilonNumworks/Upsilon.git
synced 2026-01-20 01:08:15 +01:00
[python] matplotlib: change Store::Rectangle structure to (left, right,
top, bottom) and avoid rounding error when converting flaot rect to pixel
This commit is contained in:
@@ -182,8 +182,9 @@ mp_obj_t modpyplot_bar(size_t n_args, const mp_obj_t *args) {
|
||||
mp_float_t iW = mp_obj_get_float(wItems[wLength > 1 ? i : 0]);
|
||||
mp_float_t iB = mp_obj_get_float(bItems[bLength > 1 ? i : 0]);
|
||||
mp_float_t iX = mp_obj_get_float(xItems[i])-iW/2.0;
|
||||
mp_float_t iY = iH < 0.0 ? iB : iB + iH;
|
||||
sPlotStore->addRect(mp_obj_new_float(iX), mp_obj_new_float(iY), mp_obj_new_float(iW), mp_obj_new_float(std::fabs(iH)), color);
|
||||
mp_float_t iYStart = iH < 0.0 ? iB : iB + iH;
|
||||
mp_float_t iYEnd = iH < 0.0 ? iB + iH : iB;
|
||||
sPlotStore->addRect(mp_obj_new_float(iX), mp_obj_new_float(iX+iW), mp_obj_new_float(iYStart), mp_obj_new_float(iYEnd), color); // TODO: use float_binary_op?
|
||||
}
|
||||
return mp_const_none;
|
||||
}
|
||||
@@ -262,7 +263,7 @@ mp_obj_t modpyplot_hist(size_t n_args, const mp_obj_t *args) {
|
||||
mp_float_t upperBound = mp_obj_get_float(edgeItems[binIndex+1]);
|
||||
while (mp_obj_get_float(xItems[xIndex]) < upperBound || (binIndex == nBins - 1 && mp_obj_get_float(xItems[xIndex]) == upperBound)) {
|
||||
// Increment the bin count
|
||||
binItems[binIndex] = mp_obj_new_int(mp_obj_get_int(binItems[binIndex]) + 1); // TODO: better way?
|
||||
binItems[binIndex] = mp_obj_new_int(mp_obj_get_int(binItems[binIndex]) + 1); // TODO: better way? Use int_unary_op?
|
||||
xIndex++;
|
||||
if (xIndex == xLength) {
|
||||
break;
|
||||
@@ -273,8 +274,7 @@ mp_obj_t modpyplot_hist(size_t n_args, const mp_obj_t *args) {
|
||||
|
||||
KDColor color = Palette::nextDataColor(&paletteIndex);
|
||||
for (size_t i=0; i<nBins; i++) {
|
||||
mp_float_t width = mp_obj_get_float(edgeItems[i+1]) - mp_obj_get_float(edgeItems[i]);
|
||||
sPlotStore->addRect(edgeItems[i], binItems[i], mp_obj_new_float(width), binItems[i], color);
|
||||
sPlotStore->addRect(edgeItems[i], edgeItems[i+1], binItems[i], mp_obj_new_float(0.0), color);
|
||||
}
|
||||
return mp_const_none;
|
||||
}
|
||||
|
||||
@@ -121,16 +121,16 @@ template class PlotStore::ListIterator<PlotStore::Rect>;
|
||||
PlotStore::Rect::Rect(mp_obj_t tuple) {
|
||||
mp_obj_t * elements;
|
||||
mp_obj_get_array_fixed_n(tuple, 5, &elements);
|
||||
m_x = mp_obj_get_float(elements[0]);
|
||||
m_y = mp_obj_get_float(elements[1]);
|
||||
m_width = mp_obj_get_float(elements[2]);
|
||||
m_height = mp_obj_get_float(elements[3]);
|
||||
m_left = mp_obj_get_float(elements[0]);
|
||||
m_right = mp_obj_get_float(elements[1]);
|
||||
m_top = mp_obj_get_float(elements[2]);
|
||||
m_bottom = mp_obj_get_float(elements[3]);
|
||||
m_color = KDColor::RGB16(mp_obj_get_int(elements[4]));
|
||||
}
|
||||
|
||||
void PlotStore::addRect(mp_obj_t x, mp_obj_t y, mp_obj_t width, mp_obj_t height, KDColor c) {
|
||||
void PlotStore::addRect(mp_obj_t left, mp_obj_t right, mp_obj_t top, mp_obj_t bottom, KDColor c) {
|
||||
mp_obj_t color = mp_obj_new_int(c);
|
||||
mp_obj_t items[5] = {x, y, width, height, color};
|
||||
mp_obj_t items[5] = {left, right, top, bottom, color};
|
||||
checkFloatType(items, 4);
|
||||
mp_obj_t tuple = mp_obj_new_tuple(5, items);
|
||||
mp_obj_list_append(m_rects, tuple);
|
||||
@@ -204,10 +204,8 @@ void PlotStore::initRange() {
|
||||
updateRange(&xMin, &xMax, &yMin, &yMax, segment.xEnd(), segment.yEnd());
|
||||
}
|
||||
for (PlotStore::Rect rectangle : rects()) {
|
||||
float x = rectangle.x();
|
||||
float y = rectangle.y();
|
||||
updateRange(&xMin, &xMax, &yMin, &yMax, x, y);
|
||||
updateRange(&xMin, &xMax, &yMin, &yMax, x + rectangle.width(), y - rectangle.height());
|
||||
updateRange(&xMin, &xMax, &yMin, &yMax, rectangle.left(), rectangle.top());
|
||||
updateRange(&xMin, &xMax, &yMin, &yMax, rectangle.right(), rectangle.bottom());
|
||||
}
|
||||
checkPositiveRangeAndAddMargin(&xMin, &xMax);
|
||||
checkPositiveRangeAndAddMargin(&yMin, &yMax);
|
||||
|
||||
@@ -87,16 +87,16 @@ public:
|
||||
class Rect {
|
||||
public:
|
||||
Rect(mp_obj_t tuple);
|
||||
float x() const { return m_x; }
|
||||
float y() const { return m_y; }
|
||||
float width() const { return m_width; }
|
||||
float height() const { return m_height; }
|
||||
float left() const { return m_left; }
|
||||
float right() const { return m_right; }
|
||||
float top() const { return m_top; }
|
||||
float bottom() const { return m_bottom; }
|
||||
KDColor color() const { return m_color; }
|
||||
private:
|
||||
float m_x;
|
||||
float m_y;
|
||||
float m_width;
|
||||
float m_height;
|
||||
float m_left;
|
||||
float m_right;
|
||||
float m_top;
|
||||
float m_bottom;
|
||||
KDColor m_color;
|
||||
};
|
||||
|
||||
|
||||
@@ -54,13 +54,15 @@ void PlotView::traceSegment(KDContext * ctx, KDRect r, PlotStore::Segment segmen
|
||||
|
||||
static inline KDCoordinate maxKDCoordinate(KDCoordinate x, KDCoordinate y) { return x > y ? x : y; }
|
||||
void PlotView::traceRect(KDContext * ctx, KDRect r, PlotStore::Rect rect) const {
|
||||
KDCoordinate left = std::round(floatToPixel(Axis::Horizontal, rect.left()));
|
||||
KDCoordinate right = std::round(floatToPixel(Axis::Horizontal, rect.right()));
|
||||
KDCoordinate top = std::round(floatToPixel(Axis::Vertical, rect.top()));
|
||||
KDCoordinate bottom = std::round(floatToPixel(Axis::Vertical, rect.bottom()));
|
||||
KDRect pixelRect(
|
||||
std::round(floatToPixel(Axis::Horizontal, rect.x())),
|
||||
std::round(floatToPixel(Axis::Vertical, rect.y())),
|
||||
// Use std::ceil instead of std::round to avoid empty pixel line between bars and horizontal axis line
|
||||
// TODO: change stored rectangles to keep all summits?
|
||||
maxKDCoordinate(std::ceil(rect.width() / pixelWidth()), 1), // Rectangle should at least be visible
|
||||
std::ceil(rect.height() / pixelHeight())
|
||||
left,
|
||||
top,
|
||||
maxKDCoordinate(right - left, 1), // Rectangle should at least be visible
|
||||
bottom - top
|
||||
);
|
||||
ctx->fillRect(pixelRect, rect.color());
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user