]> git.donarmstrong.com Git - lilypond.git/blob - scm/bezier-tools.scm
Add '-dcrop' option to ps and svg backends
[lilypond.git] / scm / bezier-tools.scm
1 ;;;; This file is part of LilyPond, the GNU music typesetter.
2 ;;;;
3 ;;;; Copyright (C) 2010--2015 Carl D. Sorensen <c_sorensen@byu.edu>
4 ;;;;
5 ;;;; LilyPond is free software: you can redistribute it and/or modify
6 ;;;; it under the terms of the GNU General Public License as published by
7 ;;;; the Free Software Foundation, either version 3 of the License, or
8 ;;;; (at your option) any later version.
9 ;;;;
10 ;;;; LilyPond is distributed in the hope that it will be useful,
11 ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
12 ;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 ;;;; GNU General Public License for more details.
14 ;;;;
15 ;;;; You should have received a copy of the GNU General Public License
16 ;;;; along with LilyPond.  If not, see <http://www.gnu.org/licenses/>.
17
18 (define (make-coord x-value y-value)
19   "Make a coordinate pair from @var{x-valye} and @var{y-value}."
20   (cons x-value y-value))
21
22 (define (coord+ coord1 coord2)
23   "Add @var{coord1} to @var{coord2}, returning a coordinate."
24   (cons (+ (car coord1) (car coord2))
25         (+ (cdr coord1) (cdr coord2))))
26
27 (define (coord- coord1 coord2)
28   "Subtract @var{coord2} from @var{coord1}."
29   (cons (- (car coord1) (car coord2))
30         (- (cdr coord1) (cdr coord2))))
31
32 (define (coord* scalar coord)
33   "Multiply each component of @var{coord} by @var{scalar}."
34   (cons (* (car coord) scalar)
35         (* (cdr coord) scalar)))
36
37 (define (make-bezier point-0 point-1 point-2 point-3)
38   "Create a cubic bezier from the four control points."
39   (list point-0 point-1 point-2 point-3))
40
41 (define (interpolated-control-points control-points split-value)
42   "Interpolate @var{control-points} at @var{split-value}.  Return a
43 set of control points that is one degree less than @var{control-points}."
44   (if (null? (cdr control-points))
45       '()
46       (let ((first (car control-points))
47             (second (cadr control-points)))
48         (cons* (coord+ first (coord* split-value (coord- second first)))
49                (interpolated-control-points
50                 (cdr control-points)
51                 split-value)))))
52
53 (define (split-bezier bezier split-value)
54   "Split a cubic bezier defined by @var{bezier} at the value
55 @var{split-value}.  @var{bezier} is a list of pairs; each pair is
56 is the coordinates of a control point.  Returns a list of beziers.
57 The first element is the LHS spline; the second
58 element is the RHS spline."
59   (let* ((quad-points (interpolated-control-points
60                        bezier
61                        split-value))
62          (lin-points (interpolated-control-points
63                       quad-points
64                       split-value))
65          (const-point (interpolated-control-points
66                        lin-points
67                        split-value))
68          (left-side (list (car bezier)
69                           (car quad-points)
70                           (car lin-points)
71                           (car const-point)))
72          (right-side (list (car const-point)
73                            (list-ref lin-points 1)
74                            (list-ref quad-points 2)
75                            (list-ref bezier 3))))
76     (cons left-side right-side)))
77
78 (define (multi-split-bezier bezier start-t split-list)
79   "Split @var{bezier} at all the points listed in @var{split-list}.
80 @var{bezier} has a parameter value that goes from @var{start-t} to 1.
81 Returns a list of @var{(1+ (length split-list))} beziers."
82   (let* ((bezier-split (split-bezier bezier
83                                      (/ (- (car split-list) start-t)
84                                         (- 1 start-t))))
85          (left-bezier (car bezier-split))
86          (right-bezier (cdr bezier-split)))
87     (if (null? (cdr split-list))
88         bezier-split
89         (cons* left-bezier
90                (multi-split-bezier right-bezier
91                                    (car split-list)
92                                    (cdr split-list))))))
93
94
95 (define (bezier-sandwich-list top-bezier bottom-bezier)
96   "create the list of control points for a bezier sandwich consisting
97 of @var{top-bezier} and @var{bottom-bezier}."
98   (list (list-ref bottom-bezier 1)
99         (list-ref bottom-bezier 2)
100         (list-ref bottom-bezier 3)
101         (list-ref bottom-bezier 0)
102         (list-ref top-bezier 2)
103         (list-ref top-bezier 1)
104         (list-ref top-bezier 0)
105         (list-ref top-bezier 3)))