Allgemein > Fragen zu Funktionen

Abstände von Ankerpunkten in vertikaler Richtung finden

<< < (2/3) > >>

xr:
Ich habe jetzt eine Lösung mit leichten Ungenauigkeiten.
Ich habe kurzerhand immer den letzten Wert aus der Liste genommen, den mir minimum-translations-alist ausgibt.

Hier der Code. Einfach Codebeispiel 3 damit ersetzen.


--- Code: ---\version "2.18.2"


#(define (get-cp cps nr xy)   
    (define wert
        (lambda (x)
            (cond
                ((= xy 0)
                     (car x))
                ((= xy 1)
                     (cdr x))
            )
        )
    )
         
      (cond
          ((= 0 nr)
               (wert (car cps)))
          ((= 1 nr)
               (wert (cadr cps)))
          ((= 2 nr)
               (wert (caddr cps)))
          ((= 3 nr)
               (wert (cadddr cps)))
      )
)

#(define* (set-controlPoint cps nr xy-values)
     (cond
         ((= 0 nr)
              (set-car! cps xy-values))
         ((= 1 nr)
              (set-car! (cdr cps) xy-values))
         ((= 2 nr)
              (set-car! (cddr cps) xy-values))
         ((= 3 nr)
              (set-car! (cdddr cps) xy-values))
     )
)


