Walk from left to right, using a stack to keep track of what color you're on. Instead of a discrete map, use the 10 numbers in your dataset as the break-points.
Starting with an empty stack, and setting start
to 0, loop until we reach the end:
- If stack is empty:
- Look for the first color starting at or after
start
, and push it and all lower-ranked colors onto the stack. In your flattened list, mark the beginning of that color.
- else (If not empty):
- Find next beginning point for any higher-ranked color at or after
start
, and find the end of the current color
- If the next color starts first, push it and anything else on the way to it onto the stack. Update the end of the current color as the beginning of this one, and add the start of this color to the flattened list.
- If there are none and the current color ends first, set
start
to the end of this color, pop it off of the stack, and check the next-highest ranked color
- If
start
is within the next color's range, add this color to the flattened list, starting at start
.
- If the stack empties, just continue the loop (go back to the first bullet point).
This is a mental run-through given your example data:
# Initial data.
flattened = []
stack = []
start = 0
# Stack is empty. Look for the next starting point at 0 or later: "b", 0 - Push it and all lower levels onto stack
flattened = [ (b, 0, ?) ]
stack = [ r, b ]
start = 0
# End of "b" is 5.4, next higher-colored start is "g" at 2 - Delimit and continue
flattened = [ (b, 0, 2), (g, 2, ?) ]
stack = [ r, b, g ]
start = 2
# End of "g" is 12, next higher-colored start is "y" at 3.5 - Delimit and continue
flattened = [ (b, 0, 2), (g, 2, 3.5), (y, 3.5, ?) ]
stack = [ r, b, g, y ]
start = 3.5
# End of "y" is 6.7, next higher-colored start is "o" at 6.7 - Delimit and continue
flattened = [ (b, 0, 2), (g, 2, 3.5), (y, 3.5, 6.7), (o, 6.7, ?) ]
stack = [ r, b, g, y, o ]
start = 6.7
# End of "o" is 10, and there is nothing starting at 12 or later in a higher color. Next off stack, "y", has already ended. Next off stack, "g", has not ended. Delimit and continue.
flattened = [ (b, 0, 2), (g, 2, 3.5), (y, 3.5, 6.7), (o, 6.7, 10), (g, 10, ?) ]
stack = [ r, b, g ]
start = 10
# End of "g" is 12, there is nothing starting at 12 or later in a higher color. Next off stack, "b", is out of range (already ended). Next off stack, "r", is out of range (not started). Mark end of current color:
flattened = [ (b, 0, 2), (g, 2, 3.5), (y, 3.5, 6.7), (o, 6.7, 10), (g, 10, 12) ]
stack = []
start = 12
# Stack is empty. Look for the next starting point at 12 or later: "r", 12.5 - Push onto stack
flattened = [ (b, 0, 2), (g, 2, 3.5), (y, 3.5, 6.7), (o, 6.7, 10), (g, 10, 12), (r, 12.5, ?) ]
stack = [ r ]
start = 12
# End of "r" is 13.8, and there is nothing starting at 12 or higher in a higher color. Mark end and pop off stack.
flattened = [ (b, 0, 2), (g, 2, 3.5), (y, 3.5, 6.7), (o, 6.7, 10), (g, 10, 12), (r, 12.5, 13.8) ]
stack = []
start = 13.8
# Stack is empty and nothing is past 13.8 - We're done.
Best Answer
Terminology nitpick: those aren't vectors: vectors have a direction and size, but there is no “starting point” in a vector space. instead, you're defining a line segment via the starting and ending point of this line segment.
Given these two points
A
andB
on the line, we can calculate the directionD = B - A
of the line. The line segment we are interested in consist of all pointsP
that fulfill the following equation:where
k
is some scalar value in[0, 1]
. When you have transformed all your inputs into this form, it's fairly straightforward to find solutions where the lines overlap:This is essentially a system of linear equations, which can be solved if we have two or more dimensions. (We have to solve for the two variables
k1
andk2
). There are three possible outcomes:0 <= k <= 1
constraint), i.e. the line segments do not overlap.