static internal void RunKinematics()
        {
            // Level 1
            //var engine = new World(0.01, 0, -9.8);
            //Projectile projectile1 = new Projectile(new Utility.Vector(0, 0, 0), new Utility.Vector(4, 0, Math.PI / 4, false), new Utility.Vector(0, 0, -9.8), 5);
            //engine.AddProjectile(projectile1);

            // Level 2
            //var engine = new World(0.01, 0.4, -9.8);
            //Projectile projectile1 = new Projectile(new Utility.Vector(0, 0, 0), new Utility.Vector(4, 0, Math.PI / 4, false), new Utility.Vector(0, 0, -9.8), 5);
            //engine.AddProjectile(projectile1);

            // Level 3
            //var engine = new World(0.01, 0.4, -9.8);
            //Projectile projectile1 = new Projectile(new Utility.Vector(1, 1, 1), new Utility.Vector(-2, 1, 3), new Utility.Vector(0, 0, -9.8), 5);
            //Spring spring1 = new Spring(2, 5, new Utility.Vector(), projectile1.Position);
            //engine.AddProjectile(projectile1);
            //engine.AddSpring(spring1);

            // Challenge
            // This should connect to your World or Engine class from your kinematics project
            var        engine      = new World(0.01, 0.4, -9.8);
            Projectile projectile1 = new Projectile(new Utility.Vector(1, 1, 1), new Utility.Vector(-2, 1, 3), new Utility.Vector(0, 0, -9.8), 5);
            Projectile projectile2 = new Projectile(new Utility.Vector(2, 2, 2), new Utility.Vector(1, -3, 4), new Utility.Vector(0, 0, -9.8), 3);
            Spring     spring1     = new Spring(2, 5, new Utility.Vector(), projectile1.Position);
            Spring     spring2     = new Spring(2, 5, projectile1.Position, projectile2.Position);

            engine.AddProjectile(projectile1);
            engine.AddProjectile(projectile2);
            engine.AddSpring(spring1);
            engine.AddSpring(spring2);
            // This will work once you define an EngineAdapter that inherits from IEngine


            var adapter = new EngineAdapter(engine);

            Sphere3D.NSegments = 40;
            var visualization = new KinematicsVisualization(adapter);

            Timeline.MaximumPoints = 3000;

            var fullViz = new MotionVisualizer(visualization);

            // For Levels 1-3
            //fullViz.Add3DGraph("Position", () => engine.Time, () => ConvertToVector3D(engine.ProjectileList[0].Position), "Time (s)", "Position (m)");
            //fullViz.Add3DGraph("Velocity", () => engine.Time, () => ConvertToVector3D(engine.ProjectileList[0].Velocity), "Time (s)", "Velocity (m/s)");
            //fullViz.Add3DGraph("Acceleration", () => engine.Time, () => ConvertToVector3D(engine.ProjectileList[0].Acceleration), "Time (s)", "Acceleration (m/s^2)");

            // For the challenge
            fullViz.AddSingleGraph("Distance Between Projectiles", Colors.Teal, () => engine.Time, (() => (engine.ProjectileList[1].Position - engine.ProjectileList[0].Position).Magnitude)
                                   , "Time (s)", "Distance (m)");
            fullViz.Add3DGraph("CM Position", () => engine.Time, () => ConvertToVector3D(engine.CalcCOM(projectile1, projectile2)), "Time (s)", "CM Position (m)");
            fullViz.Add3DGraph("CM Velocity", () => engine.Time, () => ConvertToVector3D((engine.ProjectileList[0].Velocity * engine.ProjectileList[0].Mass + engine.ProjectileList[1].Velocity * engine.ProjectileList[1].Mass) / (engine.ProjectileList[0].Mass + engine.ProjectileList[1].Mass)), "Time (s)", "CM Velocity (m/s)");
            fullViz.Add3DGraph("CM Accleration", () => engine.Time, () => ConvertToVector3D((engine.ProjectileList[0].Acceleration * engine.ProjectileList[0].Mass + engine.ProjectileList[1].Acceleration * engine.ProjectileList[1].Mass) / (engine.ProjectileList[0].Mass + engine.ProjectileList[1].Mass)), "Time (s)", "CM Acceleration (m/s^2)");

            fullViz.Show();
        }
        static internal void RunMarbleMadness()
        {
            var engine = new KinematicsEngine();

            engine.AddForce(new ConstantGravitationForce(engine, new Vector(0, 0, -9.8)));
            var ps       = new YourParticleStructure();
            var surfaces = new JayDongMarbleMachine();

            AddParticleStructure(ps, engine);
            AddSurfaces(surfaces, engine);

            var adapter = new EngineAdapter(engine);

            Sphere3D.NSegments = 40;
            var visualization = new KinematicsVisualization(adapter);

            visualization.Box = true;

            visualization.ConnectorRadiusScale = .1;
            ProjectileAdapter.VisualSize       = .01;

            AddConnectorsToVisualizer(ps, visualization);
            AddSurfacesToVisualizer(surfaces, visualization);

            Timeline.MaximumPoints = 3000;

            var fullViz = new MotionVisualizer(visualization);

            //fullViz.BackgroundFile = "stars.jpg";

            fullViz.Add3DGraph("Position", () => engine.Time, () => ConvertToVector3D(engine.Projectiles[0].Position), "Time (s)", "Position (m)");
            fullViz.Add3DGraph("Velocity", () => engine.Time, () => ConvertToVector3D(engine.Projectiles[0].Velocity), "Time (s)", "Velocity (m/s)");
            fullViz.Add3DGraph("Acceleration", () => engine.Time, () => ConvertToVector3D(engine.Projectiles[0].Acceleration), "Time (s)", "Acceleration (m/s^2)");

            //fullViz.AddSingleGraph("Speed", Colors.Teal, () => engine.Time, (() => engine.Projectiles[0].Velocity.Magnitude),
            //     "Time (s)", "Speed (m/s)");

            fullViz.Show();
        }
        static internal void VisualizeFastestDescent(int level, params double[] parameters)
        {
            var engine = SetupEngine(level, parameters);

            var visualization = new DescentVisualization(engine)
            {
                PathThickness   = .5,
                PathColor       = Colors.IndianRed,
                ProjectileSize  = 1,
                ProjectileColor = Colors.NavajoWhite
            };

            var fullViz = new MotionVisualizer(visualization);

            //fullViz.BackgroundFile = "stars.jpg";

            fullViz.Add3DGraph("Position", () => engine.Time, () => ConvertVector(engine.Projectile.Position), "Time (s)", "Position (m)");
            fullViz.AddText("Time", Colors.MidnightBlue, () => (Math.Round(engine.Time, 3)).ToString() + " s");

            fullViz.SlowDraw      = true;
            fullViz.TimeIncrement = .01;

            fullViz.Show();
        }