2 simple-spacer-scheme.cc -- implement Simple_spacer
4 source file of the GNU LilyPond music typesetter
6 (c) 2005--2009 Han-Wen Nienhuys <hanwen@xs4all.nl>
11 #include "paper-column.hh"
14 #include "simple-spacer.hh"
16 LY_DEFINE (ly_solve_spring_rod_problem
, "ly:solve-spring-rod-problem",
17 4, 1, 0, (SCM springs
, SCM rods
, SCM length
, SCM ragged
),
18 "Solve a spring and rod problem for @var{count} objects, that"
19 " are connected by @var{count}-1 @var{springs}, and an arbitrary"
20 " number of @var{rods}. @var{count} is implicitly given by"
21 " @var{springs} and @var{rods}. The @var{springs} argument has"
22 " the format @code{(ideal, inverse_hook)} and @var{rods} is of"
23 " the form @code{(idx1, idx2, distance)}.\n"
25 "@var{length} is a number, @var{ragged} a boolean.\n"
27 "The function returns a list containing the force (positive for"
28 " stretching, negative for compressing and @code{#f} for"
29 " non-satisfied constraints) followed by @var{spring-count}+1"
30 " positions of the objects.")
32 int len
= scm_ilength (springs
);
34 return scm_list_2 (scm_from_double (0.0), scm_from_double (0.0));
36 SCM_ASSERT_TYPE (len
>= 0, springs
, SCM_ARG1
, __FUNCTION__
, "list of springs");
37 SCM_ASSERT_TYPE (scm_ilength (rods
) > 0, rods
, SCM_ARG1
, __FUNCTION__
, "list of rods");
38 LY_ASSERT_TYPE (scm_is_number
, length
, 3);
40 bool is_ragged
= ragged
== SCM_BOOL_T
;
42 for (SCM s
= springs
; scm_is_pair (s
); s
= scm_cdr (s
))
44 Real ideal
= scm_to_double (scm_caar (s
));
45 Real inv_hooke
= scm_to_double (scm_cadar (s
));
47 Spring
sp (ideal
, 0.0);
48 sp
.set_inverse_compress_strength (inv_hooke
);
49 sp
.set_inverse_stretch_strength (inv_hooke
);
51 spacer
.add_spring (sp
);
54 for (SCM s
= rods
; scm_is_pair (s
); s
= scm_cdr (s
))
56 SCM entry
= scm_car (s
);
57 int l
= scm_to_int (scm_car (entry
));
58 int r
= scm_to_int (scm_cadr (entry
));
59 entry
= scm_cddr (entry
);
61 Real distance
= scm_to_double (scm_car (entry
));
62 spacer
.add_rod (l
, r
, distance
);
65 spacer
.solve (scm_to_double (length
), is_ragged
);
67 vector
<Real
> posns
= spacer
.spring_positions ();
69 SCM force_return
= spacer
.fits () ? scm_from_double (spacer
.force ()) : SCM_BOOL_F
;
72 for (vsize i
= posns
.size (); i
--;)
73 retval
= scm_cons (scm_from_double (posns
[i
]), retval
);
75 retval
= scm_cons (force_return
, retval
);