2 simple-spacer-scheme.cc -- implement Simple_spacer
4 source file of the GNU LilyPond music typesetter
6 (c) 2005--2007 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} springs, and an arbitrary number of rods "
20 "Springs have the format (ideal, inverse_hooke) and rods (idx1, idx2, distance) "
21 "@var{length} is a number, @var{ragged} a boolean "
22 "Return: a list containing the force (positive for stretching, "
23 "negative for compressing and #f for non-satisfied constraints) "
24 "followed by the @var{spring-count}+1 positions of the objects. ")
26 int len
= scm_ilength (springs
);
28 return scm_list_2 (scm_from_double (0.0), scm_from_double (0.0));
30 SCM_ASSERT_TYPE (len
>= 0, springs
, SCM_ARG1
, __FUNCTION__
, "list of springs");
31 SCM_ASSERT_TYPE (scm_ilength (rods
) > 0, rods
, SCM_ARG1
, __FUNCTION__
, "list of rods");
32 LY_ASSERT_TYPE (scm_is_number
, length
, 3);
34 bool is_ragged
= ragged
== SCM_BOOL_T
;
36 for (SCM s
= springs
; scm_is_pair (s
); s
= scm_cdr (s
))
38 Real ideal
= scm_to_double (scm_caar (s
));
39 Real inv_hooke
= scm_to_double (scm_cadar (s
));
41 spacer
.add_spring (ideal
, inv_hooke
);
44 for (SCM s
= rods
; scm_is_pair (s
); s
= scm_cdr (s
))
46 SCM entry
= scm_car (s
);
47 int l
= scm_to_int (scm_car (entry
));
48 int r
= scm_to_int (scm_cadr (entry
));
49 entry
= scm_cddr (entry
);
51 Real distance
= scm_to_double (scm_car (entry
));
52 spacer
.add_rod (l
, r
, distance
);
55 spacer
.solve (scm_to_double (length
), is_ragged
);
57 vector
<Real
> posns
= spacer
.spring_positions ();
59 SCM force_return
= spacer
.fits () ? scm_from_double (spacer
.force ()) : SCM_BOOL_F
;
62 for (vsize i
= posns
.size (); i
--;)
63 retval
= scm_cons (scm_from_double (posns
[i
]), retval
);
65 retval
= scm_cons (force_return
, retval
);