// Merge two patterns to one.
        private void convolute_basic(Pattern target, Pattern source1, Pattern source2)
        {
            target.Clear();
            int g_n = source1.Count;
            int f_n = source2.Count;

            if (g_n == 0 || f_n == 0)
            {
                return;
            }
            for (int k = 0; k < g_n + f_n - 1; k++)
            {
                double sumweight = 0, summass = 0;
                int    start = k < (f_n - 1) ? 0 : k - f_n + 1; // max(0, k-f_n+1)
                int    end   = k < (g_n - 1) ? k : g_n - 1;     // min(g_n - 1, k)
                for (int i = start; i <= end; i++)
                {
                    double weight = source1[i].Intensity * source2[k - i].Intensity;
                    double mass   = source1[i].Mz + source2[k - i].Mz;
                    sumweight += weight;
                    summass   += weight * mass;
                }
                Peak p = new Peak();
                if (sumweight == 0)
                {
                    p.Mz = DUMMY_MASS;
                }
                else
                {
                    p.Mz = summass / sumweight;
                }
                p.Intensity = sumweight;
                target.Add(p);
            }
        }
        public Pattern Calculate(FormMap fm, double limit, long charge)
        {
            Pattern tmp    = new Pattern();
            Pattern result = new Pattern();

            result.Add(new Peak()
            {
                Mz = 0.0, Intensity = 1.0
            });

            foreach (var i in fm)
            {
                int           atom_index = i.Key;
                SuperAtomList sal        = sad[atom_index];
                int           n          = i.Value;
                int           j          = 0;
                while (n > 0)
                {
                    int sz = sal.Count;
                    if (j == sz)
                    {
                        sal.Add(new Pattern());
                        convolute_basic(sal[j], sal[j - 1], sal[j - 1]);
                        Prune(sal[j], limit);
                    }
                    if ((n & 1) == 1)
                    { // digit is 1, convolute result
                        convolute_basic(tmp, result, sal[j]);
                        Prune(tmp, limit);
                        result.Clear();
                        result.AddRange(tmp);
                    }
                    n >>= 1;
                    j++;
                }
            }

            // take charge into account
            foreach (var p in result)
            {
                if (charge > 0)
                {
                    p.Mz = p.Mz / Math.Abs(charge) - ELECTRON_MASS;
                }
                else if (charge < 0)
                {
                    p.Mz = p.Mz / Math.Abs(charge) + ELECTRON_MASS;
                }
            }

            if (result.Count == 0)
            {
                throw new Exception("Calculate profile failed");
            }
            return(result);
        }
        /// <summary>
        /// Generates a hold note alongside normal notes.
        /// </summary>
        /// <param name="startTime">The start time of notes.</param>
        /// <returns>The <see cref="Pattern"/> containing the hit objects.</returns>
        private Pattern generateHoldAndNormalNotes(double startTime)
        {
            // - - - -
            // ■ x x -
            // ■ - x x
            // ■ x - x
            // ■ - x x

            var pattern = new Pattern();

            int holdColumn = GetColumn((HitObject as IHasXPosition)?.X ?? 0, true);
            if (convertType.HasFlag(PatternType.ForceNotStack) && PreviousPattern.ColumnWithObjects < TotalColumns)
                holdColumn = FindAvailableColumn(holdColumn, PreviousPattern);

            // Create the hold note
            addToPattern(pattern, holdColumn, startTime, EndTime);

            int nextColumn = GetRandomColumn();
            int noteCount;
            if (ConversionDifficulty > 6.5)
                noteCount = GetRandomNoteCount(0.63, 0);
            else if (ConversionDifficulty > 4)
                noteCount = GetRandomNoteCount(TotalColumns < 6 ? 0.12 : 0.45, 0);
            else if (ConversionDifficulty > 2.5)
                noteCount = GetRandomNoteCount(TotalColumns < 6 ? 0 : 0.24, 0);
            else
                noteCount = 0;
            noteCount = Math.Min(TotalColumns - 1, noteCount);

            bool ignoreHead = !sampleInfoListAt(startTime).Any(s => s.Name == HitSampleInfo.HIT_WHISTLE || s.Name == HitSampleInfo.HIT_FINISH || s.Name == HitSampleInfo.HIT_CLAP);

            var rowPattern = new Pattern();

            for (int i = 0; i <= spanCount; i++)
            {
                if (!(ignoreHead && startTime == HitObject.StartTime))
                {
                    for (int j = 0; j < noteCount; j++)
                    {
                        nextColumn = FindAvailableColumn(nextColumn, validation: c => c != holdColumn, patterns: rowPattern);
                        addToPattern(rowPattern, nextColumn, startTime, startTime);
                    }
                }

                pattern.Add(rowPattern);
                rowPattern.Clear();

                startTime += SegmentDuration;
            }

            return pattern;
        }