#(define (get-ctx grob)
    ;; get ctx from note-columns annotation
    (let* (
        (note-column (ly:grob-parent grob X))
        (ctx  (ly:grob-property note-column 'annotation))
        )
        ;; if slur has no parent (because it sits on a edge)
        ;; get ctx from another nc in the same VerticalAxisGroup
        (if (equal? ctx '())
            (let* (
                (va-group (get-parent-in-hierarchie grob 'VerticalAxisGroup))
                (els (get-elements va-group))
                ;; function for break-loop
                (fkt (lambda (x) (grob::name (list-ref els x ))))
                (nc (break-loop  els fkt 'NoteColumn ))
                )
                (set! ctx (ly:grob-property nc 'annotation))
            )
        )
    ctx)
)


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
#(define counter 0)
   
#(define (set-control-point grob rank ctx)
    ;; This method tries to calculate the vertical distances
    ;; between grobs in a PaperColumn.
    ;; It reads values from the minimum-translations-alist
    ;; of the VerticalAlignment
   
    (let* (
        (nc (get-parent-in-hierarchie grob 'NoteColumn))
        (pap (get-parent-in-hierarchie grob 'PaperColumn))
        (vertAlign (get-parent-in-hierarchie grob 'VerticalAlignment))
        (cps (ly:slur::calc-control-points grob))

        (mom (ly:grob-property pap 'when))
        (pos  (hash-ref ht-slurs mom))
               
        (trans-list (ly:grob-property vertAlign 'minimum-translations-alist))
        (ht-trans-list (make-hash-table))
       
        (actual-trans-list '())
        (chosen-value 0)
        )
       
        ;; this method uses the last value of the rank
        ;; given in the minimum-translation-list. It overwrites
        ;; all others before.
        (for-each (lambda (x)
            (hash-set! ht-trans-list (caar x)  (cdr x)))
            trans-list)

        (set! actual-trans-list (hash-ref ht-trans-list (1- rank)))
        ;; as the distances are related to the system line, but setting of the slur
        ;; is done from the first VerticalAxisGroup, the first value of the trans-list
        ;; is always substracted
        (set! chosen-value ( - (nth (modulo counter 5) actual-trans-list) (first actual-trans-list)))
       
        (fdisp 6
            (format #f "nr ~A"  counter)
            (format #f "Grob-Pos ~A"  pos)
            (format #f "value ~A"  chosen-value)
             )

          (set-controlPoint cps 0 `( -0.2 . ,chosen-value ))
          (ly:grob-set-property! grob 'control-points cps)

          (set! counter (1+ counter))
    )
)

#(define (set-control-points grob cps rank-interval)
   
    (let* (
        (ctx (get-ctx grob))
        (rank (car rank-interval))
        )
        (set-control-point grob rank ctx)
    )
)
--- Ende Code ---


Der Code dient als Beispiel und kann durchaus verfeinert werden. Z.B. wird der Hash-Table, der erstellt wird, bei jedem Durchlauf erneut erstellt. Einmal würde auch reichen.
Im Codebsp 2 könnte auch Code gestrichen werden.

Die Ungenauigkeiten, die ich oben erwähnt habe, sieht man, wenn man Bögen direkt an der h-Linie betrachtet. Manche müßten einen Tacken tiefer. Aber für meine Zwecke reicht das wohl so.


Gruß,
Xaver

harm6:

--- Zitat von: fugenkomponist ---harm, der von uns hier im Forum noch am meisten Ahnung von so Scheme-Sachen hat, hat in dem Thread auch schon geschrieben, d. h. er wird da wohl auch weiter mitlesen.

--- Ende Zitat ---

Eigentlich lese ich immer mit ;)
Jedoch habe ich zu häufig keine Zeit mich mit dem jeweiligen Anliegen zu beschäftigen und falls mir was dazu einfällt (was nicht notwendigerweise der Fall ist) das auch zu posten.
Aber jetzt ist ja Wochenende ...

@Xaver
Deinen Code habe ich compiliert, bislang aber nur flüchtig durchgesehen.
Mir ist unklar wie Du die Bögen setzen willst. Damit meine ich wo sollen sie anfangen und enden, nicht im Sinne von numerischen Werten, sondern welche Grobs Du treffen willst?
Du veränderst ja die spanner-bounds nicht...

Sonstige Beobachtungen:
(1)
Sobald Du
system-system-spacing.padding
auf einen anderen (hohen) Wert setzt stimmt alles nicht mehr.
Insoweit mein Interesse an den spanner-bounds
(2)
break-loop
ist in Deinen Beispielen nicht definiert und gibt unter bestimmten Bedingungen einen Fehler aus.
(3)
dloop ebenfalls
(4)
#(define (grob-name grob) ...
Es gibt grob::name im sourcecode, würde ich ersetzen/streichen. Später hast Du grob::name selbst verwendet ;)
(5)
statt
#(define (sum elemList)
  (if
    (null? elemList)
    0
    (+ (car elemList) (sum (cdr elemList)))
  )
)
vielleicht
#(define (sum elemList)
(if (every number? elemList)
    (apply + elemList)
    elemList))
Falls Du anderweitig sicher gestellt hast, daß die Liste wirklich nur Zahlen enthält kann man sich die fool-proof-Bedingung vielleicht sogar sparen.


Soweit erstmal.
Alles erstmal Kleinigkeiten bis auf die spanner-bounds.

Gruß,
  Harm

xr:
Hallo harms,

hier schonmal eine schnelle Antwort.


--- Zitat ---(2)
break-loop
ist in Deinen Beispielen nicht definiert und gibt unter bestimmten Bedingungen einen Fehler aus.
(3)
dloop ebenfalls
--- Ende Zitat ---

Hatte ich wohl vergessen zu kopieren. Hier der Code. Einfach einfügen.

--- Code: ---#(define (dloop vals)
    (define n 0)
    (for-each
        (lambda (x)
            (disp n)
            (if (list? n) (dloop n) n)
            (newline)
            (set! n (+ 1 n))
            (display x)
        )
        vals
    )
)
#(define (break-loop elements fkt condit)
    ;; elements => list
    ;; breaks loop when fkt result equals condit
    ;; or running out of elements
    ;; there should be a better solution for
    ;; the line: set! result ...
    (let* (
        (result #f)
        )
        (do ((i 1 (1+ i))
             (x (fkt 0)  (fkt i))
             )
            (
            (begin
                (set! result (list-ref elements (1- i) ))
                (= i (length elements)) or (equal? condit (fkt (1- i))))
            x)
        )
    result
    )
)

--- Ende Code ---


--- Zitat ---Mir ist unklar wie Du die Bögen setzen willst. Damit meine ich wo sollen sie anfangen und enden, nicht im Sinne von numerischen Werten, sondern welche Grobs Du treffen willst?
Du veränderst ja die spanner-bounds nicht...
--- Ende Zitat ---

Ich versuche die Werte numerisch zu berechnen. Ich habe da auch schon eine Lösung. Die Ausarbeitung dauert aber noch etwas.
Alles andere später.

Gruß,
Xaver

xr:

--- Zitat ---Du veränderst ja die spanner-bounds nicht...
--- Ende Zitat ---

Bei diesem Thema ging es mir auch nicht um horizontale Abstände, sondern allein um die vertikalen. Und die kann man innerhalb eines Systems mit den Werten aus der minimum-translations-alist bestimmen. (Spanner bräuchte ich doch nur für horizontale Abstände, oder nicht?)

Ich vermute, dass die Liste verschiedene Berechnungen Lilyponds zur optimalen Positionierung wiederspiegelt, und der letzte Wert dann die beste Annäherung ist. Aber das vermute ich nur, vielleicht ist es auch anders, und es gibt einen internen Vorgang, der aus all diesen Werten später den optimalen aussucht.

Xaver

xr:
Nachdem ich nun eine Weile und immer mal wieder mit der  minimum-translations-alist herumgespielt habe, ohne jedoch zu einer verläßlichen Lösung zu kommen, bin ich nun dazu übergegangen, die Lilyponddatei zweifach zu compilen. Beim ersten Mal werden die entsprechenden Werte ausgelesen, beim zweiten Mal dann eingesetzt.

Ausgelesen wird mit einer Funktion innerhalb einer Paper Umgebung, die erst angesprochen wird, wenn bereits alle Berechnungen abgeschlossen sind.

--- Code: ---\paper {   
    #(define (page-post-process layout pages)
        (get-slur-extents layout pages ))
}
--- Ende Code ---

Der Code geht mal wieder auf eine Anregung harms zurück:
http://lilypond.1069038.n5.nabble.com/intercepting-implicit-explicit-page-breaks-td194196.html#a194198

Wenn ich mein Ziel erreicht habe und halbwegs kommentierte und geordnete Dateien erzeugt haben werde, poste ich meine Lösung in diesem Thread:
https://liarchiv.joonet.de/index.php?topic=2503.0

Xaver

Navigation

[0] Themen-Index

[#] Nächste Seite

[*] Vorherige Sete

Zur normalen Ansicht wechseln