~ubuntu-branches/ubuntu/precise/lilypond/precise

« back to all changes in this revision

Viewing changes to lily/simple-spacer-scheme.cc

  • Committer: Bazaar Package Importer
  • Author(s): Thomas Bushnell, BSG
  • Date: 2006-12-19 10:18:12 UTC
  • mfrom: (3.1.4 feisty)
  • Revision ID: james.westby@ubuntu.com-20061219101812-7awtjkp0i393wxty
Tags: 2.8.7-3
scripts/midi2ly.py: When setting DATADIR, find Lilypond python files
in the @TOPLEVEL_VERSION@ directory, not 'current'.  Patch thanks to
Chris Lamb (chris@chris-lamb.co.uk).  (Closes: #400550)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
  simple-spacer-scheme.cc -- implement Simple_spacer
 
3
 
 
4
  source file of the GNU LilyPond music typesetter
 
5
 
 
6
  (c) 2005--2006 Han-Wen Nienhuys <hanwen@xs4all.nl>
 
7
*/
 
8
 
 
9
#include <cstdio>
 
10
 
 
11
#include "paper-column.hh"
 
12
#include "spring.hh"
 
13
#include "warn.hh"
 
14
#include "simple-spacer.hh"
 
15
 
 
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, 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. ")
 
25
{
 
26
  int len = scm_ilength (springs);
 
27
  if (len == 0)
 
28
    return scm_list_2 (scm_from_double (0.0), scm_from_double (0.0));
 
29
 
 
30
  SCM_ASSERT_TYPE (len >= 0, springs, SCM_ARG1, __FUNCTION__, "list of springs");
 
31
  SCM_ASSERT_TYPE (scm_ilength (rods) >= 0, rods, SCM_ARG2, __FUNCTION__, "list of rods");
 
32
  SCM_ASSERT_TYPE (scm_is_number (length) || length == SCM_BOOL_F,
 
33
                   length, SCM_ARG3, __FUNCTION__, "number or #f");
 
34
 
 
35
  bool is_ragged = ragged == SCM_BOOL_T;
 
36
  Simple_spacer spacer;
 
37
  for (SCM s = springs; scm_is_pair (s); s = scm_cdr (s))
 
38
    {
 
39
      Real ideal = scm_to_double (scm_caar (s));
 
40
      Real hooke = scm_to_double (scm_cadar (s));
 
41
 
 
42
      spacer.add_spring (ideal, 1 / hooke);
 
43
    }
 
44
 
 
45
  for (SCM s = rods; scm_is_pair (s); s = scm_cdr (s))
 
46
    {
 
47
      SCM entry = scm_car (s);
 
48
      int l = scm_to_int (scm_car (entry));
 
49
      int r = scm_to_int (scm_cadr (entry));
 
50
      entry = scm_cddr (entry);
 
51
 
 
52
      Real distance = scm_to_double (scm_car (entry));
 
53
      spacer.add_rod (l, r, distance);
 
54
    }
 
55
 
 
56
  spacer.line_len_ = scm_to_double (length);
 
57
 
 
58
  if (is_ragged)
 
59
    spacer.my_solve_natural_len ();
 
60
  else
 
61
    spacer.my_solve_linelen ();
 
62
 
 
63
  vector<Real> posns;
 
64
  posns.push_back (0.0);
 
65
  for (vsize i = 0; i < spacer.springs_.size (); i++)
 
66
    {
 
67
      Real l = spacer.springs_[i].length ((is_ragged) ? 0.0 : spacer.force_);
 
68
      posns.push_back (posns.back () + l);
 
69
    }
 
70
 
 
71
  SCM force_return = SCM_BOOL_F;
 
72
  if (!isinf (spacer.force_)
 
73
      && (spacer.is_active () || is_ragged))
 
74
    force_return = scm_from_double (spacer.force_);
 
75
 
 
76
  if (is_ragged
 
77
      && posns.back () > spacer.line_len_)
 
78
    force_return = SCM_BOOL_F;
 
79
 
 
80
  SCM retval = SCM_EOL;
 
81
  for (vsize i = posns.size (); i--;)
 
82
    retval = scm_cons (scm_from_double (posns[i]), retval);
 
83
 
 
84
  retval = scm_cons (force_return, retval);
 
85
  return retval;
 
86
}