From 8cb9ecce8fe4de67c776603dacc9c7f270b3c8bf Mon Sep 17 00:00:00 2001 From: David Kastrup Date: Tue, 30 Jun 2015 00:04:49 +0200 Subject: [PATCH] Issue 4468/1: stencil-integrate.cc: root out "slopes" They are quite unsuitable for the computational geometry performed here. Their use rendered the code inefficient, obtuse, and unreliable. Contains several other fixes like removing duplicate calculations and wrong values. The C++ module is no longer used. It had only been used for calculating sin and cos in an obscure manner. --- lily/bezier.cc | 10 ++-- lily/include/bezier.hh | 2 +- lily/include/misc.hh | 1 - lily/misc.cc | 19 ------- lily/stencil-integral.cc | 120 ++++++++++++++------------------------- 5 files changed, 48 insertions(+), 104 deletions(-) diff --git a/lily/bezier.cc b/lily/bezier.cc index 41e7d898b8..b202d45dd6 100644 --- a/lily/bezier.cc +++ b/lily/bezier.cc @@ -140,8 +140,9 @@ Bezier::curve_point (Real t) const return o; } -Real -Bezier::slope_at_point (Real t) const +// The return value is normalized unless zero or indefinite. +Offset +Bezier::dir_at_point (Real t) const { Offset second_order[3]; Offset third_order[2]; @@ -152,10 +153,7 @@ Bezier::slope_at_point (Real t) const for (vsize i = 0; i < 2; i++) third_order[i] = ((second_order[i + 1] - second_order[i]) * t) + second_order[i]; - if (third_order[1][X_AXIS] - third_order[0][X_AXIS] == 0) - return infinity_f; - - return (third_order[1][Y_AXIS] - third_order[0][Y_AXIS]) / (third_order[1][X_AXIS] - third_order[0][X_AXIS]); + return (third_order[1] - third_order[0]).direction (); } /* diff --git a/lily/include/bezier.hh b/lily/include/bezier.hh index 681c8c1816..959afc5c4e 100644 --- a/lily/include/bezier.hh +++ b/lily/include/bezier.hh @@ -48,7 +48,7 @@ public: Polynomial polynomial (Axis)const; Offset curve_point (Real t) const; - Real slope_at_point (Real t) const; + Offset dir_at_point (Real t) const; Real curve_coordinate (Real t, Axis) const; static const int CONTROL_COUNT = 4; diff --git a/lily/include/misc.hh b/lily/include/misc.hh index b294b3188f..7226aceef8 100644 --- a/lily/include/misc.hh +++ b/lily/include/misc.hh @@ -61,7 +61,6 @@ normalize (Real x, Real x1, Real x2) Real directed_round (Real f, Direction d); -Offset get_point_in_y_direction (Offset orig, Real slope, Real dist, Direction dir); Real peak_around (Real epsilon, Real threshold, Real x); Real convex_amplifier (Real standard_x, Real increase_factor, Real x); string camel_case_to_lisp_identifier (const string &in); diff --git a/lily/misc.cc b/lily/misc.cc index 773e4ecad8..b930fd521a 100644 --- a/lily/misc.cc +++ b/lily/misc.cc @@ -18,8 +18,6 @@ along with LilyPond. If not, see . */ -#include - #include "misc.hh" #include "offset.hh" #include "warn.hh" @@ -98,20 +96,3 @@ camel_case_to_lisp_identifier (const string &in) return result; } - -Offset -get_point_in_y_direction (Offset orig, Real slope, Real dist, Direction dir) -{ - if (slope == infinity_f) - return orig + Offset (dir * dist, 0.0); - - Real x = slope == 0.0 ? 1.0 * dir : 1.0 * sign (slope) * dir; - Real y = slope * x; - Real angle = atan2 (y, x); - - complex orig_c (orig[X_AXIS], orig[Y_AXIS]); - complex to_move = polar (dist, angle); - complex res = orig_c + to_move; - - return Offset (real (res), imag (res)); -} diff --git a/lily/stencil-integral.cc b/lily/stencil-integral.cc index e72517e4ea..f5e437bced 100644 --- a/lily/stencil-integral.cc +++ b/lily/stencil-integral.cc @@ -34,7 +34,6 @@ when this transforms a point (x,y), the point is written as matrix: */ #include -#include #include "box.hh" #include "bezier.hh" #include "dimensions.hh" @@ -60,7 +59,9 @@ using namespace std; Real QUANTIZATION_UNIT = 0.2; -void create_path_cap (vector &boxes, vector > &buildings, PangoMatrix trans, Offset pt, Real rad, Real slope, Direction d); +void create_path_cap (vector &boxes, + vector > &buildings, + PangoMatrix trans, Offset pt, Real rad, Offset dir); struct Transform_matrix_and_expression { @@ -147,14 +148,13 @@ get_path_list (SCM l) return SCM_BOOL_F; } -Real -perpendicular_slope (Real s) +// Gets an orthogonal vector with same size to orig, pointing left +// (in the complex domain, a multiplication by i) + +Offset +get_normal (Offset orig) { - if (s == 0.0) - return infinity_f; - if (s == infinity_f) - return 0.0; - return -1.0 / s; + return Offset (-orig[Y_AXIS], orig[X_AXIS]); } //// END UTILITY FUNCTIONS @@ -180,7 +180,7 @@ make_draw_line_boxes (vector &boxes, vector > &buildings Real x1 = robust_scm2double (scm_car (expr), 0.0); expr = scm_cdr (expr); Real y1 = robust_scm2double (scm_car (expr), 0.0); - Real slope = x1 == x0 ? infinity_f : (y1 - y0) / (x1 - x0); + ////////////////////// if (x1 < x0) { @@ -189,11 +189,13 @@ make_draw_line_boxes (vector &boxes, vector > &buildings } Offset left (x0, y0); Offset right (x1, y1); + Offset dir = (right - left).direction (); Direction d = DOWN; do { - Offset inter_l = get_point_in_y_direction (left, perpendicular_slope (slope), thick / 2, d); - Offset inter_r = get_point_in_y_direction (right, perpendicular_slope (slope), thick / 2, d); + Offset outward = d * get_normal ((thick / 2) * dir); + Offset inter_l = left + outward; + Offset inter_r = right + outward; pango_matrix_transform_point (&trans, &inter_l[X_AXIS], &inter_l[Y_AXIS]); pango_matrix_transform_point (&trans, &inter_r[X_AXIS], &inter_r[Y_AXIS]); if ((inter_l[X_AXIS] == inter_r[X_AXIS]) || (inter_l[Y_AXIS] == inter_r[Y_AXIS])) @@ -207,11 +209,7 @@ make_draw_line_boxes (vector &boxes, vector > &buildings buildings.push_back (Drul_array (inter_l, inter_r)); else { - Offset inter_l = get_point_in_y_direction (left, perpendicular_slope (slope), thick / 2, d); - Offset inter_r = get_point_in_y_direction (right, perpendicular_slope (slope), thick / 2, d); - pango_matrix_transform_point (&trans, &inter_l[X_AXIS], &inter_l[Y_AXIS]); - pango_matrix_transform_point (&trans, &inter_r[X_AXIS], &inter_r[Y_AXIS]); - Real length = sqrt (((inter_l[X_AXIS] - inter_r[X_AXIS]) * (inter_l[X_AXIS] - inter_r[X_AXIS])) + ((inter_l[Y_AXIS] - inter_r[Y_AXIS]) * (inter_l[Y_AXIS] - inter_r[Y_AXIS]))); + Real length = (inter_l - inter_r).length (); vsize passes = (vsize) ((length * 2) + 1); vector points; @@ -220,7 +218,7 @@ make_draw_line_boxes (vector &boxes, vector > &buildings { Offset pt (linear_map (x0, x1, 0, passes, i), linear_map (y0, y1, 0, passes, i)); - Offset inter = get_point_in_y_direction (pt, perpendicular_slope (slope), thick / 2, d); + Offset inter = pt + outward; pango_matrix_transform_point (&trans, &inter[X_AXIS], &inter[Y_AXIS]); points.push_back (inter); } @@ -241,19 +239,17 @@ make_draw_line_boxes (vector &boxes, vector > &buildings create_path_cap (boxes, buildings, trans, - Offset (x0, y0), + left, thick / 2, - perpendicular_slope (slope), - Direction (sign (slope))); + -dir); // end line cap create_path_cap (boxes, buildings, trans, - Offset (x1, y1), + right, thick / 2, - perpendicular_slope (slope), - Direction (sign (-slope))); + dir); } } @@ -278,10 +274,8 @@ make_partial_ellipse_boxes (vector &boxes, vector > &bui end = M_PI * end / 180; if (end == start) end += (2 * M_PI); - complex sunit = polar (1.0, start); - complex eunit = polar (1.0, end); - Offset sp (real (sunit) * x_rad, imag (sunit) * y_rad); - Offset ep (real (eunit) * x_rad, imag (eunit) * y_rad); + Offset sp (cos (start) * x_rad, sin (start) * y_rad); + Offset ep (cos (end) * x_rad, sin (end) * y_rad); ////////////////////// Drul_array > points; Direction d = DOWN; @@ -291,11 +285,8 @@ make_partial_ellipse_boxes (vector &boxes, vector > &bui for (vsize i = 0; i < 1 + (vsize) quantization; i++) { Real ang = linear_map (start, end, 0, quantization, i); - complex coord = polar (1.0, ang); - Offset pt (real (coord) * x_rad, - imag (coord) * y_rad); - Real slope = pt[Y_AXIS] / pt[X_AXIS]; - Offset inter = get_point_in_y_direction (pt, perpendicular_slope (slope), th / 2, d); + Offset pt (cos (ang) * x_rad, sin (ang) * y_rad); + Offset inter = pt + d * get_normal ((th/2) * pt.direction ()); pango_matrix_transform_point (&trans, &inter[X_AXIS], &inter[Y_AXIS]); points[d].push_back (inter); } @@ -327,30 +318,22 @@ make_partial_ellipse_boxes (vector &boxes, vector > &bui if (th > 0.0) { // beg line cap - complex coord = polar (1.0, start); - Offset pt (real (coord) * x_rad, - imag (coord) * y_rad); - Real slope = pt[Y_AXIS] / pt[X_AXIS]; + Offset pt (cos (start) * x_rad, sin (start) * y_rad); create_path_cap (boxes, buildings, trans, pt, th / 2, - perpendicular_slope (slope), - Direction (sign (slope))); + -get_normal (pt)); // end line cap - coord = polar (1.0, start); - pt = Offset (real (coord) * x_rad, - imag (coord) * y_rad); - slope = pt[Y_AXIS] / pt[X_AXIS]; + pt = Offset (cos (end) * x_rad, sin (end) * y_rad); create_path_cap (boxes, buildings, trans, pt, th / 2, - perpendicular_slope (slope), - Direction (sign (-slope))); + get_normal (pt)); } } @@ -379,26 +362,18 @@ make_round_filled_box_boxes (vector &boxes, PangoMatrix trans, SCM expr) } void -create_path_cap (vector &boxes, vector > &buildings, PangoMatrix trans, Offset pt, Real rad, Real slope, Direction d) +create_path_cap (vector &boxes, + vector > &buildings, + PangoMatrix trans, Offset pt, Real rad, Offset dir) { - Real angle = atan (slope) * 180 / M_PI; - Real other = angle > 180 ? angle - 180 : angle + 180; - if (angle < other) - { - Real holder = other; - other = angle; - angle = holder; - } - other = (slope >= 0 && d == DOWN) || (slope < 0 && d == UP) - ? other + 360.0 - : other; + Real angle = dir.angle_degrees (); PangoMatrix new_trans (trans); pango_matrix_translate (&new_trans, pt[X_AXIS], pt[Y_AXIS]); make_partial_ellipse_boxes (boxes, buildings, new_trans, scm_list_n (scm_from_double (rad), scm_from_double (rad), - scm_from_double (angle), - scm_from_double (other), + scm_from_double (angle-90), + scm_from_double (angle+90), scm_from_double (0.0), SCM_BOOL_F, SCM_BOOL_F, @@ -448,17 +423,20 @@ make_draw_bezier_boxes (vector &boxes, vector > &buildin / QUANTIZATION_UNIT); do { - Offset first = get_point_in_y_direction (curve.control_[0], perpendicular_slope (curve.slope_at_point (0.0)), th / 2, d); + Offset first = curve.control_[0] + + d * get_normal ((th / 2) * curve.dir_at_point (0.0)); pango_matrix_transform_point (&trans, &first[X_AXIS], &first[Y_AXIS]); points[d].push_back (first); for (vsize i = 1; i < (vsize) quantization; i++) { Real pt = (i * 1.0) / quantization; - Offset inter = get_point_in_y_direction (curve.curve_point (pt), perpendicular_slope (curve.slope_at_point (pt)), th / 2, d); + Offset inter = curve.curve_point (pt) + + d * get_normal ((th / 2) *curve.dir_at_point (pt)); pango_matrix_transform_point (&trans, &inter[X_AXIS], &inter[Y_AXIS]); points[d].push_back (inter); } - Offset last = get_point_in_y_direction (curve.control_[3], curve.slope_at_point (1.0), th / 2, d); + Offset last = curve.control_[3] + + d * get_normal ((th / 2) * curve.dir_at_point (1.0)); pango_matrix_transform_point (&trans, &last[X_AXIS], &last[Y_AXIS]); points[d].push_back (last); } @@ -476,35 +454,23 @@ make_draw_bezier_boxes (vector &boxes, vector > &buildin boxes.push_back (b); } - // beg line cap if (th >= 0) { - Real slope = curve.slope_at_point (0.0); - d = Direction (sign (slope == 0.0 || abs (slope) == infinity_f - ? curve.slope_at_point (0.0001) - : slope)); - + // beg line cap create_path_cap (boxes, buildings, trans, curve.control_[0], th / 2, - perpendicular_slope (curve.slope_at_point (0.0)), - d); + -curve.dir_at_point (0.0)); // end line cap - slope = curve.slope_at_point (1.0); - d = Direction (sign (slope == 0.0 || abs (slope) == infinity_f - ? curve.slope_at_point (0.9999) - : slope)); - create_path_cap (boxes, buildings, trans, curve.control_[3], th / 2, - perpendicular_slope (curve.slope_at_point (1.0)), - d); + curve.dir_at_point (1.0)); } } -- 2.39.5