X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=lily%2Fskyline.cc;h=455ebb2b9b5c9897c93f8effeb5a5968d3dd3328;hb=6e227b10eed0ebe522ca7512eb7d2cc1d9561e64;hp=1d7782008dae7df5f0ccbd28184cafa569ff323b;hpb=c659cb200486c2f908703696a1b2873e78c8160a;p=lilypond.git diff --git a/lily/skyline.cc b/lily/skyline.cc index 1d7782008d..455ebb2b9b 100644 --- a/lily/skyline.cc +++ b/lily/skyline.cc @@ -1,43 +1,41 @@ -/* +/* skyline.cc -- implement Skyline_entry and funcs. source file of the GNU LilyPond music typesetter - (c) 2002--2004 Han-Wen Nienhuys + (c) 2002--2005 Han-Wen Nienhuys */ -#include "skyline.hh" +#include "skyline.hh" /* A skyline is a shape of the form: - ---- - | | - ---------| | - | | - | | - | |______ + ---- + | | + ---------| | + | | + | | + | |______ --------| |___ - + This file deals with building such skyline structure, and computing the minimum distance between two opposing skylines. - - + + Invariants for a skyline: skyline[...].width_ forms a partition of the real interval, where the segments are adjacent, and ascending. Hence we have - + skyline.top ().width_[RIGHT] = inf skyline[0].width_[LEFT] = -inf - - */ - +*/ -const Real EPS = 1e-12; +const Real EPS = 1e-12; /* TODO: avoid unnecessary fragmentation. @@ -52,12 +50,12 @@ insert_extent_into_skyline (Array *line, Box b, Axis line_axis, Interval extent = b[line_axis]; if (extent.is_empty ()) return; - + Real stick_out = b[other_axis (line_axis)][d]; /* - Intersect each segment of LINE with EXTENT, and if non-empty, insert relevant segments. - */ + Intersect each segment of LINE with EXTENT, and if non-empty, insert relevant segments. + */ for (int i = line->size (); i--;) { Interval w = line->elem (i).width_; @@ -65,32 +63,30 @@ insert_extent_into_skyline (Array *line, Box b, Axis line_axis, if (extent[LEFT] >= w[RIGHT]) break; - + Real my_height = line->elem (i).height_; - if (!w.is_empty () && - w.length () > EPS - && d* (my_height - stick_out) < 0) + if (!w.is_empty () + && w.length () > EPS + && d * (my_height - stick_out) < 0) { Interval e1 (line->elem (i).width_[LEFT], extent[LEFT]); Interval e3 (extent[RIGHT], line->elem (i).width_[RIGHT]); if (!e3.is_empty () && e3.length () > EPS) - line->insert (Skyline_entry (e3, my_height), i+1); + line->insert (Skyline_entry (e3, my_height), i + 1); line->elem_ref (i).height_ = stick_out; line->elem_ref (i).width_ = w; if (!e1.is_empty () && e1.length () > EPS) - line->insert (Skyline_entry (e1, my_height), i ); + line->insert (Skyline_entry (e1, my_height), i); } - - } } void -merge_skyline (Array * a1, - Array const & a2, +merge_skyline (Array *a1, + Array const &a2, Direction dir) { for (int i = 0; i < a2.size (); i++) @@ -98,13 +94,12 @@ merge_skyline (Array * a1, Box b; b[X_AXIS] = a2[i].width_; b[Y_AXIS][dir] = a2[i].height_; - b[Y_AXIS][-dir] = dir * infinity_f ; + b[Y_AXIS][-dir] = dir * infinity_f; insert_extent_into_skyline (a1, b, X_AXIS, dir); } } - Array empty_skyline (Direction d) { @@ -115,7 +110,7 @@ empty_skyline (Direction d) i.swap (); Skyline_entry e; e.width_ = i; - e.height_ = -d * infinity_f; + e.height_ = -d * infinity_f; skyline.push (e); return skyline; } @@ -132,46 +127,44 @@ extents_to_skyline (Array const &extents, Axis a, Direction d) We could do a lot better (n log (n), using a balanced tree) but that seems overkill for now. - */ - for (int j = extents.size (); j--; ) + */ + for (int j = extents.size (); j--;) insert_extent_into_skyline (&skyline, extents[j], a, d); return skyline; } - - /* minimum distance that can be achieved between baselines. "Clouds" is a skyline pointing down. This is an O (n) algorithm. - */ +*/ Real skyline_meshing_distance (Array const &buildings, Array const &clouds) { int i = buildings.size () -1; - int j = clouds.size () -1; + int j = clouds.size () -1; + + Real distance = -infinity_f; - Real distance = - infinity_f; - while (i > 0 || j > 0) { Interval w = buildings[i].width_; w.intersect (clouds[j].width_); - + if (!w.is_empty ()) - distance = distance >? (buildings[i].height_ - clouds[j].height_); + distance = max (distance, (buildings[i].height_ - clouds[j].height_)); - if (i>0 && buildings[i].width_[LEFT] >= clouds[j].width_[LEFT]) + if (i > 0 && buildings[i].width_[LEFT] >= clouds[j].width_[LEFT]) { i--; } - else if (j > 0 && buildings[i].width_[LEFT] <= clouds[j].width_[LEFT]) + else if (j > 0 && buildings[i].width_[LEFT] <= clouds[j].width_[LEFT]) { j--; - } + } } return distance; @@ -186,12 +179,11 @@ Skyline_entry::Skyline_entry (Interval i, Real r) { width_ = i; height_ = r; - } void heighten_skyline (Array *buildings, Real ground) { for (int i = 0; i < buildings->size (); i++) - buildings->elem_ref (i).height_ += ground; + buildings->elem_ref (i).height_ += ground; }