Ejemplo n.º 4
0
        public void CalculateSteps()
        {
            var cols = 16;
            var rows = MathUtil.CeilToInt(totalFlags / (float)cols);

            var w = cols * tileSize.x;
            var h = rows * tileSize.y;

            var canvas = new Pattern(w, h);

            canvas.Clear();

            var totalPixels = tileSize.x * tileSize.y;

            var brush = new int[totalPixels];

            IColor[] colors = new IColor[totalFlags];

            var flagColors = flagColorChip.colors;

            for (int i = 0; i < totalFlags; i++)
            {
                colors[i] = flagColors[i];

                var pos = gameChip.CalculatePosition(i, w);

                pos.x *= tileSize.x;
                pos.y *= tileSize.y;
                // Update the brush
                for (int j = 0; j < totalPixels; j++)
                {
                    brush[j] = i;
                }

                canvas.SetPixels(pos.x, pos.y, tileSize.x, tileSize.y, brush);
            }
            var imageExporter = new PNGWriter();

            exporter = new PixelDataExporter(fullFileName, canvas.pixels, w, h, colors, imageExporter);

            exporter.CalculateSteps();
        }
Ejemplo n.º 5
0
        /// <summary>
        /// Generates a hold note alongside normal notes.
        /// </summary>
        /// <param name="startTime">The start time of notes.</param>
        /// <returns>The <see cref="Pattern"/> containing the hit objects.</returns>
        private Pattern generateHoldAndNormalNotes(double startTime)
        {
            // - - - -
            // ■ x x -
            // ■ - x x
            // ■ x - x
            // ■ - x x

            var pattern = new Pattern();

            int holdColumn = GetColumn((HitObject as IHasXPosition)?.X ?? 0, true);

            if ((convertType & PatternType.ForceNotStack) > 0 && PreviousPattern.ColumnWithObjects < TotalColumns)
            {
                while (PreviousPattern.ColumnHasObject(holdColumn))
                {
                    holdColumn = Random.Next(RandomStart, TotalColumns);
                }
            }

            // Create the hold note
            addToPattern(pattern, holdColumn, startTime, endTime);

            int nextColumn = Random.Next(RandomStart, TotalColumns);
            int noteCount;

            if (ConversionDifficulty > 6.5)
            {
                noteCount = GetRandomNoteCount(0.63, 0);
            }
            else if (ConversionDifficulty > 4)
            {
                noteCount = GetRandomNoteCount(TotalColumns < 6 ? 0.12 : 0.45, 0);
            }
            else if (ConversionDifficulty > 2.5)
            {
                noteCount = GetRandomNoteCount(TotalColumns < 6 ? 0 : 0.24, 0);
            }
            else
            {
                noteCount = 0;
            }
            noteCount = Math.Min(TotalColumns - 1, noteCount);

            bool ignoreHead = !sampleInfoListAt(startTime).Any(s => s.Name == SampleInfo.HIT_WHISTLE || s.Name == SampleInfo.HIT_FINISH || s.Name == SampleInfo.HIT_CLAP);

            var rowPattern = new Pattern();

            for (int i = 0; i <= spanCount; i++)
            {
                if (!(ignoreHead && startTime == HitObject.StartTime))
                {
                    for (int j = 0; j < noteCount; j++)
                    {
                        while (rowPattern.ColumnHasObject(nextColumn) || nextColumn == holdColumn)
                        {
                            nextColumn = Random.Next(RandomStart, TotalColumns);
                        }
                        addToPattern(rowPattern, nextColumn, startTime, startTime);
                    }
                }

                pattern.Add(rowPattern);
                rowPattern.Clear();

                startTime += segmentDuration;
            }

            return(pattern);
        }