コード例 #1
0
        private TabletopParams CreateFeatureParamsForSection(int section)
        {
            int    numSections          = sectionsProvider.NumSections();
            double sectionLengthSeconds = sectionModel.TotalLength.TotalSeconds;

            //first decide if it has a tabletop at all.
            //the chance of it being something at all rises from 0% to 100%.
            double progression = ((float)section + 1) / numSections; // <= 1

            //if it's a tabletop:
            double topLength =
                randomizer.ProportionAlong(sectionModel.FeatureLengthVariation, progression,
                                           sectionModel.MinFeatureLength.TotalSeconds,
                                           sectionModel.MaxFeatureLength.TotalSeconds);
            double maxRampLength = Math.Min(sectionModel.MaxRampLength.TotalSeconds, (sectionLengthSeconds - topLength) / 2);

            if (sectionModel.MinRampLength.TotalSeconds > maxRampLength)
            {
                throw new InvalidOperationException($"MinRampLength must be <= maxRampLength. MinTabletopLength could be too high.");
            }

            // could feasibly be MinRampLength at the start of the track. Desirable? Yes, because other parameters constrain the dramaticness at the start.
            double rampLength =
                randomizer.ProportionAlong(sectionModel.RampLengthVariation, progression,
                                           maxRampLength,
                                           sectionModel.MinRampLength.TotalSeconds); // Max is first as shorter ramps are more dramatic (nearer the end of the track)
            var result = new TabletopParams
            {
                RampLength   = rampLength,
                TopLength    = topLength,
                RampsUseSin2 = true
            };

            return(result);
        }
コード例 #2
0
        private void ValidateParams(TabletopParams p)
        {
            double sectionLengthSeconds = sectionModel.TotalLength.TotalSeconds;

            if (p.TopLength < 0)
            {
                throw new InvalidOperationException("TopLength must be >= 0");
            }
            if (p.RampLength < 0)
            {
                throw new InvalidOperationException("RampLength must be >= 0");
            }
            if (p.TopLength + 2 * p.RampLength > sectionLengthSeconds)
            {
                throw new InvalidOperationException("TopLength + 2*RampLength must be <= sectionLengthSeconds");
            }
        }
コード例 #3
0
        /*            TopLength    RampLength
         *          <--------------><->
         * y|       ________________
         *  |      /ymax            \   prefixLength (same both sides)
         *  |     /                  \ <-->
         *  |____/                    \____
         *  |ymin
         * ________________________________x
         *  <-----------xmax-------------->
         * the TopFrequency doesn't necessarily have to be greater than baseFrequency - but it must be >0.
         */

        public static double GetY(double x, double xmax, double ymin, double ymax, TabletopParams p)
        {
            double prefixLength =
                (xmax - p.TopLength - 2 * p.RampLength) / 2; //length of the bit at base frequency before the first ramp
            double dy = ymax - ymin;

            if (x < prefixLength)
            {
                //before the first ramp
                return(ymin);
            }
            else if (x < prefixLength + p.RampLength)
            {
                // on the first ('up') ramp
                double timeAlongRamp       = x - prefixLength;
                double proportionAlongRamp = timeAlongRamp / p.RampLength;
                double proportionUpRamp    = p.RampsUseSin2
                    ? Math.Pow(Math.Sin(proportionAlongRamp * Math.PI / 2), 2)
                    : proportionAlongRamp;
                return(ymin + proportionUpRamp * dy);
            }
            else if (x <= prefixLength + p.RampLength + p.TopLength)
            {
                // on the tabletop
                return(ymax);
            }
            else if (x <= prefixLength + 2 * p.RampLength + p.TopLength)
            {
                //on the second ('down') ramp
                double timeAlongRamp       = x - prefixLength - p.RampLength - p.TopLength;
                double proportionAlongRamp = timeAlongRamp / p.RampLength;
                double proportionUpRamp    = p.RampsUseSin2
                    ? Math.Pow(Math.Sin(proportionAlongRamp * Math.PI / 2), 2)
                    : proportionAlongRamp;
                return(ymin + (1 - proportionUpRamp) * dy);
            }
            else
            {
                //after the second ramp
                return(ymin);
            }
        }