Object Coordinates in the Plane
A brief example of Object Coordinates proposed for MuseScore.
Here we have step 1 of the Bézier calculation: construction of the initial shape before collision, or realignment of the shoulder out of || with the base. (Note that, follwing the code, vertical offset is not yet appplied because of additional intervening steps).
Currently, recognizable calculations are done in an artificial x-y space:
1. Realign the curve to the x-y axis: Translate the points so that PP1 is at the coordinate origin, then rotate the points so that PP2 lies in the positive x-axis.
2. Calculate the height, width and offsets and apply them to the points
3. Transform (rotate then offset) the new points back to the object position.
Here, there are no atan() calls, no angular rotations, because there is no need to transform coordinates. We apply the values directly to the object. All angle transformations are eliminated, at the cost of doing the basic arithmetic already present, on two components simultaneously instead of one.
Eliminating rotation and angle calls does not remove the ability to rotate objects. In straight-line geometry, the trasformations: Translate, Scale, and Rotate are done using the vector components of the straight lines themselves. There is no need for the radial angle. Consider U. Because it is unit length, its components are
U = (cos θ, sin θ)
If we want to rotate it by another unit vector
W = (cos ϕ, sin ϕ)
... the new position is immediate from a single component-wise MADD:
"rotate U by θ" = (cos (θ+ϕ), sin(θ+ϕ)) = (cosθ cosϕ - sinθ sinϕ, sinθ cosϕ + cosθ sinϕ)
= ( (U.x * W.y) - (U.y * W.x), (U.y * W.x) + (U.x * W.y) )
Which can be bundled into a single multiplication with a suitable vector or matrix operator.
Note also that, because the natural parameters (shoulderOffset, shoulderWidth.. .etc) are transformed in x-y space and not in Object Space, the values stored in the object itself are not recognizable, but are absolute (x,y) offsets, which change continuously as the slur is moved about, creating an unnecessary layer of obfuscation between the code and the desired result. Eliminating the rotations will eventually -with enough cleaning and simplifying- eliminate the need for an extra set of dummy points: the shoulderOffset variable in the curve object should be the actual shoulderOffset, constant whenever the shape of the curve does not change. Parameters will be understandable at sight.
I hope the desirability of such a mass simplification is clear.