public static Animation CreateComplexSumAnimation()
        {
            var matrixFill = (Brush)Brushes.Orange.LerpToTransparent(0.5);
            var vectorFill = (Brush)Brushes.Blue.LerpToTransparent(0.7);
            var c1 = new Complex(-0.5, -0.5) * Math.Sqrt(0.5);
            var c2 = new Complex(-0.5, 0.5);
            var r = 50;
            var cy = 100;
            var x1 = 125/2;
            var x2 = 350/2;
            var x3 = x2 + (x2-x1);
            var f = 14;

            var animation = new Animation {
                new TextDesc("+", new Point((x1 + x2)/2.0, cy), new Point(0.5, 0.5), fontSize: 20),
                new TextDesc("=", new Point((x3 + x2)/2.0, cy), new Point(0.5, 0.5), fontSize: 20),
                new TextDesc(c1.ToPrettyString(), new Point(x1, cy - r), new Point(0.5, 1), fontSize: f),
                new TextDesc(c2.ToPrettyString(), new Point(x2, cy - r), new Point(0.5, 1), fontSize: f),
                new TextDesc((c1 + c2).ToPrettyString(), new Point(x3, cy - r), new Point(0.5, 1), fontSize: f),

                new TextDesc(c1.ToMagPhaseString(), new Point(x1, cy + r), new Point(0.5, 0), fontSize: f),
                new TextDesc(c2.ToMagPhaseString(), new Point(x2, cy + r), new Point(0.5, 0), fontSize: f),
                new TextDesc((c1 + c2).ToMagPhaseString(), new Point(x3, cy + r), new Point(0.5, 0), fontSize: f),
                new TextDesc("Adding Complex Numbers: Place Arrows End to End",
                             new Point(x2, 5),
                             new Point(0.5, 0),
                             fontSize: 15,
                             foreground: Brushes.Gray),

                ShowComplex(vectorFill,
                            Brushes.Black,
                            c1,
                            new Point(x1, cy),
                            r),
                ShowComplex(matrixFill,
                            Brushes.Black,
                            c2,
                            new Point(x2, cy),
                            r)
            };
            var p = animation.Dilated(0.4.Seconds()).Periodic(10.Seconds());
            p.LimitedSameTime(0.Seconds(), 9.5.Seconds()).Add(ShowComplexSum(
                Brushes.Transparent,
                vectorFill.LerpTo(matrixFill, 0.5),
                Brushes.Black,
                new Ani<Complex>[] {c1, c2},
                new Point(x1, cy),
                new Point(x3, cy),
                new Vector(x2-x1, 0),
                r,
                p.Proper));

            var s2 = p.LimitedSameTime(9.5.Seconds(), 10.Seconds());
            s2.Add(ShowComplex(Ani.Anon(t => vectorFill.LerpTo(matrixFill, 0.5).LerpToTransparent(s2.Proper.ValueAt(t))),
                               Ani.Anon(t => (Brush)Brushes.Black.LerpToTransparent(s2.Proper.ValueAt(t))),
                               c1 + c2,
                               new Point(x3, cy),
                               r));

            return animation;
        }
        public static Animation CreateComplexProductAnimation()
        {
            var matrixFill = (Brush)Brushes.Orange.LerpToTransparent(0.5);
            var vectorFill = (Brush)Brushes.Blue.LerpToTransparent(0.7);
            var c1 = new Complex(1, 1) / 2;
            var c2 = new Complex(-1, 1) / 2;
            var r = 50;
            var cy = 100;
            var x1 = 125 / 2;
            var x2 = 350 / 2;
            var x3 = x2 + (x2 - x1);
            var f = 14;

            var animation = new Animation {
                new TextDesc("*", new Point((x1 + x2)/2.0, cy), new Point(0.5, 0.5), fontSize: 20),
                new TextDesc("=", new Point((x3 + x2)/2.0, cy), new Point(0.5, 0.5), fontSize: 20),
                new TextDesc(c1.ToPrettyString(), new Point(x1, cy - r), new Point(0.5, 1), fontSize: f),
                new TextDesc(c2.ToPrettyString(), new Point(x2, cy - r), new Point(0.5, 1), fontSize: f),
                new TextDesc((c1*c2).ToPrettyString(), new Point(x3, cy - r), new Point(0.5, 1), fontSize: f),

                new TextDesc(c1.ToMagPhaseString(), new Point(x1, cy + r), new Point(0.5, 0), fontSize: f),
                new TextDesc(c2.ToMagPhaseString(), new Point(x2, cy + r), new Point(0.5, 0), fontSize: f),
                new TextDesc((c1*c2).ToMagPhaseString(), new Point(x3, cy + r), new Point(0.5, 0), fontSize: f),
                new TextDesc("Complex Product: Multiply Magnitudes, Add Phases",
                             new Point(x2, 5),
                             new Point(0.5, 0),
                             fontSize: 15,
                             foreground: Brushes.Gray),

                ShowComplex(vectorFill,
                            Brushes.Black,
                            c1,
                            new Point(x1, cy),
                            r),
                ShowComplex(matrixFill,
                            Brushes.Black,
                            c2,
                            new Point(x2, cy),
                            r)
            };

            var p = animation.Dilated(0.4.Seconds()).Periodic(10.Seconds());
            var s1 = p.LimitedSameTime(0.Seconds(), 3.Seconds());
            s1.Add(ShowComplex(vectorFill,
                               Brushes.Black,
                               c1,
                               Ani.Anon(
                                   t =>
                                   new Point(x1, cy).SmoothLerpTo(new Point(x3, cy), (s1.Proper.ValueAt(t)*1.5).Min(1))
                                   + new Vector(0, (s1.Proper.ValueAt(t)*1.5).Min(1).LerpTransition(0, -25, 0))),
                               r,
                               rotation: Ani.Anon(t => Turn.FromNaturalAngle(0.0.SmoothLerpTo(Math.PI/2, (s1.Proper.ValueAt(t)*2).Min(1))))));
            s1.Add(ShowComplex(matrixFill,
                               Brushes.Black,
                               c2,
                               Ani.Anon(
                                   t =>
                                   new Point(x2, cy).SmoothLerpTo(new Point(x3, cy), (s1.Proper.ValueAt(t)*1.5).Min(1))
                                   + new Vector(0, (s1.Proper.ValueAt(t)*1.5).Min(1).LerpTransition(0, -25, 0))),
                               r));
            var sb = p.LimitedSameTime(3.Seconds(), 9.Seconds());
            sb.Add(
                ShowComplexProduct(vectorFill,
                                   matrixFill,
                                   Brushes.Black,
                                   Brushes.Black,
                                   c1,
                                   c2,
                                   new Point(x3, cy),
                                   r,
                                   Ani.Anon(t => (sb.Proper.ValueAt(t)*1.2).Min(1)),
                                   vectorFill.LerpTo(matrixFill, 0.5)));

            var s2 = p.LimitedSameTime(9.Seconds(), 9.5.Seconds());
            s2.Add(ShowComplex(Ani.Anon(t => vectorFill.LerpTo(matrixFill, 0.5).LerpToTransparent(s2.Proper.ValueAt(t))),
                               Ani.Anon(t => (Brush)Brushes.Black.LerpToTransparent(s2.Proper.ValueAt(t))),
                               c1*c2,
                               new Point(x3, cy),
                               r));

            return animation;
        }