Apply collision avoidance rules for marcato to sforzato accent as well
I'm working on a concert band score that includes many, many examples of this articulation:
The issue here is that, unlike the staccato on the second note, the sforzato on the first note is not offset by the presence of the slur. I can't even calculate the amount of time it would take me to adjust every single incidence of this. What's interesting is that, if I replace the sforzato with a marcato, I see that the marcato clearly is offset to avoid colliding with the slur.
So, my feature request is very simple: simply apply the same layout rules for marcato/slur interaction to sforzato/slur interactions.
Attachment | Size |
---|---|
accent-slur.png | 2.64 KB |
Comments
Is this reasonable? Is it feasible? I suspect that it would be incredibly easy—just copy and paste a few lines of code from one place to another, perhaps with a "find-and-replace" operation to rename a word or two. The problem is that I don't have the knowledge to make that pull request, so I'm asking someone else to.
It's reaosnable, and probably feasible, but doubtful that easy. The code for articulation placement is full of special cases that each need to be handled differently, and the marcato placement code is rather different from the sforzando placement code. So the collision avoidance code would probably need to differ as well.
Well, I'll keep waiting. This is the first score I might be likely to publish, but not while this issue exists (by the way, should I reclassify this as a bug report? Or a task?). When possible, I'd very much like to see this worked out.
See also https://musescore.org/en/node/76576.
I looked at the code again. Sforzato and marcato are handled quite differently internally - they obey different rules, so unfortunately it is *not* just a matter of copying the marcato code. Not saying it isn't possible, just not *that* simple. Meanwhile, just leave this as a feature request, because that's exactly what it is.
Considering that thousands upon thousands of scores have been published either before notation software even existed, or with notation software with less sophisticated automatic layout that required more manual adjustment, and that literally millions of manual adjustments have been made over the years to produce the final results, I wouldn't let the fact that these markings will need manual adjustment stop you. Yes, it's work, but no more work than virtually everyone who has ever published a score has done many times over as well. It's just how it is.
It might be possible to completely automate collision avoidance using a points-based system or a cost-based system. In such a system you define rules about how many "points" a particular positioning of symbols is worth, and you choose the layout that is worth the least points (points are bad!). To use sforzato as an example:
Points rules for sforzato:
So the sforzato symbol would always be at the default position, unless there was a collision in which case it would almost always be moved above the colliding element.
Such a system would probably take quite a bit of work to set up initially but it would be trivial to add new rules later and even refine existing ones.
It could even be extended to controlling things like page layout automatically. Ideally music exactly fills a page. Any remaining space is a waste, so...
Rules for trying to force the music to exactly fill a page:
Now MuseScore automatically adjusts the "stretch" and "spatium" units to make the music exactly fill a page to a maximum of 20 points. If 20 points of adjustment can't do it then the music is left half-filling a page.
Ooh! "Smart" positioning , plus! Sounds like a lot of work, though. Are you offering? ;-)
This type of system can be good, but computationally extremely expensive. That's the balancing act we are trying to do here - get the best placement we can in essentially just a single pass, so response time isn't LilyPond-slow. Keep in mind, we layo out the entire score on every edit. If some day we are able to optimize that to only layout what is necessary, this would definitely open up doors for things like what is described here.
A points based method would indeed be computationally expensive. Some ways to reduce the load:
Re. "Are you offering to do this?"
I'm just starting a Master's degree in Human Computer Interaction so I don't have much free time at the moment, but I have lots of ideas to contribute! After my degree I will be able to help more, and be qualified to do so! Anyone is welcome to have a go at implementing my ideas in the meantime, and I might have a go myself if I find a spare moment in which to do so...
Why don't you have a go at coding, Zack? You're pretty active on these forums, but if you spent a little bit of that time learning to code I think you'd get into it quite quickly. I can help you get started if you want. This is too big a task to start with, but there are plenty of smaller bugs and minor annoyances that you could have a go at tackling. Or you could try writing a plugin?
I was about to say (actually, I thought I had said, but it appears I never clicked "Save"—luckily the tab was still open):
As to contributing to the code, I've often considered it but a) I'm pretty busy myself (among other things, preparing to apply to music school); and b) it's not just that I'm not familiar with MuseScore's code—I really know absolutely nothing about any type of computer code or language at all. Helping me get started would probably be more difficult than writing the collision avoidance algorithm. ;-)
I am not opposed to the semi-automatic thing, but I don't think that is terribly popular. As for the ways of reducing the laod, well, yes, it's those sort of things we want to do across the board to make layout faster - only redoing what is needed. Right now, the code just isn't structured in a way that makes this very feasible.
What to do once a collision has been detected (like the "point based" algorithm hinted at above) is just one part of the task; the other part, possibly the more complex, is the collision detection itself!
Element bounding boxes cannot be used: look at the example at the top of the thread, the staccato dot is inside the bounding box of the slur and a bounding box-based detection would (mis-)place the dot and/or the slur who knows where!
If I am not mistaken, Marc implemented an algorithm for accidental spacing which uses a box-minus-variable-corners model, tuned for accidentals; other kind of score elements would need specific models; in particular slurs, varying a lot in size and shape, may require rather sophisticated models in order to determine their 'repulsion areas'; also there are elements which may be embedded within the area occupied by a slur and other which cannot. A general algorithm for collision detection with slurs is going to be very complex.
Let's just remember that the specific issue at hand is for sforzato positioning relative to slurs. The rest of it is really a whole other conversation.
@Zack true, but a general solution is always preferable
@Miwarre it might be possible to use the font's raw vector data to determine a collision, though admittedly this would probably be pretty difficult to code and quite processor intensive.
Edit: The accepted answer to this Stack Overflow question gives an example of something similar using Javascript, so perhaps it wouldn't be too difficult or processor intensive after all! (You can try it here, click on the letters and the turn red. Admittedly a mouse-click is only a single point whereas detecting overlapping symbols requires many points to be evaluated, but JavaScript isn't as fast as C++).
For the record, yes, I did use a bounding-box-with-cutouts model for accidental placement. The SMuFL folks added that information to the standard and to the Bravura glyphs specifically at my request. Slurs would be trickier, though, since they aren't glyphs.
The way we do slur avoidance right now is not sophisticated at all - if there is a slur, we raise the articulation some fixed amount, only for articulations that happen to be handled in one particular part of the code. Sforzato is handled in a separate part of the code because, among other things, we also go to pains to avoid the staff lines.
If there is a slur or tie present at all, the sforzato should be entirely outside of the lines of the staff: https://musescore.org/en/node/61551
Not a bad idea, but I'm not sure that's always desirable or always enough. Consider for example:
Not saying this sort of thing isn't worth trying, but my fear is, we come up with some sort of hack like this that works sometimes, doens't work other times, and people make their manual adjustments based on that, then later someone complains again and we try to change the hack, and suddenly the manual adjustments applied previously aren't good. To some extent there are ways around that, but it gets complicated really fast.
That's why I often point out it is in some cases better to have consistent / predictable defaults thatn to implement a half-solution that ends up causing problems down the road. Not saying this is definitely in that category, but it's definitely a valid concern.
Ah, different stem directions. I should have thought of that.
See also discussion at More systematic layout for articulations .
The case is correctly processed in current master. It is better to create new request with the related case in current master.
Automatically closed -- issue fixed for 2 weeks with no activity.