Interpolate poly-line with view-point #6481

This commit is contained in:
Robin Gareus 2020-04-10 17:48:07 +02:00
parent 6cc1e5e75d
commit 7bb8ca1e76
No known key found for this signature in database
GPG key ID: A090BCE02CF57F04
3 changed files with 54 additions and 5 deletions

View file

@ -45,6 +45,16 @@ protected:
void render_curve (Rect const&, Cairo::RefPtr<Cairo::Context>, Points const&, Points const&) const;
Points _points;
/* these return screen-cordidates of the most recent render_path() */
Duple const& leftedge () const { return _left; }
Duple const& rightedge () const { return _right; }
private:
static bool interpolate_line (Duple&, Duple const&, Coord const);
mutable Duple _left;
mutable Duple _right;
};
}

View file

@ -77,17 +77,56 @@ PolyItem::render_path (Rect const & /* area */, Cairo::RefPtr<Cairo::Context> co
}
Points::const_iterator i = _points.begin();
Duple c (item_to_window (Duple (i->x, i->y)));
Duple c0 (item_to_window (Duple (i->x, i->y)));
const double pixel_adjust = (_outline_width == 1.0 ? 0.5 : 0.0);
context->move_to (c.x + pixel_adjust, c.y + pixel_adjust);
++i;
while (c0.x < -1.) {
Duple c1 (item_to_window (Duple (i->x, i->y)));
if (interpolate_line(c0, c1, -1)) {
break;
}
if (++i == _points.end()) {
c1.x = 0;
context->move_to (c1.x + pixel_adjust, c1.y + pixel_adjust);
_left = _right = c1;
return;
}
c0 = c1;
}
context->move_to (c0.x + pixel_adjust, c0.y + pixel_adjust);
_left = c0;
while (i != _points.end()) {
c = item_to_window (Duple (i->x, i->y));
Duple c = item_to_window (Duple (i->x, i->y));
if (c.x > 16383) {
if (interpolate_line (c0, c, 16383)) {
context->line_to (c0.x + pixel_adjust, c0.y + pixel_adjust);
}
break;
}
context->line_to (c.x + pixel_adjust, c.y + pixel_adjust);
c0 = c;
++i;
}
_right = c0;
}
bool
PolyItem::interpolate_line (Duple& c0, Duple const& c1, Coord const x)
{
if (c1.x <= c0.x) {
return false;
}
if (x < c0.x || x > c1.x) {
return false;
}
c0.y += ((x - c0.x) / (c1.x - c0.x)) * (c1.y - c0.y);
c0.x = x;
return true;
}
void

View file

@ -71,8 +71,8 @@ PolyLine::render (Rect const & area, Cairo::RefPtr<Cairo::Context> context) cons
Duple y (0, _y1);
float y1 = item_to_window (y).y;
render_path (area, context);
Duple c0 (item_to_window (_points.back()));
Duple c1 (item_to_window (_points.front()));
Duple const& c0 (rightedge ());
Duple const& c1 (leftedge ());
if (c0.x < vp.x1) {
context->line_to (vp.x1, c0.y);
context->line_to (vp.x1, y1);