public override void Run()
        {
            string ptstr = @"{\p1}m 0 0 l -31 2 -53 10 -67 7 -53 9 -32 1 -41 -2 -49 -2 -54 -1 -49 -3 -41 -3 -46 -7 -49 -23 -45 -8 -41 -4 -32 0 -29 1 -26 1 -23 1 -10 0 -21 -8 -28 -12 -35 -11 -28 -13 -21 -9 -10 -1 -4 -14 5 -19 13 -25 13 -33 18 -37 24 -35 25 -29 23 -34 18 -36 14 -33 14 -25 10 -22 20 -17 20 -9 13 -5 19 -9 19 -17 9 -21 6 -19 -3 -13 -9 -1 0 -1 25 4 43 2 54 15 43 3 36 3 38 12 47 25 37 13 35 4 25 5 12 3 -8 22 -31 25 -41 32 -32 24 -9 21 11 3";

            ASS ass_in  = ASS.FromFile(this.InFileName);
            ASS ass_out = new ASS();

            ass_out.Header = ass_in.Header;
            ass_out.Events = new List <ASSEvent>();

            int    ox  = 424;
            int    oy  = 240;
            Random rnd = new Random();

            double tStart         = 1;
            double tEnd           = 10;
            double particlePerSec = 200;
            string mainCol        = "FF205C";

            CompositeCurve curve = Line.Create1(424 - 20, 240 - 20, 424 + 20, 240 + 20, 100, tStart, tEnd);

            for (int iP = 0; iP < particlePerSec * (tEnd - tStart); iP++)
            {
                double    t0    = Common.RandomDouble(rnd, tStart, tEnd);
                double    life  = 0.3;
                double    t1    = t0 + life;
                double    tmpt  = (double)iP / (particlePerSec * (tEnd - tStart)) * (tEnd - tStart) + tStart;
                ASSPointF orgpt = curve.GetPointF(tmpt);
                double    x0    = orgpt.X;
                double    y0    = orgpt.Y;
                double    ag    = Common.RandomDouble(rnd, 0, 2 * Math.PI);
                double    r     = 40;
                double    x1    = x0 + r * Math.Cos(ag);
                double    y1    = y0 + r * Math.Sin(ag);

                int tmpz = Common.RandomInt(rnd, 100, 200) * Common.RandomSig(rnd);
                tmpz = Common.RandomInt(rnd, 0, 359);

                for (int i = 0; i < 1; i++)
                {
                    ass_out.AppendEvent(10 + i, "pt", t0, t1,
                                        move(x0, y0, x1, y1, 0, life * 0.7) + a(1, "77") + a(3, "DD") + fad(0, life * 0.8) +
                                        c(1, mainCol) + c(3, mainCol) +
                                        bord(3 - i) + be(3 - i) + fsc(30, 30) +
                                        t(life * 0.5, life, fsc(0, 0).t()) +
                                        frz(tmpz) +
                                        ptstr);
                }
                ass_out.AppendEvent(20, "pt", t0, t1,
                                    move(x0, y0, x1, y1, 0, life * 0.7) + a(1, "77") + a(3, "DD") + fad(0, life * 0.8) +
                                    c(1, "FFFFFF") + c(3, "FFFFFF") +
                                    bord(2) + blur(2) + fsc(30, 30) +
                                    t(life * 0.5, life, fsc(0, 0).t()) +
                                    frz(tmpz) +
                                    ptstr);
            }

            ass_out.SaveFile(OutFileName);
        }
        public ASSPointF GetForceField(double time)
        {
            return(forceCurve.GetPointF(time));

            double ag = time * 3;

            return(new ASSPointF {
                X = 50.0 * Math.Cos(ag), Y = 50.0 * Math.Sin(ag)
            });
        }
        public override void Run()
        {
            string ptstr = @"{\p1}m 0 0 l 1 0 1 1 0 1";

            ASS ass_in  = ASS.FromFile(this.InFileName);
            ASS ass_out = new ASS();

            ass_out.Header = ass_in.Header;
            ass_out.Events = new List <ASSEvent>();

            forceCurve = new CompositeCurve {
                MinT = 0, MaxT = 30
            };
            double lastag = 0;

            for (double time = forceCurve.MinT; time <= forceCurve.MaxT; time += 1)
            {
                double ag = Common.RandomDouble(rnd, 0, Math.PI * 2);
                while (Math.Abs(ag - lastag) < Math.PI * 0.5 || Math.Abs(ag - lastag) > Math.PI * 1.5)
                {
                    ag = Common.RandomDouble(rnd, 0, Math.PI * 2);
                }
                lastag = ag;
                //ag = 0;
                double x = 1000.0 * Math.Cos(ag);
                double y = 600.0 * Math.Sin(ag);
                forceCurve.AddCurve(time, time + 1, new Line {
                    X0 = x, Y0 = y, X1 = 0, Y1 = 0, Acc = 0.7
                });
                //forceCurve.AddCurve(time, time + 1, new Line { X0 = 0, Y0 = 0, X1 = 0, Y1 = 0 });
            }

            NumberPerSecond = 100;
            XXParticleSystem xxps = new XXParticleSystem();

            xxps.Emitter                = this;
            xxps.ForceField             = this;
            xxps.StartTime              = 0;
            xxps.EndTime                = 3;
            xxps.InterpolationPrecision = 0.04;
            xxps.Resistance             = 0.03;
            xxps.Repulsion              = -2200;
            xxps.Gravity                = 0;
            xxps.GravityPosition        = this;
            List <KeyValuePair <XXParticleElement, List <ASSPointF> > > result = xxps.RenderPoint();

            foreach (KeyValuePair <XXParticleElement, List <ASSPointF> > pair in result)
            {
                string s = CreatePolygon(rnd, 5, 10, 6);
                foreach (ASSPointF pt in pair.Value)
                {
                    ass_out.AppendEvent(0, "pt", pt.T, pt.T + xxps.InterpolationPrecision,
                                        pos(pt.X, pt.Y) + a(1, "22") + a(3, "77") + blur(2) + bord(1.5) + c(3, "532BFF") +
                                        s);
                    continue;
                    ass_out.AppendEvent(0, "pt", pt.T, pt.T + xxps.InterpolationPrecision,
                                        pos(pt.X, pt.Y) + a(1, "00") +
                                        ptstr);
                    continue;
                    ASSPointF force = forceCurve.GetPointF(pt.T);
                    ass_out.AppendEvent(0, "pt", pt.T, pt.T + xxps.InterpolationPrecision,
                                        pos(0, 0) + an(7) + a(1, "00") + fs(16) +
                                        string.Format("{0}, {1}", force.X, force.Y));
                }
            }

            ass_out.SaveFile(OutFileName);
        }
 public ASSPointF GetForceField(double time)
 {
     return(forceCurve.GetPointF(time));
 }
        public override void Run()
        {
            ASS ass_in  = ASS.FromFile(this.InFileName);
            ASS ass_out = new ASS();

            ass_out.Header = ass_in.Header;
            ass_out.Events = new List <ASSEvent>();

            Random rnd = new Random();

            for (int iEv = 0; iEv < ass_in.Events.Count; iEv++)
            {
                if (iEv <= 2)
                {
                    continue;
                }

                ASSEvent ev = ass_in.Events[iEv];

                /// trick
                if (iEv == 2)
                {
                    ev.Text = ev.Text.Replace(' ', '@');
                }
                List <KElement> kelems = ev.SplitK(true);
                if (iEv == 2)
                {
                    ev.Text = ev.Text.Replace('@', ' ');
                    foreach (KElement ke in kelems)
                    {
                        ke.KText = ke.KText.Replace('@', ' ');
                    }
                }

                this.FontCharset = 1;
                this.FontName    = "EPSON 丸ゴシック体M";
                this.MaskStyle   = "Style: Default,EPSON 丸ゴシック体M,38,&H00FFFFFF,&HFFFFFFFF,&HFFFFFFFF,&HFFFFFFFF,-1,0,0,0,100,100,0,0,1,0,0,5,0,0,0,1";
                string evStyle = "ed_jp";

                int tw      = GetTotalWidth(ev);
                int x0      = (PlayResX - MarginLeft - MarginRight - tw) / 2 + MarginLeft;
                int startx0 = x0;
                int y0      = PlayResY - MarginBottom - FontHeight;
                int kSum    = 0;

                List <CompositeCurve> curves      = new List <CompositeCurve>();
                List <CompositeCurve> curve_blurs = new List <CompositeCurve>();
                for (int i = 0; i < 4; i++)
                {
                    Brown brown = new Brown {
                        X0 = 0, Y0 = 0, R = 5, Speed = 100, MinT = ev.Start, MaxT = ev.End
                    };
                    CompositeCurve curve = new CompositeCurve {
                        MinT = ev.Start, MaxT = ev.End
                    };
                    curve.AddCurve(ev.Start, ev.End, brown);

                    Brown brown_blur = new Brown {
                        X0 = 0, Y0 = 0, R = 1, Speed = 5, MinT = ev.Start - 1, MaxT = ev.End + 1
                    };
                    CompositeCurve curve_blur = new CompositeCurve {
                        MinT = ev.Start - 1, MaxT = ev.End + 1
                    };
                    curve_blur.AddCurve(ev.Start - 1, ev.End + 1, brown_blur);

                    curves.Add(curve);
                    curve_blurs.Add(curve_blur);
                }

                List <int> centerOffsetX = new List <int>();
                if (iEv == 1 || iEv == 2)
                {
                    List <int> tmpx = new List <int>();
                    int        tx0  = x0;
                    for (int i = 0; i < kelems.Count; i++)
                    {
                        KElement ke    = kelems[i];
                        Size     sz    = GetSize(ke.KText);
                        int      x_an7 = x0;
                        int      y_an7 = y0;
                        tmpx.Add(tx0);
                        tx0 += sz.Width + FontSpace;
                        if (ke.KText.Trim().Length == 0)
                        {
                            continue;
                        }
                    }
                    tmpx.Add(tx0);
                    for (int i = 0; i < kelems.Count; i++)
                    {
                        KElement ke = kelems[i];
                        int      j  = i;
                        while (j + 1 < kelems.Count)
                        {
                            if (kelems[j + 1].KEnd_NoSplit == ke.KEnd_NoSplit && kelems[j + 1].KStart_NoSplit == ke.KStart_NoSplit)
                            {
                                j++;
                            }
                            else
                            {
                                break;
                            }
                        }
                        int centerx = (tmpx[i] + tmpx[j + 1]) / 2;
                        for (; i <= j; i++)
                        {
                            centerOffsetX.Add(tmpx[i] - centerx);
                        }
                        i--;
                    }
                }

                for (int iK = 0; iK < kelems.Count; iK++)
                {
                    Console.WriteLine("{0} / {1} : {2} / {3}", iEv + 1, ass_in.Events.Count, iK + 1, kelems.Count);
                    KElement ke      = kelems[iK];
                    Size     sz      = GetSize(ke.KText);
                    double   kStart  = ev.Start + kSum * 0.01;
                    double   kEnd    = kStart + ke.KValue * 0.01;
                    double   kStart0 = kStart;
                    double   kEnd0   = kEnd;
                    kSum  += ke.KValue;
                    kStart = ke.KStart_NoSplit;
                    kEnd   = ke.KEnd_NoSplit;
                    int x     = x0 + this.FontSpace + sz.Width / 2;
                    int y     = y0 + FontHeight / 2;
                    int x_an7 = x0;
                    int y_an7 = y0;
                    x0 += this.FontSpace + sz.Width;
                    if (ke.KText.Trim().Length == 0)
                    {
                        continue;
                    }

                    if (iEv == 0)
                    {
                        for (int j = 0; j < 3; j++)
                        {
                            if (j == 1)
                            {
                                x = MarginLeft + sz.Width / 2;
                            }
                            if (j == 2)
                            {
                                x = PlayResX - MarginRight - sz.Width / 2;
                            }
                            if (j != 0)
                            {
                                continue;
                            }

                            for (int i = 0; i < 4; i++)
                            {
                                CompositeCurve curve      = curves[i];
                                CompositeCurve curve_blur = curve_blurs[i];

                                foreach (ASSPointF pt in curve.GetPath_DT(0.04))
                                {
                                    ASSPointF pt_blur = curve_blur.GetPointF(pt.T);
                                    string    a1      = "22";
                                    if (pt.T - ev.Start < 0.3)
                                    {
                                        a1 = Common.scaleAlpha("FF", "22", (pt.T - ev.Start) / 0.3);
                                    }
                                    if (ev.End - pt.T < 0.3)
                                    {
                                        a1 = Common.scaleAlpha("FF", "22", (ev.End - pt.T) / 0.3);
                                    }

                                    ass_out.AppendEvent(50, evStyle, pt.T, pt.T + 0.04,
                                                        pos(pt.X + x, pt.Y + y) +
                                                        a(1, a1) +
                                                        c(1, (i % 2 == 0) ? "FFFFFF" : "000000") +
                                                        blur(5.0 * ((pt_blur.X + 1.1) * 0.5)) +
                                                        ke.KText);
                                }
                            }
                        }
                    }

                    if (iEv == 1 || iEv == 2)
                    {
                        for (int i = 0; i < 2; i++)
                        {
                            CompositeCurve curve      = curves[i];
                            CompositeCurve curve_blur = curve_blurs[i];

                            foreach (ASSPointF pt in curve.GetPath_DT(0.04))
                            {
                                ASSPointF pt_blur = curve_blur.GetPointF(pt.T);
                                string    a1      = "22";
                                if (pt.T - ev.Start < 0.3)
                                {
                                    a1 = Common.scaleAlpha("FF", "22", (pt.T - ev.Start) / 0.3);
                                }
                                if (ev.End - pt.T < 0.3)
                                {
                                    a1 = Common.scaleAlpha("FF", "22", (ev.End - pt.T) / 0.3);
                                }

                                double blur_value = 2.0 * ((pt_blur.X + 2) * 0.5);
                                int    ifsc       = 100;
                                double kEnd2      = kEnd;
                                bool   ink        = false;
                                if (pt.T >= kStart && pt.T <= kEnd2)
                                {
                                    ifsc = 135;
                                    ink  = true;
                                }
                                string col = (i % 2 == 0) ? "FFFFFF" : "000000";
                                if (i % 2 == 0 && ink)
                                {
                                    col = "FFFFFF";
                                    a1  = "00";
                                }
                                else
                                {
                                    a1 = "77";
                                }

                                ass_out.AppendEvent((i == 0) ? (ink ? 150 : 50) : 100, evStyle, pt.T, pt.T + 0.04,
                                                    pos(pt.X + x + (double)(ifsc - 100) / 100.0 * centerOffsetX[iK], pt.Y + y) +
                                                    a(1, a1) +
                                                    c(1, col) +
                                                    blur(blur_value) + fsc(ifsc) +
                                                    ke.KText);

                                if (i == 1)
                                {
                                    continue;
                                }
                                double tx  = pt.X + x;
                                double dx  = -(pt.T - kStart0) / ev.Last * 10.0;
                                double ta1 = 1;
                                if (!ink)
                                {
                                    ta1 = 0.5;
                                }
                                if (pt.T - ev.Start < 0.3)
                                {
                                    ta1 *= (pt.T - ev.Start) / 0.3;
                                }
                                if (ev.End - pt.T < 0.3)
                                {
                                    ta1 *= (ev.End - pt.T) / 0.3;
                                }
                                double tb   = blur_value;
                                int    tfsc = ifsc + 5;
                                for (int j = 0; j < 10; j++)
                                {
                                    ass_out.AppendEvent(50 + j + 1, evStyle, pt.T, pt.T + 0.04,
                                                        pos(tx + (double)(tfsc - 100) / 100.0 * centerOffsetX[iK], pt.Y + y) +
                                                        a(1, Common.scaleAlpha("FF", "00", ta1)) +
                                                        c(1, col) +
                                                        blur(tb) + fsc(tfsc) +
                                                        ke.KText);

                                    tx += dx;
                                    if (dx < 0)
                                    {
                                        dx -= 1.0;
                                    }
                                    else
                                    {
                                        dx += 1.0;
                                    }
                                    ta1  *= 0.9;
                                    tb   += 1;
                                    tfsc += (int)Math.Abs(dx);
                                }
                            }
                        }
                    }

                    if (iEv > 2)
                    {
                        ass_out.AppendEvent(49, evStyle, ev.Start, ev.End,
                                            pos(x - 1, y - 1) +
                                            a(1, "00") + c(1, "000000") + blur(1.1) +
                                            ke.KText);
                        ass_out.AppendEvent(50, evStyle, ev.Start, ev.End,
                                            pos(x, y) +
                                            a(1, "00") + c(1, "000000") + blur(0.9) +
                                            ke.KText);
                        ass_out.AppendEvent(51, evStyle, ev.Start, ev.End,
                                            pos(x + 2, y + 2) +
                                            a(1, "00") + c(1, "000000") +
                                            ke.KText);
                    }
                }
            }

            ass_out.SaveFile(OutFileName);
            Console.WriteLine("Lines : {0}", ass_out.Events.Count);
        }