NavigationNext - Previous TOC
|
Perhaps one of the most basic need for reading something is that symbols are distinct from each other. This is also true for normal word processor, but in music notation the grphics are so sophisitcated that this very basic rule sometimes became very hard to manage. You will see in the developpement that the computation time is far to be neglectable from two factor
Definition :
A colision happen when two symbols are overriding.
At first a box could be a nice approximation. We call it the bounding box. For a some category of symbol like the slurs and beam this is not a correct simplification. And we define different type of possible base type to compute collisions.
When defining a bounding box we always have two points (x1,y1) (x2,y2). We always assume x1<x2 and y1<y2.
A bounding box is a simple box. That is the approximate collider corresponding to a symbol. A bounding box BB we can have its interior simply defined with an equation
x1 < x < x2 y1 < y < y2
Two symbols are collinging if interior are overiding.
Other symbol are a little harder to simplify to have this equation for resolving collisions. This is particulary true for stems and slurs that leaves big empty spaces if they are bounded by a simple box. For those we did the segment regression that is a simplifcation of the form of a slur or a stem. The interior of a segment regression is defined considering all the point of this segement a segment can be defined with the equation
SR{
x1 < x < x2
y = ax + b
}
But for the program we will use its extreme point to define it SR { (x1,y1), (x2,y2) }
With those 2 model of symbol simplification we want to build a fonction collide. There is so 4 types of collision. The collide operation is symetric, this means that Segment->collide(BBox)==BBox->collide(Segment) that is why we can group those operations in the same types of collision.
| X | Bounding Box | Segment Regression |
| Bounding Box | Type 1 | Type 2 |
| Segment Regression | Type 2 | Type 3 |
let us consider two bounding box :
BB{
x1 < x < x2
y1 < y < y2
}
and
BB'{
x1' < x < x2'
y1' < y < y2'
}
If a solution of this equation exists then BB and BB' are colliding. we assume x1 < x2 and y1 < y2
The algorithm is :
if x1>x2' : return false
if x1'>x2 : return false
if y1>y2' : return false
if y1'>y2 : return false
return true
x1>x2' == false x1'>x2 == false y1>y2' == false y1'>y2 == false return true Collision !
x1>x2' == false x1'>x2 == false y1>y2' == false y1'>y2 == true return false No Collision !
x1>x2' == false x1'>x2 == false y1>y2' == false y1'>y2 == false Collision !
let us consider a bounding box and a segment regression :
BB{
x1 < x < x2
y1 < y < y2
}
SR{
(x1', y1')
(x2', y2')
}
Algorithm
if x1>x2' : return false
if x1'>x2 : return false
This second test will be useless in theorical case but in practical it
will be a strong discimination that cost low. So it is more a statistic
decision that an algorithmic decision
xmin=max(x1,x1')
xmax=min(x2,x2')
If the two tests above passed then you can verify xmin<xmax
a=(y2'-y1')/(x2'-x1')
yleft'=(xmin - x1')*a+y1'
yright'=(xmax - x1')*a+y1'
if yleft' < y2 && xleft' > y1 return true
if yright' < y2 && xleft' > y1 return true
return false
In the example we skip the y bounding test but it is for the example. x1>x2' == false x1'>x2 == false xmin=max(x1,x1')=1 xmax=min(x2,x2')=1.7 a=(y2'-y1')/(x2'-x1')=.3/1.2=.25 yleft'=(xmin - x1')*a+y1'=(1-.5)*.25+.5=0.6125 yright'=(xmax - x1')*a+y1'=(1.7-.5)*.25+.5=.8 yleft' < y2 && xleft' > y1 == false if yright' < y2 && xleft' > y1 == false return false No Collision !
In the example we skip the y bounding test but it is for the example. x1>x2' == false x1'>x2 == false xmin=max(x1,x1')=1 xmax=min(x2,x2')=1.5 a=(y2'-y1')/(x2'-x1')=.5/.7=.7 yleft'=(xmin - x1')*a+y1'=(1-.8)*.7+1.3=1.16 yright'=(xmax - x1')*a+y1'=(1.5-.8)*.7+1.3=.8 yleft' < y2 && xleft' > y1 == true return true Collision !
Algorithm if x1>x2' : return false if x1'>x2 : return false We express the equation of the line suport of the segment y=ax+b a=(y2-y1)/(x2-x1) b=y1-x1*a a'=(y2'-y1')/(x2'-x1') b'=y1'-x1'*a for an x solution xsol we have axsol+b=a'xsol+b' if a=a' return false (to avoid floting point excpetion xsol=(b'-b)/(a-a') if xsol>x1&&xsol>x1'&&xsol<x2&&xsol<x2' return true return false
x1=1,x2=2,y1=1,y2=2,x1'=1,x2'=2,y1'=2,y2'=1 if x1>x2' : return false if x1'>x2 : return false a=(2-1)/(2-1)=1 a'=(1-1)/(2-1)=-1 b=1-1*1=0 b'=2-(-1*1)=3 xsol=(3-0)/(1-(-1)) xsol=1.5 xsol>1&&xsol>1&&xsol<2&&xsol<2 : true return true Collision !
x1=1,x2=2,y1=1,y2=2,x1'=1,x2'=2,y1'=1.5,y2'=2.5 if x1>x2' : return false if x1'>x2 : return false a=(2-1)/(2-1)=1 a'=(2.5-1.5)/(2-1)=1 b=1-1*1=0 b'=1.5-(1*1)=.5 xsol=(1-1)/(1-(1)) Floating point exception (Oh no...) It does not collide No Collision !
Implement the computeCollisions in the measure section We must care that a collision is detected only one time and so according to the index in the note symbol we must test the collision with only the symbol with following indexes.
There are various constraints in the representation of a musical score. The big thing you have to understand if you look in the graphical classes is how to classify the constraints.
A constraint is a geometrical dependency beetween to elements. In a constraint there is always a master element and a slave element. The rule is simple when the master element change its geometry then the slave element also change its geometry.
What we call geometry is a subset of the following properties :
Some elements like note have only X and Y, but they can be the master constraint for a Alteration.
There are many types of constraints, to make the code clear we have to divide it into classes :
This is probably the most important class of constraint. This constraint rules the time and X axis dependencies.
In every music notation the X axis on a score represent time. In a line that is a set of parts,every event happening at the same position in X is simultaneous to every symol that starts at the same X.
This kind of constraint apply to
This cconstaint apply to any symbol that is attached to a part. That is to say
This constraint apply to
Apply to
Apply to :