예제 #1
0
        public static MathObject InitialAngle(Obj a, Obj b, int solution = 0, int n = 0)
        {
            if (Misc.NotNull(
                    a.position.x,
                    b.position.x,
                    a.position.y,
                    b.position.y,
                    a.speed,
                    a.acceleration.y)
                &&
                a.speed != 0 &&
                a.speed != 0.0)
            {
                var xf = b.position.x - a.position.x;
                var yf = b.position.y - a.position.y;
                var vi = a.speed;
                var ay = a.acceleration.y;

                if (solution == 0)
                    return
                        (Trig.Asin((yf - ay * (xf ^ 2) / (vi ^ 2)) / Misc.Sqrt((xf ^ 2) + (yf ^ 2))) + Trig.Atan2(yf, xf))
                        /
                        2;
                else if (solution == 1)
                    return
                        (Trig.Pi - Trig.Asin((yf - ay * (xf ^ 2) / (vi ^ 2)) / Misc.Sqrt((xf ^ 2) + (yf ^ 2))) + Trig.Atan2(yf, xf))
                        /
                        2;
            }

            throw new Exception();
        }
예제 #2
0
        static void Main(string[] args)
        {
            // A simple accelerometer is constructed by suspending a
            // mass m from a string of length L that is tied to the top
            // of a cart. As the cart is accelerated the string-mass
            // system makes a constant angle th with the vertical.
            // (a) Assuming that the string mass is negligible compared
            // with m, derive an expression for the cart’s acceleration
            // in terms of and show that it is independent of
            // the mass mand the length L.
            // (b) Determine the acceleration of the cart when th = 23.0°.

            var F1 = new Symbol("F1"); // force of string
            var F2 = new Symbol("F2"); // force of gravity

            var th1 = new Symbol("th1");
            var th2 = new Symbol("th2");;

            var _F1 = new Point() { angle = th1 };
            var _F2 = new Point() { angle = th2, magnitude = F2 };

            var m = new Symbol("m");

            var g = new Symbol("g");

            var obj = new Obj() { mass = m };

            obj.acceleration.y = 0;

            obj.forces.Add(_F1);
            obj.forces.Add(_F2);

            _F1.magnitude = obj.ForceMagnitude(_F1);

            ("Derive an expression for the cart’s acceleration in terms " +
            "of and show that it is independent of the mass mand the length L:").Disp();

            "".Disp();

            obj.AccelerationX()
                .Substitute(F2, m * g)
                .Substitute(Trig.Cos(th2), 0)
                .Substitute(Trig.Sin(th2), -1)
                .Disp();

            "".Disp();

            "Determine the acceleration of the cart when th = 23.0°".Disp(); "".Disp();

            obj.AccelerationX()
                .Substitute(F2, m * g)
                .Substitute(Trig.Cos(th2), 0)
                .Substitute(Trig.Sin(th2), -1)
                .Substitute(th1, (90 - 23).ToRadians())
                .Substitute(Trig.Pi, Math.PI)
                .Substitute(g, 9.8)
                .Disp();

            Console.ReadLine();
        }
예제 #3
0
        static void Main(string[] args)
        {
            // You are a judge in a children’s kite-flying contest, and
            // two children will win prizes for the kites that pull most
            // strongly and least strongly on their strings. To measure
            // string tensions, you borrow a weight hanger, some slotted
            // weights, and a protractor from your physics teacher
            // and use the following protocol, illustrated in Figure
            // P5.26: Wait for a child to get her kite well-controlled,
            // hook the hanger onto the kite string about 30 cm from
            // her hand, pile on weights until that section of string is
            // horizontal, record the mass required, and record the
            // angle between the horizontal and the string running up
            // to the kite. (a) Explain how this method works. As you
            // construct your explanation, imagine that the children’s
            // parents ask you about your method, that they might
            // make false assumptions about your ability without concrete
            // evidence, and that your explanation is an opportunity to
            // give them confidence in your evaluation tech-nique.
            // (b) Find the string tension if the mass required
            // to make the string horizontal is 132 g and the angle of
            // the kite string is 46.3°.

            var F1 = new Symbol("F1");
            var F2 = new Symbol("F2");
            var F3 = new Symbol("F3");

            var th1 = new Symbol("th1");
            var th2 = new Symbol("th2");
            var th3 = new Symbol("th3");

            var _F1 = new Point() { angle = th1 };
            var _F2 = new Point() { angle = th2 };
            var _F3 = new Point() { magnitude = F3, angle = th3 };

            var m = new Symbol("m");

            var obj = new Obj();

            obj.acceleration.x = 0;
            obj.acceleration.y = 0;

            obj.mass = m;

            obj.forces.Add(_F1);
            obj.forces.Add(_F2);
            obj.forces.Add(_F3);

            "Tension in line to kite:".Disp(); "".Disp();

            obj.ForceMagnitude(_F2)
                .Substitute(th1, (180).ToRadians())
                .Substitute(th2, (46.3 * Math.PI / 180))
                .Substitute(th3, (270).ToRadians())
                .Substitute(F3, 0.132 * 9.8)
                .Substitute(Trig.Pi, Math.PI)
                .Disp();

            Console.ReadLine();
        }
예제 #4
0
        static void Main(string[] args)
        {
            // A cannon with a muzzle speed of 1 000 m/s is used to
            // start an avalanche on a mountain slope. The target is
            // 2 000 m from the cannon horizontally and 800 m above
            // the cannon. At what angle, above the horizontal, should
            // the cannon be fired?

            var xA = new Symbol("xA");      // position.x at point A
            var yA = new Symbol("yA");      // position.y at point A
            var thA = new Symbol("thA");  // angle of snowball 1 at point A
            var vA = new Symbol("vA");      // velocity at point A

            var xB = new Symbol("xB");      // position.x at point A
            var yB = new Symbol("yB");      // position.y at point A

            var g = new Symbol("g");        // magnitude of gravity
            var _g = new Point(0, -g);      // gravity vector

            var objA = new Obj()
            {
                position = new Point(xA, yA),
                speed = vA,
                acceleration = _g,
                time = 0
            };

            var objB = new Obj()
            {
                position = new Point(xB, yB),
                acceleration = _g
            };

            "At what angle, above the horizontal, should the cannon be fired?".Disp();

            Calc.InitialAngle(objA, objB)
                .ToDegrees()
                .Substitute(xA, 0)
                .Substitute(yA, 0)
                .Substitute(xB, 2000.0)
                .Substitute(yB, 800)
                .Substitute(vA, 1000)
                .Substitute(g, 9.8)
                .Substitute(Trig.Pi, Math.PI)
                .Disp();

            Console.ReadLine();
        }
예제 #5
0
        public static MathObject ForceMagnitude(Obj a, Obj b, Point _F1A, Point _F1B)
        {
            if (a.forces.Count(elt => elt.magnitude == null) == 2 &&
                a.forces.Count(elt => elt.angle == null) == 0 &&
                b.forces.Count(elt => elt.magnitude == null) == 2 &&
                b.forces.Count(elt => elt.angle == null) == 0)
            {
                var _F2A = a.forces.Find(elt => elt != _F1A && elt.magnitude == null);
                var _F2B = b.forces.Find(elt => elt != _F1B && elt.magnitude == null);

                var th1A = _F1A.angle;
                var th1B = _F1B.angle;

                var th2A = _F2A.angle;
                var th2B = _F2B.angle;

                var knownForcesA = new List<Point>(a.forces);

                knownForcesA.Remove(_F1A);
                knownForcesA.Remove(_F2A);

                var knownForcesB = new List<Point>(b.forces);

                knownForcesB.Remove(_F1B);
                knownForcesB.Remove(_F2B);

                var result = -b.acceleration.x * b.mass * Trig.Cos(th2A);

                result += a.acceleration.x * a.mass * Trig.Cos(th2B);

                knownForcesA.ForEach(_F3A =>
                    result -= _F3A.magnitude * Trig.Cos(_F3A.angle) * Trig.Cos(th2B));

                knownForcesB.ForEach(_F3B =>
                    result += _F3B.magnitude * Trig.Cos(_F3B.angle) * Trig.Cos(th2A));

                if ((-Trig.Cos(th1B) * Trig.Cos(th2A) + Trig.Cos(th1A) * Trig.Cos(th2B)) != 0)
                {
                    result /= (-Trig.Cos(th1B) * Trig.Cos(th2A) + Trig.Cos(th1A) * Trig.Cos(th2B));

                    return result;
                }
            }

            throw new Exception();
        }
예제 #6
0
        static void Main(string[] args)
        {
            Action<Equation> AssertIsTrue = (eq) =>
            {
                if (!eq) Console.WriteLine(eq.ToString());
            };

            Func<MathObject, MathObject> sin = obj => Trig.Sin(obj);
            Func<MathObject, MathObject> cos = obj => Trig.Cos(obj);

            {
                var x = new Symbol("x");
                var y = new Symbol("y");
                var z = new Symbol("z");

                Func<int, Integer> Int = (n) => new Integer(n);

                AssertIsTrue(x + x == 2 * x);

                AssertIsTrue(x + x == 2 * x);

                AssertIsTrue(x + x + x == 3 * x);

                AssertIsTrue(5 + x + 2 == 7 + x);

                AssertIsTrue(3 + x + 5 + x == 8 + 2 * x);

                AssertIsTrue(4 * x + 3 * x == 7 * x);

                AssertIsTrue(x + y + z + x + y + z == 2 * x + 2 * y + 2 * z);

                AssertIsTrue(10 - x == 10 + x * -1);

                AssertIsTrue(x * y / 3 == Int(1) / 3 * x * y);

                AssertIsTrue(x / y == x * (y ^ -1));

                AssertIsTrue(x / 3 == x * (Int(1) / 3));

                AssertIsTrue(6 * x * y / 3 == 2 * x * y);

                AssertIsTrue((((x ^ Int(1) / 2) ^ Int(1) / 2) ^ 8) == (x ^ 2));

                AssertIsTrue(((((x * y) ^ (Int(1) / 2)) * (z ^ 2)) ^ 2) == (x * y * (z ^ 4)));

                AssertIsTrue(x / x == 1);

                AssertIsTrue(x / y * y / x == 1);

                AssertIsTrue((x ^ 2) * (x ^ 3) == (x ^ 5));

                AssertIsTrue(x + y + x + z + 5 + z == 5 + 2 * x + y + 2 * z);

                AssertIsTrue(((Int(1) / 2) * x + (Int(3) / 4) * x) == Int(5) / 4 * x);

                AssertIsTrue(1.2 * x + 3 * x == 4.2 * x);

                AssertIsTrue(3 * x + 1.2 * x == 4.2 * x);

                AssertIsTrue(1.2 * x * 3 * y == 3.5999999999999996 * x * y);

                AssertIsTrue(3 * x * 1.2 * y == 3.5999999999999996 * x * y);

                AssertIsTrue(3.4 * x * 1.2 * y == 4.08 * x * y);

                // Power.Simplify

                AssertIsTrue((0 ^ x) == 0);
                AssertIsTrue((1 ^ x) == 1);
                AssertIsTrue((x ^ 0) == 1);
                AssertIsTrue((x ^ 1) == x);

                // Product.Simplify

                AssertIsTrue(x * 0 == 0);

                // Difference

                AssertIsTrue(-x == -1 * x);

                AssertIsTrue(x - y == x + -1 * y);

                AssertIsTrue(Int(10).Substitute(Int(10), 20) == 20);
                AssertIsTrue(Int(10).Substitute(Int(15), 20) == 10);

                AssertIsTrue(new DoubleFloat(1.0).Substitute(new DoubleFloat(1.0), 2.0) == 2.0);
                AssertIsTrue(new DoubleFloat(1.0).Substitute(new DoubleFloat(1.5), 2.0) == 1.0);

                AssertIsTrue((Int(1) / 2).Substitute(Int(1) / 2, Int(3) / 4) == Int(3) / 4);
                AssertIsTrue((Int(1) / 2).Substitute(Int(1) / 3, Int(3) / 4) == Int(1) / 2);

                AssertIsTrue(x.Substitute(x, y) == y);
                AssertIsTrue(x.Substitute(y, y) == x);

                AssertIsTrue((x ^ y).Substitute(x, 10) == (10 ^ y));
                AssertIsTrue((x ^ y).Substitute(y, 10) == (x ^ 10));

                AssertIsTrue((x ^ y).Substitute(x ^ y, 10) == 10);

                AssertIsTrue((x * y * z).Substitute(x, y) == ((y ^ 2) * z));
                AssertIsTrue((x * y * z).Substitute(x * y * z, x) == x);

                AssertIsTrue((x + y + z).Substitute(x, y) == ((y * 2) + z));
                AssertIsTrue((x + y + z).Substitute(x + y + z, x) == x);

                AssertIsTrue(
                    ((((x * y) ^ (Int(1) / 2)) * (z ^ 2)) ^ 2)
                        .Substitute(x, 10)
                        .Substitute(y, 20)
                        .Substitute(z, 3)
                        == 16200
                        );

                AssertIsTrue(sin(new DoubleFloat(3.14159 / 2)) == 0.99999999999911982);

                AssertIsTrue(sin(x + y) + sin(x + y) == 2 * sin(x + y));

                AssertIsTrue(sin(x + x) == sin(2 * x));

                AssertIsTrue(sin(x + x).Substitute(x, 1) == sin(Int(2)));

                AssertIsTrue(sin(x + x).Substitute(x, 1.0) == 0.90929742682568171);

                AssertIsTrue(sin(2 * x).Substitute(x, y) == sin(2 * y));

                // Product.RecursiveSimplify

                AssertIsTrue(1 * x == x);

                AssertIsTrue(x * 1 == x);

                AssertIsTrue(x != y);

                AssertIsTrue(x != 10);

                // ==(double a, MathObject b)

                AssertIsTrue(1.0 == new DoubleFloat(3.0) - 2.0);

                // Console.WriteLine((x + x + x + x) / x);
            }

            #region PSE 5E Example 4.3
            {
                var thA = new Symbol("thA"); // angle at point A
                var vA = new Symbol("vA"); // velocity at point A

                var g = new Symbol("g"); // magnitude of gravity

                var _g = new Point(0, -g); // gravity vector

                var objA =
                    new Obj()
                    {
                        position = new Point(0, 0),
                        velocity = Point.FromAngle(thA, vA),
                        acceleration = _g,
                        time = new Integer(0)
                    };

                var objB =
                    new Obj()
                    {
                        velocity = new Point(objA.velocity.x, 0),
                        acceleration = _g
                    };

                var timeB = Calc.Time(objA, objB);
                var timeC = timeB * 2;

                objB = objA.AtTime(timeB);
                var objC = objA.AtTime(timeC);

                //Console.WriteLine("How far does he dump in the horizontal direction?");

                AssertIsTrue(objC.position.x == 2 * Trig.Cos(thA) * Trig.Sin(thA) * (vA ^ 2) / g);

                //Console.WriteLine("What is the maximum height reached?");

                AssertIsTrue(objB.position.y == (Trig.Sin(thA) ^ 2) * (vA ^ 2) / 2 / g);

                // Console.WriteLine("Distance jumped: ");

                var deg = 3.14159 / 180.0;

                AssertIsTrue(
                    objC.position.x
                    // .Substitute(thA, Trig.ToRadians(20))
                    .Substitute(thA, 20 * deg)
                    .Substitute(g, 9.8)
                    .Substitute(Trig.Pi, 3.14159)
                    .Substitute(vA, 11)
                    ==
                    7.9364536850196412);

                //Console.WriteLine("Maximum height reached: ");

                AssertIsTrue(
                    objB.position.y
                    .Substitute(g, 9.8)
                    .Substitute(thA, Trig.ToRadians(20))
                    .Substitute(Trig.Pi, 3.14159)
                    .Substitute(vA, 11)
                    ==
                    0.72215756424454336);
            }
            #endregion

            #region PSE 5E EXAMPLE 4.5
            {
                // A stone is thrown from the top of a building upward at an
                // angle of 30.0° to the horizontal and with an initial speed of
                // 20.0 m/s, as shown in Figure 4.12. If the height of the building
                // is 45.0 m, (a) how long is it before the stone hits the ground?
                // (b) What is the speed of the stone just before it strikes the
                // ground?

                var thA = new Symbol("thA"); // angle at point A
                var vA = new Symbol("vA"); // velocity at point A

                var g = new Symbol("g"); // magnitude of gravity

                var _g = new Point(0, -g); // gravity vector

                var objA = new Obj()
                {
                    position = new Point(0, 0),
                    velocity = Point.FromAngle(thA, vA),
                    acceleration = _g,
                    time = new Integer(0)
                };

                var objB = new Obj()
                {
                    velocity = new Point(objA.velocity.x, 0),
                    acceleration = _g,
                };

                var timeB = Calc.Time(objA, objB);

                objB = objA.AtTime(timeB);

                var timeC = timeB * 2;

                var objC = objA.AtTime(timeC);

                var yD = new Symbol("yD");

                var objD = new Obj()
                {
                    position = new Point(null, yD),
                    velocity = new Point(objA.velocity.x, null),
                    acceleration = _g
                };

                var timeAD = Calc.Time(objA, objD, 1);

                objD = objA.AtTime(timeAD);

                // "How long is it before the stone hits the ground?".Disp();

                // "Symbolic answer:".Disp();

                AssertIsTrue(
                    timeAD
                    ==
                    -1 * (g ^ -1) * (-1 * Trig.Sin(thA) * vA + -1 * (((Trig.Sin(thA) ^ 2) * (vA ^ 2) + -2 * g * yD) ^ (new Integer(1) / 2))));

                // "Numeric answer:".Disp();

                AssertEqual(
                    (DoubleFloat)
                    timeAD
                        .Substitute(g, 9.8)
                        .Substitute(thA, (30).ToRadians())
                        .Substitute(Trig.Pi, 3.14159)
                        .Substitute(vA, 20)
                        .Substitute(yD, -45),
                    new DoubleFloat(4.21804787012706),
                    0.0001);

                // "What is the speed of the stone just before it strikes the ground?".Disp();

                // "Symbolic answer:".Disp();

                AssertIsTrue(
                    objD.velocity.Norm()
                    ==
                    (((Trig.Cos(thA) ^ 2) * (vA ^ 2) + (Trig.Sin(thA) ^ 2) * (vA ^ 2) + -2 * g * yD) ^ (new Integer(1) / 2)));

                // "Numeric answer:".Disp();

                AssertEqual(
                    (DoubleFloat)
                    objD.velocity.Norm()
                        .Substitute(g, 9.8)
                        .Substitute(thA, (30).ToRadians())
                        .Substitute(Trig.Pi, 3.14159)
                        .Substitute(vA, 20)
                        .Substitute(yD, -45),
                    new DoubleFloat(35.805027579936315),
                    0.1);
            }
            #endregion

            #region PSE 5E EXAMPLE 4.6
            {
                // An Alaskan rescue plane drops a package of emergency rations
                // to a stranded party of explorers, as shown in Figure
                // 4.13. If the plane is traveling horizontally at 40.0 m/s and is
                // 100 m above the ground, where does the package strike the
                // ground relative to the point at which it was released?

                var xA = new Symbol("xA");      // position.x at point A

                var yA = new Symbol("yA");      // position.y at point A

                var thA = new Symbol("thA");    // angle at point A

                var vA = new Symbol("vA");      // velocity at point A

                var g = new Symbol("g");        // magnitude of gravity

                var _g = new Point(0, -g);      // gravity vector

                var objA = new Obj()            // obj at the initial position
                {
                    position = new Point(xA, yA),
                    velocity = Point.FromAngle(thA, vA),
                    acceleration = _g,
                    time = 0
                };

                var objB = new Obj()            // obj at the final position
                {
                    position = new Point(null, 0),
                    velocity = new Point(objA.velocity.x, null),
                    acceleration = _g
                };

                var timeB = Calc.Time(objA, objB, 1);

                objB = objA.AtTime(timeB);

                //"Where does the package strike the ground relative to the point at which it was released?".Disp(); "".Disp();

                //"symbolic:".Disp();

                //objB.position.x.Disp(); "".Disp();

                AssertIsTrue(
                    objB.position.x
                    ==
                    xA - cos(thA) / g * vA * (-sin(thA) * vA - (((sin(thA) ^ 2) * (vA ^ 2) + 2 * g * yA) ^ new Integer(1) / 2)));

                //"numeric:".Disp();

                //objB.position.x
                //    .Substitute(xA, 0)
                //    .Substitute(yA, 100)
                //    .Substitute(vA, 40)
                //    .Substitute(thA, 0.0)
                //    .Substitute(g, 9.8)
                //    .Disp();

                AssertEqual(
                    objB.position.x
                        .Substitute(xA, 0)
                        .Substitute(yA, 100)
                        .Substitute(vA, 40)
                        .Substitute(thA, 0.0)
                        .Substitute(g, 9.8),
                    180.70158058105025);

                //"".Disp();

                //("What are the horizontal and vertical components " +
                // "of the velocity of the package just before it hits the ground?").Disp(); "".Disp();

                //"symbolic velocity.x:".Disp();

                //objB.velocity.x.Disp(); "".Disp();

                AssertIsTrue(objB.velocity.x == cos(thA) * vA);

                //"symbolic velocity.y:".Disp();

                //objB.velocity.y.Disp(); "".Disp();

                AssertIsTrue(
                    objB.velocity.y
                    ==
                    -1 * (((sin(thA) ^ 2) * (vA ^ 2) + 2 * g * yA) ^ (new Integer(1) / 2)));

                //"numeric velocity.x:".Disp();

                //objB.velocity.x
                //    .Substitute(xA, 0)
                //    .Substitute(yA, 100)
                //    .Substitute(vA, 40)
                //    .Substitute(thA, 0.0)
                //    .Substitute(g, 9.8)
                //    .Disp(); "".Disp();

                AssertEqual(
                    objB.velocity.x
                        .Substitute(xA, 0)
                        .Substitute(yA, 100)
                        .Substitute(vA, 40)
                        .Substitute(thA, 0.0)
                        .Substitute(g, 9.8),
                    40);

                //"numeric velocity.y:".Disp();

                //objB.velocity.y
                //    .Substitute(xA, 0)
                //    .Substitute(yA, 100)
                //    .Substitute(vA, 40)
                //    .Substitute(thA, 0.0)
                //    .Substitute(g, 9.8)
                //    .Disp(); "".Disp();

                AssertEqual(
                    objB.velocity.y
                        .Substitute(xA, 0)
                        .Substitute(yA, 100)
                        .Substitute(vA, 40)
                        .Substitute(thA, 0.0)
                        .Substitute(g, 9.8),
                    -44.271887242357316);
            }
            #endregion

            #region PSE 5E EXAMPLE 4.7

            {
                // A ski jumper leaves the ski track moving in the horizontal
                // direction with a speed of 25.0 m/s, as shown in Figure 4.14.
                // The landing incline below him falls off with a slope of 35.0°.
                // Where does he land on the incline?

                var thA = new Symbol("thA");    // angle at point A

                var vA = new Symbol("vA");      // velocity at point A

                var g = new Symbol("g");        // magnitude of gravity

                var _g = new Point(0, -g);      // gravity vector

                var th = new Symbol("th");      // angle of incline

                var objA = new Obj()
                {
                    position = new Point(0, 0),
                    velocity = Point.FromAngle(thA, vA),
                    acceleration = _g,
                    time = 0
                };

                Func<MathObject, MathObject> numeric = obj =>
                    obj
                        .Substitute(vA, 25)
                        .Substitute(thA, 0.0)
                        .Substitute(th, (-35).ToRadians())
                        .Substitute(Trig.Pi, 3.14159)
                        .Substitute(g, 9.8);

                var intersection = objA.ProjectileInclineIntersection(th);

                Action nl = () => "".Disp();

                // "Where does he land on the incline?".Disp(); nl();

                // "x position (symbolic):".Disp();

                // intersection.x.Disp(); nl();

                AssertIsTrue(
                    intersection.x
                    ==
                    -2 * (cos(th) ^ -1) * (cos(thA) ^ 2) * (g ^ -1) * (sin(th) + -1 * cos(th) * (cos(thA) ^ -1) * sin(thA)) * (vA ^ 2));

                //"y position (symbolic):".Disp();

                //intersection.y.Disp(); nl();

                AssertIsTrue(
                    intersection.y
                    ==
                    -2 * (cos(th) ^ -2) * (cos(thA) ^ 2) / g * sin(th) * (sin(th) + -1 * cos(th) * (cos(thA) ^ -1) * sin(thA)) * (vA ^ 2));

                //"x position (numeric):".Disp();

                //numeric(intersection.x).Disp(); nl();

                AssertEqual(numeric(intersection.x), 89.3120879153208);

                //"y position (numeric):".Disp();

                //numeric(intersection.y).Disp(); nl();

                AssertEqual(numeric(intersection.y), -62.536928534704884);

                var objB = new Obj()
                {
                    position = intersection,
                    acceleration = _g
                };

                //"Determine how long the jumper is airborne".Disp(); nl();

                //"symbolic:".Disp();

                var timeB = Calc.Time(objA, objB, 1);

                // timeB.Disp(); nl();

                Func<MathObject, MathObject> sqrt = obj => obj ^ (new Integer(1) / 2);

                AssertIsTrue(
                    timeB
                    ==
                    -1 / g *
                    (-sin(thA) * vA -
                        sqrt(
                            (sin(thA) ^ 2) * (vA ^ 2) + 4 * (cos(th) ^ -2) * (cos(thA) ^ 2) * sin(th) *
                            (sin(th) - cos(th) / cos(thA) * sin(thA)) *
                            (vA ^ 2))));

                //"numeric:".Disp();

                //numeric(timeB).Disp(); nl();

                AssertEqual(numeric(timeB), 3.5724835166128317);

                objB = objA.AtTime(timeB);

                //"Determine his vertical component of velocity just before he lands".Disp();
                //nl();

                //"symbolic:".Disp();

                //objB.velocity.y.Disp(); nl();

                AssertIsTrue(
                    objB.velocity.y
                    ==
                    -sqrt(
                        (sin(thA) ^ 2) * (vA ^ 2)
                        +
                        4 * (cos(th) ^ -2) * (cos(thA) ^ 2) * sin(th) *
                        (sin(th) - cos(th) * (cos(thA) ^ -1) * sin(thA)) *
                        (vA ^ 2)));

                //"numeric:".Disp();

                //numeric(objB.velocity.y).Disp();

                AssertEqual(
                    numeric(objB.velocity.y),
                    -35.010338462805755);
            }

            #endregion

            #region PSE 5E PROBLEM 4.11

            {
                // One strategy in a snowball fight is to throw a first snowball at a
                // high angle over level ground. While your opponent is watching the
                // first one, you throw a second one at a low angle and timed to arrive
                // at your opponent before or at the same time as the first one. Assume
                // both snowballs are thrown with a speed of 25.0 m/s. The first one is
                // thrown at an angle of 70.0° with respect to the horizontal.
                //
                // (a) At what angle should the second (low-angle) snowball be thrown
                // if it is to land at the same point as the first?
                //
                // (b) How many seconds later should the second snowball be thrown if it
                // is to land at the same time as the first?

                var xA = new Symbol("xA");      // position.x at point A
                var yA = new Symbol("yA");      // position.y at point A
                var th1A = new Symbol("th1A");  // angle of snowball 1 at point A
                var vA = new Symbol("vA");      // velocity at point A

                var g = new Symbol("g");        // magnitude of gravity
                var _g = new Point(0, -g);      // gravity vector

                //Func<MathObject, MathObject> numeric = obj =>
                //    obj
                //        .Substitute(xA, 0)
                //        .Substitute(xB, 1.4)
                //        .Substitute(yA, 0.86)
                //        .Substitute(g, 9.8)
                //        .Substitute(Trig.Pi, 3.14159);

                var obj1A = new Obj()           // snowball 1 at initial point
                {
                    position = new Point(xA, yA),
                    velocity = Point.FromAngle(th1A, vA),
                    acceleration = _g,
                    time = 0
                };

                var obj1B = new Obj()            // snowball 1 at final point
                {
                    position = new Point(null, 0),
                    velocity = new Point(obj1A.velocity.x, null),
                    acceleration = _g
                };

                var time1B = Calc.Time(obj1A, obj1B, 1);

                obj1B = obj1A.AtTime(time1B);

                var obj2A = new Obj()           // snowball 2 at initial point
                {
                    position = obj1A.position,
                    speed = vA,
                    acceleration = _g
                };

                var obj2B = new Obj()           // snowball 2 at final point
                {
                    position = obj1B.position,
                    acceleration = _g
                };

                //Calc.InitialAngle(obj2A, obj2B, 1, 0)
                //    .Substitute(yA, 0)
                //    .Substitute(th1A, (70).ToRadians())
                //    .Substitute(vA, 25)
                //    .Substitute(Trig.Pi, 3.14159)
                //    .Substitute(g, 9.8)
                //    .ToDegrees()
                //    .Substitute(Trig.Pi, 3.14159)
                //    .Disp();

                var th2 = Calc.InitialAngle(obj2A, obj2B, 0, 0);

                //("At what angle should the second (low-angle) snowball " +
                //"be thrown if it is to land at the same point as the first?").Disp();

                //"".Disp();

                //"symbolic:".Disp();

                //th2.Disp(); "".Disp();

                //"numeric:".Disp();

                AssertEqual(
                    th2
                        .ToDegrees()
                        .Substitute(yA, 0)
                        .Substitute(th1A, (70).ToRadians())
                        .Substitute(vA, 25)
                        .Substitute(g, 9.8)
                        .Substitute(Trig.Pi, Math.PI),
                    20.000000000000007);

                //"".Disp();

                obj2A.velocity = Point.FromAngle(th2, vA);

                var time2B = Calc.Time(obj2A, obj2B, 1);

                //("How many seconds later should the second snowball be thrown if it " +
                //"is to land at the same time as the first?").Disp();

                //"".Disp();

                //"symbolic:".Disp();

                //(time1B - time2B).Disp(); "".Disp();

                //"numeric:".Disp();

                //(time1B - time2B)
                //    .Substitute(yA, 0)
                //    .Substitute(th1A, (70).ToRadians())
                //    .Substitute(vA, 25)
                //    .Substitute(Trig.Pi, 3.14159)
                //    .Substitute(g, 9.8)
                //    .Disp();

                AssertEqual(
                    (time1B - time2B)
                        .Substitute(yA, 0)
                        .Substitute(th1A, (70).ToRadians())
                        .Substitute(vA, 25)
                        .Substitute(Trig.Pi, 3.14159)
                        .Substitute(g, 9.8),
                    3.0493426265020469);

                //Console.ReadLine();
            }

            #endregion

            #region PSE 5E PROBLEM 4.17

            {
                // A cannon with a muzzle speed of 1 000 m/s is used to
                // start an avalanche on a mountain slope. The target is
                // 2 000 m from the cannon horizontally and 800 m above
                // the cannon. At what angle, above the horizontal, should
                // the cannon be fired?

                var xA = new Symbol("xA");      // position.x at point A
                var yA = new Symbol("yA");      // position.y at point A
                var thA = new Symbol("thA");  // angle of snowball 1 at point A
                var vA = new Symbol("vA");      // velocity at point A

                var xB = new Symbol("xB");      // position.x at point A
                var yB = new Symbol("yB");      // position.y at point A

                var g = new Symbol("g");        // magnitude of gravity
                var _g = new Point(0, -g);      // gravity vector

                var objA = new Obj()
                {
                    position = new Point(xA, yA),
                    speed = vA,
                    acceleration = _g,
                    time = 0
                };

                var objB = new Obj()
                {
                    position = new Point(xB, yB),
                    acceleration = _g
                };

                //"At what angle, above the horizontal, should the cannon be fired?".Disp();

                AssertEqual(
                    Calc.InitialAngle(objA, objB)
                        .ToDegrees()
                        .Substitute(xA, 0)
                        .Substitute(yA, 0)
                        .Substitute(xB, 2000.0)
                        .Substitute(yB, 800)
                        .Substitute(vA, 1000)
                        .Substitute(g, 9.8)
                        .Substitute(Trig.Pi, Math.PI),
                    22.365163229244317);

                //Calc.InitialAngle(objA, objB)
                //    .ToDegrees()
                //    .Substitute(xA, 0)
                //    .Substitute(yA, 0)
                //    .Substitute(xB, 2000.0)
                //    .Substitute(yB, 800)
                //    .Substitute(vA, 1000)
                //    .Substitute(g, 9.8)
                //    .Substitute(Trig.Pi, Math.PI)
                //    .Disp();
            }

            #endregion

            #region PSE 5E PROBLEM 4.24
            {
                // A bag of cement of weight 325 N hangs from three
                // wires as shown in Figure P5.24. Two of the wires make
                // angles th1 = 60.0° and th2 = 25.0° with the horizontal. If
                // the system is in equilibrium, find the tensions
                // T1, T2, and T3 in the wires.

                var F1 = new Symbol("F1");
                var F2 = new Symbol("F2");
                var F3 = new Symbol("F3");

                var th1 = new Symbol("th1");
                var th2 = new Symbol("th2");
                var th3 = new Symbol("th3");

                var _F1 = new Point() { angle = th1 };
                var _F2 = new Point() { angle = th2 };
                var _F3 = new Point() { magnitude = F3, angle = th3 };

                var m = new Symbol("m");

                var obj = new Obj();

                obj.acceleration.x = 0;
                obj.acceleration.y = 0;

                obj.mass = m;

                obj.forces.Add(_F1);
                obj.forces.Add(_F2);
                obj.forces.Add(_F3);

                //"F1 magnitude, symbolic:".Disp(); "".Disp();

                //obj.ForceMagnitude(_F1).Disp(); "".Disp();

                //"F1 magnitude, numeric:".Disp(); "".Disp();

                //obj.ForceMagnitude(_F1)
                //    .Substitute(F3, 325)
                //    .Substitute(th1, (180 - 60).ToRadians())
                //    .Substitute(th2, (25).ToRadians())
                //    .Substitute(th3, (270).ToRadians())
                //    .Substitute(Trig.Pi, Math.PI)
                //    .Disp();

                AssertEqual(
                    obj.ForceMagnitude(_F1)
                        .Substitute(F3, 325)
                        .Substitute(th1, (180 - 60).ToRadians())
                        .Substitute(th2, (25).ToRadians())
                        .Substitute(th3, (270).ToRadians())
                        .Substitute(Trig.Pi, Math.PI),
                    295.67516405290525);

                // "".Disp();

                //"F3 magnitude, numeric:".Disp(); "".Disp();

                //obj.ForceMagnitude(_F2)
                //    .Substitute(F3, 325)
                //    .Substitute(th1, (180 - 60).ToRadians())
                //    .Substitute(th2, (25).ToRadians())
                //    .Substitute(th3, (270).ToRadians())
                //    .Substitute(Trig.Pi, Math.PI)
                //    .Disp();

                AssertEqual(
                    obj.ForceMagnitude(_F2)
                        .Substitute(F3, 325)
                        .Substitute(th1, (180 - 60).ToRadians())
                        .Substitute(th2, (25).ToRadians())
                        .Substitute(th3, (270).ToRadians())
                        .Substitute(Trig.Pi, Math.PI),
                    163.12072360079395);
            }
            #endregion

            #region PSE 5E PROBLEM 5.26
            {
                // You are a judge in a children’s kite-flying contest, and
                // two children will win prizes for the kites that pull most
                // strongly and least strongly on their strings. To measure
                // string tensions, you borrow a weight hanger, some slotted
                // weights, and a protractor from your physics teacher
                // and use the following protocol, illustrated in Figure
                // P5.26: Wait for a child to get her kite well-controlled,
                // hook the hanger onto the kite string about 30 cm from
                // her hand, pile on weights until that section of string is
                // horizontal, record the mass required, and record the
                // angle between the horizontal and the string running up
                // to the kite. (a) Explain how this method works. As you
                // construct your explanation, imagine that the children’s
                // parents ask you about your method, that they might
                // make false assumptions about your ability without concrete
                // evidence, and that your explanation is an opportunity to
                // give them confidence in your evaluation tech-nique.
                // (b) Find the string tension if the mass required
                // to make the string horizontal is 132 g and the angle of
                // the kite string is 46.3°.

                var F1 = new Symbol("F1");
                var F2 = new Symbol("F2");
                var F3 = new Symbol("F3");

                var th1 = new Symbol("th1");
                var th2 = new Symbol("th2");
                var th3 = new Symbol("th3");

                var _F1 = new Point() { angle = th1 };
                var _F2 = new Point() { angle = th2 };
                var _F3 = new Point() { magnitude = F3, angle = th3 };

                var m = new Symbol("m");

                var obj = new Obj();

                obj.acceleration.x = 0;
                obj.acceleration.y = 0;

                obj.mass = m;

                obj.forces.Add(_F1);
                obj.forces.Add(_F2);
                obj.forces.Add(_F3);

                //"Tension in line to kite:".Disp(); "".Disp();

                //obj.ForceMagnitude(_F2)
                //    .Substitute(th1, (180).ToRadians())
                //    .Substitute(th2, (46.3 * Math.PI / 180))
                //    .Substitute(th3, (270).ToRadians())
                //    .Substitute(F3, 0.132 * 9.8)
                //    .Substitute(Trig.Pi, Math.PI)
                //    .Disp();

                AssertEqual(
                    obj.ForceMagnitude(_F2)
                        .Substitute(th1, (180).ToRadians())
                        .Substitute(th2, (46.3 * Math.PI / 180))
                        .Substitute(th3, (270).ToRadians())
                        .Substitute(F3, 0.132 * 9.8)
                        .Substitute(Trig.Pi, Math.PI),
                    1.7892929261294661);

                //Console.ReadLine();
            }
            #endregion

            #region PSE 5E PROBLEM 5.28
            {
                // A fire helicopter carries a 620-kg bucket of water at the
                // end of a cable 20.0 m long. As the aircraft flies back
                // from a fire at a constant speed of 40.0 m/s, the cable
                // makes an angle of 40.0° with respect to the vertical.
                // (a) Determine the force of air resistance on the bucket.
                // (b) After filling the bucket with sea water, the pilot re-
                // turns to the fire at the same speed with the bucket now
                // making an angle of 7.00° with the vertical. What is the
                // mass of the water in the bucket?

                var F1 = new Symbol("F1"); // force of air resistance
                var F2 = new Symbol("F2"); // force of cable
                var F3 = new Symbol("F3"); // force of gravity

                var th1 = new Symbol("th1");
                var th2 = new Symbol("th2");
                var th3 = new Symbol("th3");

                var _F1 = new Point() { angle = th1 };
                var _F2 = new Point() { angle = th2 };
                var _F3 = new Point() { magnitude = F3, angle = th3 };

                var m = new Symbol("m");

                var obj = new Obj();

                obj.acceleration.x = 0;
                obj.acceleration.y = 0;

                obj.mass = m;

                obj.forces.Add(_F1);
                obj.forces.Add(_F2);
                obj.forces.Add(_F3);

                //"Force of air resistance on the bucket:".Disp(); "".Disp();

                var FAir =
                    obj.ForceMagnitude(_F1)
                        .Substitute(F3, 620 * 9.8)
                        .Substitute(th1, (180).ToRadians())
                        .Substitute(th2, (90 - 40).ToRadians())
                        .Substitute(th3, (270).ToRadians())
                        .Substitute(Trig.Pi, Math.PI);

                AssertEqual(
                    obj.ForceMagnitude(_F1)
                        .Substitute(F3, 620 * 9.8)
                        .Substitute(th1, (180).ToRadians())
                        .Substitute(th2, (90 - 40).ToRadians())
                        .Substitute(th3, (270).ToRadians())
                        .Substitute(Trig.Pi, Math.PI),
                    5098.3693590331513);

                //"".Disp();

                _F1.magnitude = FAir;

                _F3.magnitude = null;

                var FBucketWithWater =
                    obj.ForceMagnitude(_F3)
                        .Substitute(th1, (180).ToRadians())
                        .Substitute(th2, (90 - 7).ToRadians())
                        .Substitute(th3, (270).ToRadians())
                        .Substitute(Trig.Pi, Math.PI);

                //"What is the mass of the water in the bucket?".Disp(); "".Disp();

                //(FBucketWithWater / 9.8 - 620).Disp();

                AssertEqual(
                    (FBucketWithWater / 9.8 - 620),
                    3617.0292120139611);
            }
            #endregion

            #region PSE 5E PROBLEM 5.30
            {
                // A simple accelerometer is constructed by suspending a
                // mass m from a string of length L that is tied to the top
                // of a cart. As the cart is accelerated the string-mass
                // system makes a constant angle th with the vertical.
                // (a) Assuming that the string mass is negligible compared
                // with m, derive an expression for the cart’s acceleration
                // in terms of and show that it is independent of
                // the mass mand the length L.
                // (b) Determine the acceleration of the cart when th = 23.0°.

                var F1 = new Symbol("F1"); // force of string
                var F2 = new Symbol("F2"); // force of gravity

                var th1 = new Symbol("th1");
                var th2 = new Symbol("th2"); ;

                var _F1 = new Point() { angle = th1 };
                var _F2 = new Point() { angle = th2, magnitude = F2 };

                var m = new Symbol("m");

                var g = new Symbol("g");

                var obj = new Obj() { mass = m };

                obj.acceleration.y = 0;

                obj.forces.Add(_F1);
                obj.forces.Add(_F2);

                _F1.magnitude = obj.ForceMagnitude(_F1);

                //("Derive an expression for the cart’s acceleration in terms " +
                //"of and show that it is independent of the mass mand the length L:").Disp();

                //"".Disp();

                //obj.AccelerationX()
                //    .Substitute(F2, m * g)
                //    .Substitute(Trig.Cos(th2), 0)
                //    .Substitute(Trig.Sin(th2), -1)
                //    .Disp();

                //"".Disp();

                //"Determine the acceleration of the cart when th = 23.0°".Disp(); "".Disp();

                //obj.AccelerationX()
                //    .Substitute(F2, m * g)
                //    .Substitute(Trig.Cos(th2), 0)
                //    .Substitute(Trig.Sin(th2), -1)
                //    .Substitute(th1, (90 - 23).ToRadians())
                //    .Substitute(Trig.Pi, Math.PI)
                //    .Substitute(g, 9.8)
                //    .Disp();

                AssertEqual(
                    obj.AccelerationX()
                        .Substitute(F2, m * g)
                        .Substitute(Trig.Cos(th2), 0)
                        .Substitute(Trig.Sin(th2), -1)
                        .Substitute(th1, (90 - 23).ToRadians())
                        .Substitute(Trig.Pi, Math.PI)
                        .Substitute(g, 9.8),
                    4.1598531988541261);
            }
            #endregion

            #region PSE 5E PROBLEM 5.31
            {
                // Two people pull as hard as they can on ropes attached
                // to a boat that has a mass of 200 kg. If they pull in the
                // same direction, the boat has an acceleration of
                // 1.52 m/s^2 to the right. If they pull in opposite directions,
                // the boat has an acceleration of 0.518 m/s^2
                // to the left. What is the force exerted by each person on the
                // boat? (Disregard any other forces on the boat.)

                // Trig.Cos(new DoubleFloat(Math.PI)).Disp();

                var m = new Symbol("m");

                var aAx = new Symbol("aAx");
                var aBx = new Symbol("aBx");

                var objA = new Obj() { mass = m };

                objA.acceleration.x = aAx;

                var _F1A = new Point() { angle = 0 };
                var _F2A = new Point() { angle = 0 };

                objA.forces.Add(_F1A);
                objA.forces.Add(_F2A);

                var objB = new Obj() { mass = m };

                objB.acceleration.x = aBx;

                var _F1B = new Point() { angle = 0 };
                var _F2B = new Point() { angle = new DoubleFloat(Math.PI) };

                objB.forces.Add(_F1B);
                objB.forces.Add(_F2B);

                //"force 1 magnitude (symbolic):".Disp(); "".Disp();

                //Calc.ForceMagnitude(objA, objB, _F1A, _F1B)
                //    .Substitute(Trig.Cos(0), 1)
                //    .Disp();

                //"force 1 magnitude (numeric):".Disp(); "".Disp();

                //Calc.ForceMagnitude(objA, objB, _F1A, _F1B)
                //    .Substitute(Trig.Cos(0), 1)
                //    .Substitute(m, 200)
                //    .Substitute(aAx, 1.52)
                //    .Substitute(aBx, -0.518)
                //    .Disp();

                AssertEqual(
                    Calc.ForceMagnitude(objA, objB, _F1A, _F1B)
                        .Substitute(Trig.Cos(0), 1)
                        .Substitute(m, 200)
                        .Substitute(aAx, 1.52)
                        .Substitute(aBx, -0.518),
                    100.19999999999999);

                //"".Disp();

                //"force 2 magnitude (symbolic):".Disp(); "".Disp();

                //Calc.ForceMagnitude(objA, objB, _F2A, _F2B)
                //    .Substitute(Trig.Cos(0), 1)
                //    .Disp();

                //"force 2 magnitude (numeric):".Disp(); "".Disp();

                //Calc.ForceMagnitude(objA, objB, _F2A, _F2B)
                //    .Substitute(Trig.Cos(0), 1)
                //    .Substitute(m, 200)
                //    .Substitute(aAx, 1.52)
                //    .Substitute(aBx, -0.518)
                //    .Disp();

                //"".Disp();

                AssertEqual(
                    Calc.ForceMagnitude(objA, objB, _F2A, _F2B)
                        .Substitute(Trig.Cos(0), 1)
                        .Substitute(m, 200)
                        .Substitute(aAx, 1.52)
                        .Substitute(aBx, -0.518),
                    203.8);

            }
            #endregion

            Console.WriteLine("Testing complete");

            Console.ReadLine();
        }
예제 #7
0
        static void Main(string[] args)
        {
            // Three forces, given by _F1 = (-2.00i + 2.00j) N,
            // _F2 = (5.00i - 3.00j) N, and _F3 = (-45.0i) N,
            // act on an object to give
            // it an acceleration of magnitude 3.75 m/s^2.
            // (a) What is the direction of the acceleration? (b) What
            // is the mass of the object? (c) If the object is initially at
            // rest, what is its speed after 10.0 s?
            // (d) What are the velocity components of the object after 10.0 s?

            var F1x = new Symbol("F1x");
            var F1y = new Symbol("F1y");
            var F2x = new Symbol("F2x");
            var F2y = new Symbol("F2y");
            var F3x = new Symbol("F3x");
            var F3y = new Symbol("F3y");

            var a = new Symbol("a");

            var t = new Symbol("t");

            var obj = new Obj()
            {
                forces = new List<Point>()
                {
                    new Point(F1x, F1y),
                    new Point(F2x, F2y),
                    new Point(F3x, F3y)
                }
            };

            "What is the direction of the acceleration?".Disp(); "".Disp();

            "symbolic:".Disp(); "".Disp();

            obj.TotalForce().ToAngle().Disp(); "".Disp();

            "numeric:".Disp(); "".Disp();

            obj.TotalForce().ToAngle()
                .ToDegrees()
                .Substitute(F1x, -2)
                .Substitute(F1y, 2)
                .Substitute(F2x, 5)
                .Substitute(F2y, -3)
                .Substitute(F3x, -45)
                .Substitute(F3y, 0)
                .Substitute(Trig.Pi, Math.PI)
                .Disp();

            "".Disp();

            "What is the mass of the object?".Disp(); "".Disp();

            obj.totalForce = obj.TotalForce();

            obj.acceleration = Point.FromAngle(obj.totalForce.ToAngle(), a);

            obj.mass = obj.Mass();

            "symbolic:".Disp(); "".Disp();

            obj.mass.Disp(); "".Disp();

            "numeric:".Disp(); "".Disp();

            obj.mass
                .Substitute(a, 3.75)
                .Substitute(F1x, -2)
                .Substitute(F1y, 2)
                .Substitute(F2x, 5)
                .Substitute(F2y, -3)
                .Substitute(F3x, -45)
                .Substitute(F3y, 0)
                .Disp();

            "".Disp();

            "If the object is initially at rest, what is its speed after 10.0 s?".Disp();

            "".Disp();

            obj.velocity = new Point(0, 0);

            obj.time = 0;

            obj.VelocityAtTime(t).Norm().Disp();

            "".Disp();

            obj.VelocityAtTime(t).Norm()
                .Substitute(a, 3.75)
                .Substitute(F1x, -2)
                .Substitute(F1y, 2)
                .Substitute(F2x, 5)
                .Substitute(F2y, -3)
                .Substitute(F3x, -45)
                .Substitute(F3y, 0)
                .Substitute(t, 10)
                .Disp();

            "".Disp();

            "What are the velocity components of the object after 10.0 s?".Disp();

            "".Disp();

            "velocity.x: ".Disp();
            obj.VelocityAtTime(t).x
                .Substitute(a, 3.75)
                .Substitute(F1x, -2)
                .Substitute(F1y, 2)
                .Substitute(F2x, 5)
                .Substitute(F2y, -3)
                .Substitute(F3x, -45)
                .Substitute(F3y, 0)
                .Substitute(t, 10)
                .Disp(); "".Disp();

            "velocity.y: ".Disp();
            obj.VelocityAtTime(t).y
                .Substitute(a, 3.75)
                .Substitute(F1x, -2)
                .Substitute(F1y, 2)
                .Substitute(F2x, 5)
                .Substitute(F2y, -3)
                .Substitute(F3x, -45)
                .Substitute(F3y, 0)
                .Substitute(t, 10)
                .Disp(); "".Disp();

            Console.ReadLine();
        }
예제 #8
0
        static void Main(string[] args)
        {
            // A long-jumper leaves the ground at an angle of 20.0° above
            // the horizontal and at a speed of 11.0 m/s.
            // (a) How far does he jump in the horizontal direction?
            // (Assume his motion is equivalent to that of a particle.)
            // (b) What is the maximum height reached?

            // For the purposes of solving the problem, let's take
            //   point A as the initial position
            //   point B as the peak position
            //   point C as the final position.

            // First we'll get the answer in a symbolic form.

            var thA = new Symbol("thA"); // angle at point A
            var vA = new Symbol("vA"); // velocity at point A

            var g = new Symbol("g"); // magnitude of gravity

            var _g = new Point(0, -g); // gravity vector

            // An Obj representing the object at A:

            var objA =
                new Obj()
                {
                    position = new Point(0, 0),
                    velocity = Point.FromAngle(thA, vA),
                    acceleration = _g,
                    time = 0
                };

            var objB =
                new Obj()
                {
                    velocity = new Point(objA.velocity.x, 0),
                    acceleration = _g
                };

            var timeB = Calc.Time(objA, objB);
            var timeC = timeB * 2;

            objB = objA.AtTime(timeB);
            var objC = objA.AtTime(timeC);

            Console.WriteLine("How far does he jump in the horizontal direction?");
            Console.WriteLine(objC.position.x);

            Console.WriteLine();

            Console.WriteLine("What is the maximum height reached?");
            Console.WriteLine(objB.position.y);

            Console.WriteLine();

            Console.WriteLine("Now for the numerical solutions:");

            Console.WriteLine();

            Console.WriteLine("Distance jumped: ");

            Console.WriteLine(
                objC.position.x
                .Substitute(thA, Trig.ToRadians(20))
                .Substitute(g, 9.8)
                .Substitute(Trig.Pi, 3.14159)
                .Substitute(vA, 11)
                );

            Console.WriteLine();

            Console.WriteLine("Maximum height reached: ");

            Console.WriteLine(
                objB.position.y
                .Substitute(g, 9.8)
                .Substitute(thA, Trig.ToRadians(20))
                .Substitute(Trig.Pi, 3.14159)
                .Substitute(vA, 11)
                );

            Console.ReadLine();
        }
예제 #9
0
        static void Main(string[] args)
        {
            // A bag of cement of weight 325 N hangs from three
            // wires as shown in Figure P5.24. Two of the wires make
            // angles th1 = 60.0° and th2 = 25.0° with the horizontal. If
            // the system is in equilibrium, find the tensions
            // T1, T2, and T3 in the wires.

            // From problem 5.25:

            // If the system is in equilibrium, show that
            // the tension in the left-hand wire is
            //
            // T1 = Fg cos(th2) / sin(th1 + th2)

            var F3 = new Symbol("F3");

            var th1 = new Symbol("th1");
            var th2 = new Symbol("th2");
            var th3 = new Symbol("th3");

            var _F1 = new Point() { angle = th1 };
            var _F2 = new Point() { angle = th2 };
            var _F3 = new Point() { magnitude = F3, angle = th3 };

            var m = new Symbol("m");

            var obj = new Obj();

            obj.acceleration.x = 0;
            obj.acceleration.y = 0;

            obj.mass = m;

            obj.forces.Add(_F1);
            obj.forces.Add(_F2);
            obj.forces.Add(_F3);

            "F1 magnitude, symbolic:".Disp(); "".Disp();

            obj.ForceMagnitude(_F1).Disp(); "".Disp();

            "F1 magnitude, numeric:".Disp(); "".Disp();

            obj.ForceMagnitude(_F1)
                .Substitute(F3, 325)
                .Substitute(th1, (180 - 60).ToRadians())
                .Substitute(th2, (25).ToRadians())
                .Substitute(th3, (270).ToRadians())
                .Substitute(Trig.Pi, Math.PI)
                .Disp();

            "".Disp();

            "F3 magnitude, numeric:".Disp(); "".Disp();

            obj.ForceMagnitude(_F2)
                .Substitute(F3, 325)
                .Substitute(th1, (180 - 60).ToRadians())
                .Substitute(th2, (25).ToRadians())
                .Substitute(th3, (270).ToRadians())
                .Substitute(Trig.Pi, Math.PI)
                .Disp();

            Console.ReadLine();
        }
예제 #10
0
        static void Main(string[] args)
        {
            // A 15.0-lb block rests on the floor. (a) What force does
            // the floor exert on the block? (b) If a rope is tied to the
            // block and run vertically over a pulley, and the other end
            // is attached to a free-hanging 10.0-lb weight, what is the
            // force exerted by the floor on the 15.0-lb block? (c) If we
            // replace the 10.0-lb weight in part (b) with a 20.0-lb
            // weight, what is the force exerted by the floor on the
            // 15.0-lb block?

            var thn = new Symbol("thn"); // angle of normal force
            var thg = new Symbol("thg"); // angle of gravity force
            var th3 = new Symbol("th3");

            var Fn = new Symbol("Fn"); // normal force
            var Fg = new Symbol("Fg"); // gravity force
            var F3 = new Symbol("F3"); // rope force

            var m = new Symbol("m");
            var ay = new Symbol("ay");

            var g = new Symbol("g");

            {
                var obj = new Obj() { mass = m };

                obj.acceleration.y = ay;

                obj.forces.Add(new Point() { angle = thn });
                obj.forces.Add(new Point() { angle = thg, magnitude = Fg });

                "Without rope, normal force magnitude:".Disp(); "".Disp();

                obj.ForceMagnitude(obj.forces[0])
                    .Substitute(thn, (90).ToRadians())
                    .Substitute(thg, (270).ToRadians())
                    .Substitute(Trig.Pi, Math.PI)
                    .Substitute(Fg, 15)
                    .Substitute(ay, 0)
                    .Disp();

                "".Disp();
            }

            {
                var obj = new Obj() { mass = m };

                obj.acceleration.y = ay;

                obj.forces.Add(new Point() { angle = thn });
                obj.forces.Add(new Point() { angle = thg, magnitude = Fg });
                obj.forces.Add(new Point() { angle = th3, magnitude = F3 });

                "Rope & 10 lb weight, normal force magnitude:".Disp(); "".Disp();

                obj.ForceMagnitude(obj.forces[0])
                    .Substitute(thn, (90).ToRadians())
                    .Substitute(thg, (270).ToRadians())
                    .Substitute(th3, (90).ToRadians())
                    .Substitute(Trig.Pi, Math.PI)
                    .Substitute(Fg, 15)
                    .Substitute(F3, 10)
                    .Substitute(ay, 0)
                    .Disp();
            }

            Console.ReadLine();
        }
예제 #11
0
        static void Main(string[] args)
        {
            // Two forces _F1 and _F2 act on a 5.00-kg mass.
            // If F1 = 20.0 N and F2 = 15.0 N, find the accelerations in
            // (a) and (b) of Figure P5.15.

            var F1 = new Symbol("F1");
            var F2 = new Symbol("F2");

            var th1 = new Symbol("th1");
            var th2 = new Symbol("th2");

            var m = new Symbol("m");

            var obj = new Obj() { mass = m };

            obj.forces.Add(Point.FromAngle(th1, F1));
            obj.forces.Add(Point.FromAngle(th2, F2));

            "symbolic:".Disp(); "".Disp();

            "acceleration.x:".Disp(); "".Disp();

            obj.Acceleration().x.Disp(); "".Disp();

            "acceleration.y:".Disp(); "".Disp();

            obj.Acceleration().y.Disp(); "".Disp();

            "numeric (th2 = 90 deg):".Disp(); "".Disp();

            Console.Write("acceleration is ");

            Console.Write(
                obj.Acceleration().Norm()
                    .Substitute(th1, 0.0)
                    .Substitute(F1, 20)
                    .Substitute(th2, (90).ToRadians())
                    .Substitute(F2, 15)
                    .Substitute(m, 5)
                    .Substitute(Trig.Pi, Math.PI));

            Console.Write(" at ");

            Console.Write(
                obj.Acceleration().ToAngle().ToDegrees()
                    .Substitute(th1, 0.0)
                    .Substitute(F1, 20)
                    .Substitute(th2, (90).ToRadians())
                    .Substitute(F2, 15)
                    .Substitute(m, 5)
                    .Substitute(Trig.Pi, Math.PI));

            Console.Write(" degrees"); "".Disp(); "".Disp();

            "numeric (th2 = 60 deg):".Disp(); "".Disp();

            Console.Write("acceleration is ");

            Console.Write(
                obj.Acceleration().Norm()
                    .Substitute(th1, 0.0)
                    .Substitute(F1, 20)
                    .Substitute(th2, (60).ToRadians())
                    .Substitute(F2, 15)
                    .Substitute(m, 5)
                    .Substitute(Trig.Pi, Math.PI));

            Console.Write(" at ");

            Console.Write(
                obj.Acceleration().ToAngle().ToDegrees()
                    .Substitute(th1, 0.0)
                    .Substitute(F1, 20)
                    .Substitute(th2, (60).ToRadians())
                    .Substitute(F2, 15)
                    .Substitute(m, 5)
                    .Substitute(Trig.Pi, Math.PI));

            Console.Write(" degrees"); Console.WriteLine();

            Console.ReadLine();
        }
예제 #12
0
        static void Main(string[] args)
        {
            Action<Equation> AssertIsTrue = (eq) =>
            {
                if (!eq) Console.WriteLine(eq.ToString());
            };

            Func<MathObject, MathObject> sin = obj => Trig.Sin(obj);
            Func<MathObject, MathObject> cos = obj => Trig.Cos(obj);
            Func<MathObject, MathObject> tan = obj => new Tan(obj).Simplify();

            Func<MathObject, MathObject> asin = obj => new Asin(obj).Simplify();
            Func<MathObject, MathObject> atan = obj => new Atan(obj).Simplify();

            {
                var a = new Symbol("a");
                var b = new Symbol("b");
                var c = new Symbol("c");
                var d = new Symbol("d");

                var x = new Symbol("x");
                var y = new Symbol("y");
                var z = new Symbol("z");

                Func<int, Integer> Int = (n) => new Integer(n);

                {
                    DoubleFloat.tolerance = 0.000000001;

                    Assert(new DoubleFloat(1.2).Equals(new DoubleFloat(1.2)), "new DoubleFloat(1.2).Equals(new DoubleFloat(1.2))");

                    Assert(new DoubleFloat(1.20000001).Equals(new DoubleFloat(1.20000002)) == false, "new DoubleFloat(1.20000001).Equals(new DoubleFloat(1.20000002)) == false");

                    Assert(new DoubleFloat(1.2000000000001).Equals(new DoubleFloat(1.200000000002)), "new DoubleFloat(1.2000000000001).Equals(new DoubleFloat(1.200000000002))");

                    Assert(new DoubleFloat(1.2).Equals(new DoubleFloat(1.23)) == false, "new DoubleFloat(1.2).Equals(new DoubleFloat(1.23)) == false");

                    DoubleFloat.tolerance = null;
                }

                #region Simplify

                AssertIsTrue(x + x == 2 * x);

                AssertIsTrue(x + x == 2 * x);

                AssertIsTrue(x + x + x == 3 * x);

                AssertIsTrue(5 + x + 2 == 7 + x);

                AssertIsTrue(3 + x + 5 + x == 8 + 2 * x);

                AssertIsTrue(4 * x + 3 * x == 7 * x);

                AssertIsTrue(x + y + z + x + y + z == 2 * x + 2 * y + 2 * z);

                AssertIsTrue(10 - x == 10 + x * -1);

                AssertIsTrue(x * y / 3 == Int(1) / 3 * x * y);

                AssertIsTrue(x / y == x * (y ^ -1));

                AssertIsTrue(x / 3 == x * (Int(1) / 3));

                AssertIsTrue(6 * x * y / 3 == 2 * x * y);

                AssertIsTrue((((x ^ Int(1) / 2) ^ Int(1) / 2) ^ 8) == (x ^ 2));

                AssertIsTrue(((((x * y) ^ (Int(1) / 2)) * (z ^ 2)) ^ 2) == (x * y * (z ^ 4)));

                AssertIsTrue(x / x == 1);

                AssertIsTrue(x / y * y / x == 1);

                AssertIsTrue((x ^ 2) * (x ^ 3) == (x ^ 5));

                AssertIsTrue(x + y + x + z + 5 + z == 5 + 2 * x + y + 2 * z);

                AssertIsTrue(((Int(1) / 2) * x + (Int(3) / 4) * x) == Int(5) / 4 * x);

                AssertIsTrue(1.2 * x + 3 * x == 4.2 * x);

                AssertIsTrue(3 * x + 1.2 * x == 4.2 * x);

                AssertIsTrue(1.2 * x * 3 * y == 3.5999999999999996 * x * y);

                AssertIsTrue(3 * x * 1.2 * y == 3.5999999999999996 * x * y);

                AssertIsTrue(3.4 * x * 1.2 * y == 4.08 * x * y);

                AssertIsTrue((a == b) == (a == b));

                #endregion

                #region Power.Simplify

                AssertIsTrue((0 ^ x) == 0);
                AssertIsTrue((1 ^ x) == 1);
                AssertIsTrue((x ^ 0) == 1);
                AssertIsTrue((x ^ 1) == x);

                #endregion

                // Product.Simplify

                AssertIsTrue(x * 0 == 0);

                // Difference

                AssertIsTrue(-x == -1 * x);

                AssertIsTrue(x - y == x + -1 * y);

                #region Substitute

                AssertIsTrue(Int(10).Substitute(Int(10), 20) == 20);
                AssertIsTrue(Int(10).Substitute(Int(15), 20) == 10);

                AssertIsTrue(new DoubleFloat(1.0).Substitute(new DoubleFloat(1.0), 2.0) == 2.0);
                AssertIsTrue(new DoubleFloat(1.0).Substitute(new DoubleFloat(1.5), 2.0) == 1.0);

                AssertIsTrue((Int(1) / 2).Substitute(Int(1) / 2, Int(3) / 4) == Int(3) / 4);
                AssertIsTrue((Int(1) / 2).Substitute(Int(1) / 3, Int(3) / 4) == Int(1) / 2);

                AssertIsTrue(x.Substitute(x, y) == y);
                AssertIsTrue(x.Substitute(y, y) == x);

                AssertIsTrue((x ^ y).Substitute(x, 10) == (10 ^ y));
                AssertIsTrue((x ^ y).Substitute(y, 10) == (x ^ 10));

                AssertIsTrue((x ^ y).Substitute(x ^ y, 10) == 10);

                AssertIsTrue((x * y * z).Substitute(x, y) == ((y ^ 2) * z));
                AssertIsTrue((x * y * z).Substitute(x * y * z, x) == x);

                AssertIsTrue((x + y + z).Substitute(x, y) == ((y * 2) + z));
                AssertIsTrue((x + y + z).Substitute(x + y + z, x) == x);

                AssertIsTrue(
                    ((((x * y) ^ (Int(1) / 2)) * (z ^ 2)) ^ 2)
                        .Substitute(x, 10)
                        .Substitute(y, 20)
                        .Substitute(z, 3)
                        == 16200
                        );

                #region Equation.Substitute

                AssertIsTrue((x == y).Substitute(y, z) == (x == z));

                AssertIsTrue((x != y).Substitute(y, z) == (x != z));

                (x == 0).Substitute(x, 0).AssertEqTo(true);

                (x == 0).Substitute(x, 1).AssertEqTo(false);

                (x != 0).Substitute(x, 0).AssertEqTo(false);

                (x != 0).Substitute(x, 1).AssertEqTo(true);

                #endregion

                #endregion

                AssertIsTrue(sin(new DoubleFloat(3.14159 / 2)) == 0.99999999999911982);

                AssertIsTrue(sin(x + y) + sin(x + y) == 2 * sin(x + y));

                AssertIsTrue(sin(x + x) == sin(2 * x));

                AssertIsTrue(sin(x + x).Substitute(x, 1) == sin(Int(2)));

                AssertIsTrue(sin(x + x).Substitute(x, 1.0) == 0.90929742682568171);

                AssertIsTrue(sin(2 * x).Substitute(x, y) == sin(2 * y));

                // Product.RecursiveSimplify

                AssertIsTrue(1 * x == x);

                AssertIsTrue(x * 1 == x);

                AssertIsTrue(x != y);

                AssertIsTrue(x != 10);

                // ==(double a, MathObject b)

                AssertIsTrue(1.0 == new DoubleFloat(3.0) - 2.0);

                AssertIsTrue((a == b) != (a != b));

                #region Equation.ToString

                Assert((x == y).ToString() == "x == y", "x == y");

                Assert((x != y).ToString() == "x != y", "x != y");

                #endregion

                #region Function.ToString

                Assert(new And().ToString() == "And()", "And()");

                #endregion

                #region Equation.Simplify

                (new Integer(0) == new Integer(0)).Simplify().AssertEqTo(true);

                (new Integer(0) == new Integer(1)).Simplify().AssertEqTo(false);

                (new Integer(0) != new Integer(1)).Simplify().AssertEqTo(true);

                (new Integer(0) != new Integer(0)).Simplify().AssertEqTo(false);

                #endregion

                #region And

                new And().Simplify().AssertEqTo(true);

                new And(10).Simplify().AssertEqTo(10);

                new And(true).Simplify().AssertEqTo(true);

                new And(false).Simplify().AssertEqTo(false);

                new And(10, 20, 30).Simplify().AssertEqTo(new And(10, 20, 30));

                new And(10, false, 20).Simplify().AssertEqTo(false);

                new And(10, true, 20).Simplify().AssertEqTo(new And(10, 20));

                new And(10, new And(20, 30), 40)
                    .Simplify()
                    .AssertEqTo(new And(10, 20, 30, 40));

                #endregion

                #region Or

                new Or(10).Simplify().AssertEqTo(10);

                new Or(true).Simplify().AssertEqTo(true);

                new Or(false).Simplify().AssertEqTo(false);

                new Or(10, 20, false).Simplify().AssertEqTo(new Or(10, 20));

                new Or(false, false).Simplify().AssertEqTo(false);

                new Or(10, true, 20, false).Simplify().AssertEqTo(true);

                new Or(10, false, 20).Simplify().AssertEqTo(new Or(10, 20));

                new Or(10, new Or(20, 30), 40)
                    .Simplify()
                    .AssertEqTo(new Or(10, 20, 30, 40));

                #endregion

                #region Function.Map

                new And(1, 2, 3, 4, 5, 6).Map(elt => elt * 2)
                    .AssertEqTo(new And(2, 4, 6, 8, 10, 12));

                new And(1, 2, 3, 4, 5, 6).Map(elt => (elt is Integer) && (elt as Integer).val % 2 == 0 ? elt : false)
                    .AssertEqTo(false);

                new Or(1, 2, 3).Map(elt => elt * 2)
                    .AssertEqTo(new Or(2, 4, 6));

                new Or(1, 2, 3, 4, 5, 6).Map(elt => (elt is Integer) && (elt as Integer).val % 2 == 0 ? elt : false)
                    .AssertEqTo(new Or(2, 4, 6));

                #endregion Function.Map

                #region Sum

                Assert((x + y).Equals(x * y) == false, "(x + y).Equals(x * y)");

                #endregion

                #region Has

                Assert(a.Has(elt => elt == a), "a.Has(elt => elt == a)");

                Assert(a.Has(elt => elt == b) == false, "a.Has(elt => elt == b) == false");

                Assert((a == b).Has(elt => elt == a), "Has - 3");

                Assert((a == b).Has(elt => elt == c) == false, "Has - 4");

                Assert(((a + b) ^ c).Has(elt => elt == a + b), "Has - 5");

                Assert(((a + b) ^ c).Has(elt => (elt is Power) && (elt as Power).exp == c), "Has - 6");

                Assert((x * (a + b + c)).Has(elt => (elt is Sum) && (elt as Sum).Has(b)), "Has - 7");

                Assert((x * (a + b + c)).Has(elt => (elt is Sum) && (elt as Sum).elts.Any(obj => obj == b)), "Has - 8");

                Assert((x * (a + b + c)).Has(elt => (elt is Product) && (elt as Product).elts.Any(obj => obj == b)) == false, "Has - 9");

                #endregion

                #region FreeOf

                Assert((a + b).FreeOf(b) == false, "(a + b).FreeOf(b)");
                Assert((a + b).FreeOf(c) == true, "(a + b).FreeOf(c)");
                Assert(((a + b) * c).FreeOf(a + b) == false, "((a + b) * c).FreeOf(a + b)");
                Assert((sin(x) + 2 * x).FreeOf(sin(x)) == false, "(sin(x) + 2 * x).FreeOf(sin(x))");
                Assert(((a + b + c) * d).FreeOf(a + b) == true, "((a + b + c) * d).FreeOf(a + b)");
                Assert(((y + 2 * x - y) / x).FreeOf(x) == true, "((y + 2 * x - y) / x).FreeOf(x)");
                Assert(((x * y) ^ 2).FreeOf(x * y) == true, "((x * y) ^ 2).FreeOf(x * y)");

                #endregion

                #region Denominator
                {
                    ((new Integer(2) / 3) * ((x * (x + 1)) / (x + 2)) * (y ^ z))
                        .Denominator()
                        .AssertEqTo(3 * (x + 2));
                }
                #endregion

                #region LogicalExpand

                new And(new Or(a, b), c)
                    .LogicalExpand()
                    .AssertEqTo(
                        new Or(
                            new And(a, c),
                            new And(b, c)));

                new And(a, new Or(b, c))
                    .LogicalExpand()
                    .AssertEqTo(new Or(new And(a, b), new And(a, c)));

                new And(a, new Or(b, c), d)
                    .LogicalExpand()
                    .AssertEqTo(
                        new Or(
                            new And(a, b, d),
                            new And(a, c, d)));

                new And(new Or(a == b, b == c), x == y)
                    .LogicalExpand()
                    .AssertEqTo(
                        new Or(
                            new And(a == b, x == y),
                            new And(b == c, x == y)));

                new And(
                    new Or(a == b, b == c),
                    new Or(c == d, d == a),
                    x == y)
                    .LogicalExpand()
                    .AssertEqTo(
                        new Or(
                            new And(a == b, c == d, x == y),
                            new And(a == b, d == a, x == y),
                            new And(b == c, c == d, x == y),
                            new And(b == c, d == a, x == y)));

                #endregion

                #region SimplifyEquation

                (2 * x == 0)
                    .SimplifyEquation()
                    .AssertEqTo(x == 0);

                (2 * x != 0)
                    .SimplifyEquation()
                    .AssertEqTo(x != 0);

                ((x ^ 2) == 0)
                    .SimplifyEquation()
                    .AssertEqTo(x == 0);

                #endregion

                #region SimplifyLogical

                new And(a, b, c, a)
                    .SimplifyLogical()
                    .AssertEqTo(new And(a, b, c));

                #endregion SimplifyLogical

                #region DegreeGpe

                {
                    var w = new Symbol("w");

                    Assert(
                        ((3 * w * x ^ 2) * (y ^ 3) * (z ^ 4)).DegreeGpe(new List<MathObject>() { x, z }) == 6,
                        "((3 * w * x ^ 2) * (y ^ 3) * (z ^ 4)).DegreeGpe(new List<MathObject>() { x, z })");

                    Assert(
                        ((a * x ^ 2) + b * x + c).DegreeGpe(new List<MathObject>() { x }) == 2,
                        "((a * x ^ 2) + b * x + c).DegreeGpe(new List<MathObject>() { x })");

                    Assert(
                        (a * (sin(x) ^ 2) + b * sin(x) + c).DegreeGpe(new List<MathObject>() { sin(x) }) == 2,
                        "(a * (sin(x) ^ 2) + b * sin(x) + c).DegreeGpe(new List<MathObject>() { sin(x) })");

                    Assert(
                        (2 * (x ^ 2) * y * (z ^ 3) + w * x * (z ^ 6)).DegreeGpe(new List<MathObject>() { x, z }) == 7,
                        "(2 * (x ^ 2) * y * (z ^ 3) + w * x * (z ^ 6)).DegreeGpe(new List<MathObject>() { x, z })");
                }

                #endregion

                #region CoefficientGpe

                AssertIsTrue((a * (x ^ 2) + b * x + c).CoefficientGpe(x, 2) == a);

                AssertIsTrue((3 * x * (y ^ 2) + 5 * (x ^ 2) * y + 7 * x + 9).CoefficientGpe(x, 1) == 3 * (y ^ 2) + 7);

                AssertIsTrue((3 * x * (y ^ 2) + 5 * (x ^ 2) * y + 7 * x + 9).CoefficientGpe(x, 3) == 0);

                Assert(
                    (3 * sin(x) * (x ^ 2) + 2 * x + 4).CoefficientGpe(x, 2) == null,
                    "(3 * sin(x) * (x ^ 2) + 2 * x + 4).CoefficientGpe(x, 2) == null");

                #endregion

                #region AlgebraicExpand

                AssertIsTrue(
                    ((x + 2) * (x + 3) * (x + 4)).AlgebraicExpand()
                    ==
                    24 + 26 * x + 9 * (x ^ 2) + (x ^ 3));

                AssertIsTrue(
                    ((x + y + z) ^ 3).AlgebraicExpand()
                    ==
                    (x ^ 3) + (y ^ 3) + (z ^ 3) +
                    3 * (x ^ 2) * y +
                    3 * (y ^ 2) * x +
                    3 * (x ^ 2) * z +
                    3 * (y ^ 2) * z +
                    3 * (z ^ 2) * x +
                    3 * (z ^ 2) * y +
                    6 * x * y * z);

                AssertIsTrue(
                    (((x + 1) ^ 2) + ((y + 1) ^ 2)).AlgebraicExpand()
                    ==
                    2 + 2 * x + (x ^ 2) + 2 * y + (y ^ 2));

                AssertIsTrue(
                    ((((x + 2) ^ 2) + 3) ^ 2).AlgebraicExpand()
                    ==
                    49 + 56 * x + 30 * (x ^ 2) + 8 * (x ^ 3) + (x ^ 4));

                AssertIsTrue(
                    sin(x * (y + z)).AlgebraicExpand()
                    ==
                    sin(x * y + x * z));

                AssertIsTrue(
                    (a * (b + c) == x * (y + z)).AlgebraicExpand()
                    ==
                    (a * b + a * c == x * y + x * z));

                #endregion

                #region IsolateVariable

                (x + y + z == 0).IsolateVariable(a).AssertEqTo(x + y + z == 0);

                // (x * a + x * b == 0).IsolateVariable(x).Disp();

                (x * (a + b) - x * a - x * b + x == c)
                    .IsolateVariable(x)
                    .AssertEqTo(x == c);

                new And(x == y, a == b)
                    .IsolateVariable(b)
                    .AssertEqTo(new And(x == y, b == a));

                new Or(new And(y == x, z == x), new And(b == x, c == x))
                    .IsolateVariable(x)
                    .AssertEqTo(new Or(new And(x == y, x == z), new And(x == b, x == c)));

                Assert((0 == x - y).IsolateVariableEq(x).Equals(x == y), "(0 == x - y).IsolateVariable(x).Equals(x == y)");

                Func<MathObject, MathObject> sqrt = obj => obj ^ (new Integer(1) / 2);

                (a * (x ^ 2) + b * x + c == 0)
                    .IsolateVariable(x)
                    .AssertEqTo(

                        new Or(

                            new And(
                                x == (-b + sqrt((b ^ 2) + -4 * a * c)) / (2 * a),
                                a != 0
                            ),

                            new And(
                                x == (-b - sqrt((b ^ 2) + -4 * a * c)) / (2 * a),
                                a != 0
                            ),

                            new And(x == -c / b, a == 0, b != 0),

                            new And(a == 0, b == 0, c == 0)
                        )
                    );

                (a * (x ^ 2) + c == 0)
                    .IsolateVariable(x)
                    .AssertEqTo(

                        new Or(
                            new And(
                                x == sqrt(-4 * a * c) / (2 * a),
                                a != 0
                            ),

                            new And(
                                x == -sqrt(-4 * a * c) / (2 * a),
                                a != 0
                            ),

                            new And(a == 0, c == 0)
                        )
                    );

                // a x^2 + b x + c == 0
                // a x^2 + c == - b x
                // (a x^2 + c) / x == - b

                ((a * (x ^ 2) + c) / x == -b)
                    .IsolateVariable(x)
                    .AssertEqTo(

                    new Or(

                            new And(
                                x == (-b + sqrt((b ^ 2) + -4 * a * c)) / (2 * a),
                                a != 0
                            ),

                            new And(
                                x == (-b - sqrt((b ^ 2) + -4 * a * c)) / (2 * a),
                                a != 0
                            ),

                            new And(x == -c / b, a == 0, b != 0),

                            new And(a == 0, b == 0, c == 0)
                        )
                );

                (sqrt(x + y) == z).IsolateVariable(x).AssertEqTo(x == (z ^ 2) - y);

                (a * b + a == c)
                    .IsolateVariable(a)
                    .AssertEqTo(a == c / (b + 1));

                (a * b + a * c == d)
                    .IsolateVariable(a)
                    .AssertEqTo(a == d / (b + c));

                (1 / sqrt(x) == y)
                    .IsolateVariable(x)
                    .AssertEqTo(x == (y ^ -2));

                (y == sqrt(x) / x)
                    .IsolateVariable(x)
                    .AssertEqTo(x == (y ^ -2));

                (-sqrt(x) + z * x == y)
                    .IsolateVariable(x)
                    .AssertEqTo(-sqrt(x) + z * x == y);

                (sqrt(a + x) - z * x == -y)
                    .IsolateVariable(x)
                    .AssertEqTo(sqrt(a + x) - z * x == -y);

                (sqrt(2 + x) * sqrt(3 + x) == y)
                    .IsolateVariable(x)
                    .AssertEqTo(sqrt(2 + x) * sqrt(3 + x) == y);

                #endregion

                #region EliminateVariable

                new And((x ^ 3) == (y ^ 5), z == x)
                .EliminateVariable(x)
                .AssertEqTo((z ^ 3) == (y ^ 5));

                new And((x ^ 3) == (y ^ 5), z == (x ^ 7))
                .EliminateVariable(x)
                .AssertEqTo(new And((x ^ 3) == (y ^ 5), z == (x ^ 7)));

                #endregion

            }

            #region EliminateVariable

            #region
            {

                var x = new Symbol("x");
                var y = new Symbol("y");
                var z = new Symbol("z");

                var eqs = new And()
                {
                    args =
                    {
                        (x ^ 2) - 4 == 0,
                        y + x == 0,
                        x + z == 10
                    }
                }
                .Simplify();

                var half = new Integer(1) / 2;

                Func<MathObject, MathObject> sqrt = obj => obj ^ half;

                ((x ^ 2) - 4 == 0)
                    .IsolateVariableEq(x)
                    .AssertEqTo(new Or(x == half * sqrt(16), x == -half * sqrt(16)));

                eqs.EliminateVariable(x)
                    .AssertEqTo(
                        new Or(
                            new And(
                                half * sqrt(16) + y == 0,
                                half * sqrt(16) + z == 10
                            ),
                            new And(
                                -half * sqrt(16) + y == 0,
                                -half * sqrt(16) + z == 10
                            )
                        )
                    );

            }
            #endregion

            #region
            {
                var a = new Symbol("a");
                var x = new Symbol("x");
                var y = new Symbol("y");
                var z = new Symbol("z");

                new Or(
                    new And(x == y, x == z, x == a),
                    new And(x == -y, x == z, x == a)
                    )
                    .EliminateVariable(x)
                    .AssertEqTo(
                        new Or(
                            new And(y == z, y == a),
                            new And(-y == z, -y == a)
                        )
                    )
                    .EliminateVariable(y)
                    .AssertEqTo(new Or(z == a, z == a));
            }
            #endregion

            {
                var x = new Symbol("x");
                var y = new Symbol("y");
                var z = new Symbol("z");

                new And(y != z, y == x, y == 10)
                    .EliminateVariable(y)
                    .AssertEqTo(new And(x != z, x == 10));
            }

            #region PSE Example 2.6

            {
                var sAC = new Symbol("sAC");
                var sAB = new Symbol("sAB");

                var vA = new Symbol("vA");
                var vB = new Symbol("vB");
                var vC = new Symbol("vC");

                var a = new Symbol("a");

                var tAC = new Symbol("tAC");
                var tAB = new Symbol("tAB");

                var eqs = new And(tAB == tAC / 2);

                eqs.args.AddRange(Kinematic(sAC, vA, vC, a, tAC));
                eqs.args.AddRange(Kinematic(sAB, vA, vB, a, tAB));

                var vals = new List<Equation>() { vA == 10, vC == 30, tAC == 10 };

                eqs
                    .EliminateVariables(tAB, sAC, vB, sAB)
                    .IsolateVariable(a)
                    .AssertEqTo(a == (vC - vA) / tAC)
                    .SubstituteEqLs(vals)
                    .AssertEqTo(a == 2);

                eqs
                    .EliminateVariables(vB, a, tAB, sAC)
                    .AssertEqTo(sAB == tAC / 4 * (2 * vA + (vC - vA) / 2))
                    .SubstituteEqLs(vals)
                    .AssertEqTo(sAB == 75);
            }

            #endregion

            #region PSE Example 2.7
            {
                // s =
                // u = 63
                // v =  0
                // a =
                // t =  2

                var s = new Symbol("s");
                var u = new Symbol("u");
                var v = new Symbol("v");
                var a = new Symbol("a");
                var t = new Symbol("t");

                var eqs = new And();

                eqs.args.AddRange(Kinematic(s, u, v, a, t));

                var vals = new List<Equation>() { u == 63, v == 0, t == 2.0 };

                eqs
                    .EliminateVariable(s)
                    .AssertEqTo(v == a * t + u)
                    .IsolateVariable(a)
                    .AssertEqTo(a == (v - u) / t)
                    .SubstituteEqLs(vals)
                    .AssertEqTo(a == -31.5);

                eqs
                    .EliminateVariable(a)
                    .SubstituteEqLs(vals)
                    .AssertEqTo(s == 63.0);
            }
            #endregion

            #region PSE Example 2.8
            {
                // car
                //
                // s1 =
                // u1 = 45
                // v1 = 45
                // a1 =  0
                // t1 =

                // officer
                //
                // s2 =
                // u2 =  0
                // v2 =
                // a2 =  3
                // t2

                var s1 = new Symbol("s1");
                var u1 = new Symbol("u1");
                var v1 = new Symbol("v1");
                var a1 = new Symbol("a1");
                var t1 = new Symbol("t1");

                var s2 = new Symbol("s2");
                var u2 = new Symbol("u2");
                var v2 = new Symbol("v2");
                var a2 = new Symbol("a2");
                var t2 = new Symbol("t2");

                var eqs = new And(
                    u1 == v1,
                    s1 == s2,
                    t2 == t1 - 1);

                eqs.args.AddRange(Kinematic(s1, u1, v1, a1, t1));
                eqs.args.AddRange(Kinematic(s2, u2, v2, a2, t2));

                var vals = new List<Equation>()
                {
                    v1 == 45.0,
                    u2 == 0,
                    a2 == 3
                };

                eqs
                    .EliminateVariables(s2, t1, a1, s1, v2, u1)
                    .IsolateVariable(t2)
                    .SubstituteEqLs(vals)
                    .AssertEqTo(new Or(t2 == -0.96871942267131317, t2 == 30.968719422671313));
            }
            #endregion

            #region PSE Example 2.12

            {
                var yA = new Symbol("yA");
                var yB = new Symbol("yB");
                var yC = new Symbol("yC");
                var yD = new Symbol("yD");

                var tA = new Symbol("tA");
                var tB = new Symbol("tB");
                var tC = new Symbol("tC");
                var tD = new Symbol("tD");

                var vA = new Symbol("vA");
                var vB = new Symbol("vB");
                var vC = new Symbol("vC");
                var vD = new Symbol("vD");

                var a = new Symbol("a");

                var eqs = new And();

                eqs.args.AddRange(Kinematic(yA, yB, vA, vB, a, tA, tB));
                eqs.args.AddRange(Kinematic(yB, yC, vB, vC, a, tB, tC));
                eqs.args.AddRange(Kinematic(yC, yD, vC, vD, a, tC, tD));

                var vals = new List<Equation>()
                {
                    yA == 50,
                    yC == 50,
                    vA == 20,
                    vB == 0,
                    a == -9.8,
                    tA == 0,
                    tD == 5
                };

                // velocity and position at t = 5.00 s

                DoubleFloat.tolerance = 0.000000001;

                eqs
                    .EliminateVariables(tB, tC, vC, yB, yD)
                    .SubstituteEqLs(vals)
                    .AssertEqTo(new Or(vD == -29.000000000000004, vD == -29.000000000000007));

                eqs
                    .EliminateVariables(tB, tC, vC, yB, vD)
                    .IsolateVariable(yD)
                    .SubstituteEqLs(vals)
                    .AssertEqTo(new Or(yD == 27.499999999, yD == 27.499999999));

                DoubleFloat.tolerance = null;
            }

            #endregion

            #region PSE Example 4.3

            {
                var xA = new Symbol("xA");
                var xB = new Symbol("xB");
                var xC = new Symbol("xC");

                var yA = new Symbol("yA");
                var yB = new Symbol("yB");
                var yC = new Symbol("yC");

                var vxA = new Symbol("vxA");
                var vxB = new Symbol("vxB");
                var vxC = new Symbol("vxC");

                var vyA = new Symbol("vyA");
                var vyB = new Symbol("vyB");
                var vyC = new Symbol("vyC");

                var tAB = new Symbol("tAB");
                var tAC = new Symbol("tAC");

                var ax = new Symbol("ax");
                var ay = new Symbol("ay");

                var vA = new Symbol("vA");
                var thA = new Symbol("thA");

                var eqs = new And(

                    vxA == vA * cos(thA),
                    vyA == vA * sin(thA),

                    tAC == 2 * tAB,

                    vxB == vxA + ax * tAB,
                    vyB == vyA + ay * tAB,

                    xB == xA + vxA * tAB + ax * (tAB ^ 2) / 2,
                    yB == yA + vyA * tAB + ay * (tAB ^ 2) / 2,

                    vxC == vxA + ax * tAB,
                    vyC == vyA + ay * tAB,

                    xC == xA + vxA * tAC + ax * (tAC ^ 2) / 2,
                    yC == yA + vyA * tAC + ay * (tAC ^ 2) / 2

                    );

                var zeros = new List<Equation>() { xA == 0, yA == 0, ax == 0, vyB == 0 };

                var vals = new List<Equation>() { thA == (20).ToRadians(), vA == 11.0, ay == -9.8, Trig.Pi == Math.PI };

                eqs
                    .EliminateVariables(xB, yC, vxB, vxC, vyC, yB, tAC, vxA, vyA, tAB)
                    .SubstituteEqLs(zeros)
                    .AssertEqTo(xC == -2 * cos(thA) * sin(thA) * (vA ^ 2) / ay)
                    .SubstituteEqLs(vals)
                    .AssertEqTo(xC == 7.9364592624562507);

                eqs
                    .EliminateVariables(xB, yC, vxB, vxC, vyC, xC, vxA, tAC, vyA, tAB)
                    .SubstituteEqLs(zeros)
                    .AssertEqTo(yB == -(sin(thA) ^ 2) * (vA ^ 2) / (2 * ay))
                    .SubstituteEqLs(vals)
                    .AssertEqTo(yB == 0.72215873425009314);
            }

            #endregion

            #region PSE 5E Example 4.5

            {
                Func<MathObject, MathObject> sqrt = obj => obj ^ (new Integer(1) / 2);

                var xA = new Symbol("xA");
                var xB = new Symbol("xB");
                var xC = new Symbol("xC");

                var yA = new Symbol("yA");
                var yB = new Symbol("yB");
                var yC = new Symbol("yC");

                var vxA = new Symbol("vxA");
                var vxB = new Symbol("vxB");
                var vxC = new Symbol("vxC");

                var vyA = new Symbol("vyA");
                var vyB = new Symbol("vyB");
                var vyC = new Symbol("vyC");

                var tAB = new Symbol("tAB");
                var tAC = new Symbol("tAC");

                var ax = new Symbol("ax");
                var ay = new Symbol("ay");

                var vA = new Symbol("vA");
                var thA = new Symbol("thA");

                var vC = new Symbol("vC");

                var eqs = new And(

                    vxA == vA * cos(thA),
                    vyA == vA * sin(thA),

                    // tAC == 2 * tAB,

                    // vxB == vxA + ax * tAB,
                    // vyB == vyA + ay * tAB,

                    // xB == xA + vxA * tAB + ax * (tAB ^ 2) / 2,
                    // yB == yA + vyA * tAB + ay * (tAB ^ 2) / 2,

                    vxC == vxA + ax * tAC,
                    vyC == vyA + ay * tAC,

                    // xC == xA + vxA * tAC + ax * (tAC ^ 2) / 2,
                    yC == yA + vyA * tAC + ay * (tAC ^ 2) / 2,

                    vC == sqrt((vxC ^ 2) + (vyC ^ 2)),

                    ay != 0
                );

                var zeros = new List<Equation>() { ax == 0, yC == 0 };
                var vals = new List<Equation>() { yA == 45, vA == 20, thA == (30).ToRadians(), ay == -9.8, Trig.Pi == Math.PI };

                DoubleFloat.tolerance = 0.00001;

                eqs
                    .EliminateVariables(vC, vxA, vxC, vyC, vyA)
                    .IsolateVariable(tAC)
                    .LogicalExpand().SimplifyEquation().SimplifyLogical()
                    .CheckVariable(ay)
                    .AssertEqTo(
                        new Or(
                            new And(
                                tAC == -(sin(thA) * vA + sqrt((sin(thA) ^ 2) * (vA ^ 2) + 2 * ay * (yC - yA))) / ay,
                                ay != 0),
                            new And(
                                tAC == -(sin(thA) * vA - sqrt((sin(thA) ^ 2) * (vA ^ 2) + 2 * ay * (yC - yA))) / ay,
                                ay != 0)))
                    .SubstituteEqLs(zeros)
                    .SubstituteEqLs(vals)
                    .AssertEqTo(new Or(tAC == 4.2180489012229376, tAC == -2.1772325746923267));

                eqs
                    .SubstituteEqLs(zeros)
                    .EliminateVariables(vxC, vxA, vyA, vyC, tAC)
                    .SimplifyEquation().SimplifyLogical()
                    .CheckVariable(ay)
                    .AssertEqTo(
                        new Or(
                            new And(
                                ay != 0,
                                vC == sqrt((cos(thA) ^ 2) * (vA ^ 2) + ((sin(thA) * vA - (sin(thA) * vA + sqrt((sin(thA) ^ 2) * (vA ^ 2) + -2 * ay * yA))) ^ 2))),
                            new And(
                                ay != 0,
                                vC == sqrt((cos(thA) ^ 2) * (vA ^ 2) + ((sin(thA) * vA - (sin(thA) * vA - sqrt((sin(thA) ^ 2) * (vA ^ 2) + -2 * ay * yA))) ^ 2)))))
                    .SubstituteEqLs(vals)
                    .AssertEqTo(new Or(vC == 35.805027579936315, vC == 35.805027579936322));

                DoubleFloat.tolerance = null;
            }

            #endregion

            #region PSE 5E Example 4.6

            {
                Func<MathObject, MathObject> sqrt = obj => obj ^ (new Integer(1) / 2);

                var xA = new Symbol("xA");
                var xB = new Symbol("xB");

                var yA = new Symbol("yA");
                var yB = new Symbol("yB");

                var vxA = new Symbol("vxA");
                var vxB = new Symbol("vxB");

                var vyA = new Symbol("vyA");
                var vyB = new Symbol("vyB");

                var tAB = new Symbol("tAB");

                var ax = new Symbol("ax");
                var ay = new Symbol("ay");

                var eqs = new And(

                    vxB == vxA + ax * tAB,
                    vyB == vyA + ay * tAB,

                    xB == xA + vxA * tAB + ax * (tAB ^ 2) / 2,
                    yB == yA + vyA * tAB + ay * (tAB ^ 2) / 2,

                    vxA != 0,

                    ay != 0
                );

                var vals = new List<Equation>() { xA == 0, yA == 100, vxA == 40, vyA == 0, yB == 0, ax == 0, ay == -9.8, Trig.Pi == Math.PI };

                var zeros = vals.Where(eq => eq.b == 0).ToList();

                DoubleFloat.tolerance = 0.00001;

                eqs
                    .EliminateVariables(vxB, vyB, tAB)
                    .IsolateVariable(xB)
                    .LogicalExpand().SimplifyEquation()
                    .CheckVariable(ay)
                    .CheckVariable(vxA).SimplifyLogical()
                    .SubstituteEq(ax == 0)
                    .AssertEqTo(
                        new Or(
                            new And(
                                vxA != 0,
                                xB == -1 * (ay ^ -1) * (vxA ^ 2) * (-1 * (-1 * (vxA ^ -1) * vyA + ay * (vxA ^ -2) * xA) + sqrt(((-1 * (vxA ^ -1) * vyA + ay * (vxA ^ -2) * xA) ^ 2) + 2 * ay * (vxA ^ -2) * ((vxA ^ -1) * vyA * xA - ay / 2 * (vxA ^ -2) * (xA ^ 2) + -1 * yA + yB))),
                                ay * (vxA ^ -2) != 0,
                                ay != 0),
                            new And(
                                vxA != 0,
                                xB == -1 * (ay ^ -1) * (vxA ^ 2) * (-1 * (-1 * (vxA ^ -1) * vyA + ay * (vxA ^ -2) * xA) + -1 * sqrt(((-1 * (vxA ^ -1) * vyA + ay * (vxA ^ -2) * xA) ^ 2) + 2 * ay * (vxA ^ -2) * ((vxA ^ -1) * vyA * xA - ay / 2 * (vxA ^ -2) * (xA ^ 2) + -1 * yA + yB))),
                                ay * (vxA ^ -2) != 0,
                                ay != 0)))
                    .SubstituteEqLs(zeros)
                    .AssertEqTo(
                        new Or(
                            new And(
                                vxA != 0,
                                xB == -1 / ay * (vxA ^ 2) * sqrt(-2 * ay * (vxA ^ -2) * yA),
                                ay / (vxA ^ 2) != 0,
                                ay != 0),
                            new And(
                                vxA != 0,
                                xB == 1 / ay * (vxA ^ 2) * sqrt(-2 * ay * (vxA ^ -2) * yA),
                                ay / (vxA ^ 2) != 0,
                                ay != 0)))
                    .SubstituteEqLs(vals)
                    .AssertEqTo(new Or(xB == 180.70158058105022, xB == -180.70158058105022));

                eqs
                    .EliminateVariables(vxB, xB, tAB)
                    .IsolateVariable(vyB)
                    .LogicalExpand().SimplifyEquation()
                    .CheckVariable(ay)
                    .AssertEqTo(
                        new Or(
                            new And(
                                vyB == -1 * ay * sqrt(2 * (ay ^ -1) * ((ay ^ -1) / 2 * (vyA ^ 2) + -1 * yA + yB)),
                    // (ay ^ -1) != 0,
                                vxA != 0,
                                ay != 0),
                            new And(
                                vyB == ay * sqrt(2 * (ay ^ -1) * ((ay ^ -1) / 2 * (vyA ^ 2) + -1 * yA + yB)),
                    // (ay ^ -1) != 0,
                                vxA != 0,
                                ay != 0)))
                    .SubstituteEqLs(zeros)
                    .AssertEqTo(
                        new Or(
                          new And(
                              vyB == -ay * sqrt(-2 / ay * yA),
                    // 1 / ay != 0,
                              vxA != 0,
                              ay != 0),
                          new And(
                              vyB == ay * sqrt(-2 / ay * yA),
                    // 1 / ay != 0,
                              vxA != 0,
                              ay != 0)))
                    .SubstituteEqLs(vals)
                    .AssertEqTo(new Or(vyB == 44.271887242357309, vyB == -44.271887242357309));

                DoubleFloat.tolerance = null;
            }

            #endregion

            #region PSE 5E Example 4.7

            {
                Func<MathObject, MathObject> sqrt = obj => obj ^ (new Integer(1) / 2);

                var xA = new Symbol("xA");
                var yA = new Symbol("yA");

                var xB = new Symbol("xB");
                var yB = new Symbol("yB");

                var vxA = new Symbol("vxA");
                var vyA = new Symbol("vyA");

                var vxB = new Symbol("vxB");
                var vyB = new Symbol("vyB");

                var tAB = new Symbol("tAB");

                var ax = new Symbol("ax");
                var ay = new Symbol("ay");

                var th = new Symbol("th");
                var d = new Symbol("d");

                var eqs = new And(

                    cos(th) == (xB - xA) / d,
                    sin(th) == (yA - yB) / d,

                    vxB == vxA + ax * tAB,
                    vyB == vyA + ay * tAB,

                    xB == xA + vxA * tAB + ax * (tAB ^ 2) / 2,
                    yB == yA + vyA * tAB + ay * (tAB ^ 2) / 2,

                    yB != 0,

                    ay != 0
                );

                var vals = new List<Equation>() { xA == 0, yA == 0, vxA == 25, vyA == 0, ax == 0, ay == -9.8, th == (35).ToRadians(), Trig.Pi == Math.PI };

                var zeros = vals.Where(eq => eq.b == 0).ToList();

                DoubleFloat.tolerance = 0.00001;

                eqs
                    .SubstituteEqLs(zeros)
                    .EliminateVariables(vxB, vyB, d, yB, tAB)
                    .IsolateVariable(xB)
                    .LogicalExpand()
                    .CheckVariable(ay)
                    .SimplifyEquation()
                    .AssertEqTo(
                        new Or(
                            new And(
                                xB == -(sin(th) / cos(th) + sqrt((cos(th) ^ -2) * (sin(th) ^ 2))) * (vxA ^ 2) / ay,
                                ay / (vxA ^ 2) != 0,
                                sin(th) / cos(th) * xB != 0,
                                ay != 0),
                            new And(
                                xB == -(sin(th) / cos(th) - sqrt((cos(th) ^ -2) * (sin(th) ^ 2))) * (vxA ^ 2) / ay,
                                ay / (vxA ^ 2) != 0,
                                sin(th) / cos(th) * xB != 0,
                                ay != 0)))
                    .SubstituteEqLs(vals)
                    .SimplifyEquation()
                    .AssertEqTo(
                        new Or(
                            new And(
                                xB == 89.312185996136435,
                                xB != 0),
                            new And(
                                xB == 7.0805039835788038E-15,
                                xB != 0)));

                eqs
                    .SubstituteEqLs(zeros)
                    .EliminateVariables(vxB, vyB, d, xB, tAB)
                    .IsolateVariable(yB)
                    .LogicalExpand()
                    .CheckVariable(yB)
                    .AssertEqTo(
                        new And(
                            yB == 2 * (sin(th) ^ 2) * (vxA ^ 2) / ay / (cos(th) ^ 2),
                            -ay * (cos(th) ^ 2) / (sin(th) ^ 2) / (vxA ^ 2) / 2 != 0,
                            yB != 0,
                            ay != 0))
                    .SubstituteEqLs(vals)
                    .AssertEqTo(
                        new And(
                            yB == -62.537065888482395,
                            yB != 0));

                eqs
                    .SubstituteEqLs(zeros)
                    .EliminateVariables(vxB, vyB, d, xB, yB)
                    .IsolateVariable(tAB)
                    .LogicalExpand().CheckVariable(ay).SimplifyEquation().SimplifyLogical()
                    .AssertEqTo(
                        new Or(
                            new And(
                                tAB == -(sin(th) * vxA / cos(th) + sqrt((sin(th) ^ 2) * (vxA ^ 2) / (cos(th) ^ 2))) / ay,
                                ay != 0,
                                sin(th) * tAB * vxA / cos(th) != 0),
                            new And(
                                tAB == -(sin(th) * vxA / cos(th) - sqrt((sin(th) ^ 2) * (vxA ^ 2) / (cos(th) ^ 2))) / ay,
                                ay != 0,
                                sin(th) * tAB * vxA / cos(th) != 0)))
                    .SubstituteEqLs(vals)
                    .CheckVariable(tAB).SimplifyEquation()
                    .AssertEqTo(
                        new And(
                            tAB == 3.5724874398454571,
                            tAB != 0));

                eqs
                    .SubstituteEqLs(zeros)
                    .EliminateVariables(vxB, d, tAB, xB, yB)
                    .IsolateVariable(vyB)
                    .LogicalExpand()
                    .CheckVariable(ay)
                    .SimplifyEquation()
                    .CheckVariable(ay)
                    .AssertEqTo(
                        new Or(
                            new And(
                                vyB == -ay * (sin(th) * vxA / (ay * cos(th)) + sqrt((sin(th) ^ 2) * (vxA ^ 2) / ((ay ^ 2) * (cos(th) ^ 2)))),
                                sin(th) * vxA * vyB / (ay * cos(th)) != 0,
                                ay != 0),
                            new And(
                                vyB == -ay * (sin(th) * vxA / (ay * cos(th)) - sqrt((sin(th) ^ 2) * (vxA ^ 2) / ((ay ^ 2) * (cos(th) ^ 2)))),
                                sin(th) * vxA * vyB / (ay * cos(th)) != 0,
                                ay != 0)))
                    .SubstituteEqLs(vals)
                    .CheckVariable(vyB)
                    .SimplifyEquation()
                    .CheckVariable(vyB)
                    .AssertEqTo(
                        new And(
                            vyB == -35.010376910485483,
                            vyB != 0));

                DoubleFloat.tolerance = null;
            }

            #endregion

            #region PSE 5E P4.9

            {
                // In a local bar, a customer slides an empty beer mug
                // down the counter for a refill. The bartender is momentarily
                // distracted and does not see the mug, which slides
                // off the counter and strikes the floor 1.40 m from the
                // base of the counter. If the height of the counter is
                // 0.860 m, (a) with what velocity did the mug leave the
                // counter and (b) what was the direction of the mug’s
                // velocity just before it hit the floor?

                Func<MathObject, MathObject> sqrt = obj => obj ^ (new Integer(1) / 2);

                var xA = new Symbol("xA");
                var yA = new Symbol("yA");

                var xB = new Symbol("xB");
                var yB = new Symbol("yB");

                var vxA = new Symbol("vxA");
                var vyA = new Symbol("vyA");

                var vxB = new Symbol("vxB");
                var vyB = new Symbol("vyB");

                var tAB = new Symbol("tAB");

                var ax = new Symbol("ax");
                var ay = new Symbol("ay");

                var thB = new Symbol("thB");
                var vB = new Symbol("vB");

                var eqs = new And(

                    vxB == vxA + ax * tAB,
                    vyB == vyA + ay * tAB,

                    tan(thB) == vyB / vxB,

                    xB == xA + vxA * tAB + ax * (tAB ^ 2) / 2,
                    yB == yA + vyA * tAB + ay * (tAB ^ 2) / 2,

                    xB != 0
                );

                var vals = new List<Equation>() { xA == 0, yA == 0.86, /* vxA */ vyA == 0, xB == 1.4, yB == 0, /* vxB vyB vB thB */ /* tAB */ ax == 0, ay == -9.8 };

                var zeros = vals.Where(eq => eq.b == 0).ToList();

                DoubleFloat.tolerance = 0.00001;

                eqs
                    .SubstituteEqLs(zeros)
                    .EliminateVariables(thB, vxB, vyB, tAB)
                    .IsolateVariable(vxA)
                    .LogicalExpand()
                    .AssertEqTo(
                        new Or(
                            new And(
                                vxA == ay * (xB ^ 2) / yA / 4 * sqrt(-8 / ay * (xB ^ -2) * yA),
                                2 / ay * (xB ^ -2) * yA != 0,
                                xB != 0),
                            new And(
                                vxA == -ay * (xB ^ 2) / yA / 4 * sqrt(-8 / ay * (xB ^ -2) * yA),
                                2 / ay * (xB ^ -2) * yA != 0,
                                xB != 0)))
                    .SubstituteEqLs(vals)
                    .AssertEqTo(new Or(vxA == -3.3417722634053204, vxA == 3.3417722634053204));

                eqs
                    .SubstituteEqLs(zeros)
                    .EliminateVariables(vxB, vyB, tAB, vxA)
                    .LogicalExpand()
                    .CheckVariable(xB)
                    .SimplifyLogical()
                    .IsolateVariable(thB)
                    .AssertEqTo(
                        new And(
                            -tan(thB) / ay != 0,
                            thB == new Atan(-2 * yA / xB),
                            xB != 0))
                    .SubstituteEqLs(vals)
                    .AssertEqTo(
                        new And(
                            0.1020408163265306 * tan(thB) != 0,
                            thB == -0.88760488150470185));

                DoubleFloat.tolerance = null;
            }

            #endregion

            #region SumDifferenceFormulaFunc

            // sin(u) cos(v) - cos(u) sin(v) -> sin(u - v)

            Func<MathObject, MathObject> SumDifferenceFormulaFunc = elt =>
            {
                if (elt is Sum)
                {
                    var items = new List<MathObject>();

                    foreach (var item in (elt as Sum).elts)
                    {
                        if (
                            item is Product &&
                            (item as Product).elts[0] == -1 &&
                            (item as Product).elts[1] is Cos &&
                            (item as Product).elts[2] is Sin
                            )
                        {
                            var u_ = ((item as Product).elts[1] as Cos).args[0];
                            var v_ = ((item as Product).elts[2] as Sin).args[0];

                            Func<MathObject, bool> match = obj =>
                                obj is Product &&
                                (obj as Product).elts[0] is Cos &&
                                (obj as Product).elts[1] is Sin &&

                                ((obj as Product).elts[1] as Sin).args[0] == u_ &&
                                ((obj as Product).elts[0] as Cos).args[0] == v_;

                            if (items.Any(obj => match(obj)))
                            {
                                items = items.Where(obj => match(obj) == false).ToList();

                                items.Add(sin(u_ - v_));
                            }
                            else items.Add(item);
                        }
                        else items.Add(item);
                    }

                    return new Sum() { elts = items }.Simplify();
                }

                return elt;
            };

            #endregion

            {
                var u = new Symbol("u");
                var v = new Symbol("v");

                (sin(u) * cos(v) - cos(u) * sin(v))
                    .DeepSelect(SumDifferenceFormulaFunc)
                    .AssertEqTo(sin(u - v));
            }

            #region DoubleAngleFormulaFunc

            // sin(u) cos(u) -> sin(2 u) / 2

            Func<MathObject, MathObject> DoubleAngleFormulaFunc =
                    elt =>
                    {
                        if (elt is Product)
                        {
                            var items = new List<MathObject>();

                            foreach (var item in (elt as Product).elts)
                            {
                                if (item is Sin)
                                {
                                    var sym = (item as Sin).args.First();

                                    if (items.Any(obj => (obj is Cos) && (obj as Cos).args.First() == sym))
                                    {
                                        items = items.Where(obj => ((obj is Cos) && (obj as Cos).args.First() == sym) == false).ToList();

                                        items.Add(sin(2 * sym) / 2);
                                    }
                                    else items.Add(item);
                                }

                                else if (item is Cos)
                                {
                                    var sym = (item as Cos).args.First();

                                    if (items.Any(obj => (obj is Sin) && (obj as Sin).args.First() == sym))
                                    {
                                        items = items.Where(obj => ((obj is Sin) && (obj as Sin).args.First() == sym) == false).ToList();

                                        items.Add(sin(2 * sym) / 2);
                                    }
                                    else items.Add(item);
                                }

                                else items.Add(item);

                            }
                            return new Product() { elts = items }.Simplify();
                        }
                        return elt;
                    };

            #endregion

            #region PSE 5E P4.11

            {
                // One strategy in a snowball fight is to throw a first snowball
                // at a high angle over level ground. While your opponent is watching
                // the first one, you throw a second one at a low angle and timed
                // to arrive at your opponent before or at the same time as the first one.

                // Assume both snowballs are thrown with a speed of 25.0 m/s.

                // The first one is thrown at an angle of 70.0° with respect to the horizontal.

                // (a) At what angle should the second (lowangle)
                // snowball be thrown if it is to land at the same
                // point as the first?

                // (b) How many seconds later should the second snowball
                // be thrown if it is to land at the same time as the first?

                Func<MathObject, MathObject> sqrt = obj => obj ^ (new Integer(1) / 2);

                var xA = new Symbol("xA");
                var yA = new Symbol("yA");

                var vxA = new Symbol("vxA");
                var vyA = new Symbol("vyA");

                var vA = new Symbol("vA");

                var thA = new Symbol("thA");

                var xB = new Symbol("xB");
                var yB = new Symbol("yB");

                var vxB = new Symbol("vxB");
                var vyB = new Symbol("vyB");

                var tAB = new Symbol("tAB");
                var tAC = new Symbol("tAC");

                var ax = new Symbol("ax");
                var ay = new Symbol("ay");

                var Pi = new Symbol("Pi");

                var eqs = new And(

                    vxA == vA * cos(thA),
                    vyA == vA * sin(thA),

                    vxB == vxA + ax * tAB,
                    vyB == vyA + ay * tAB,

                    xB == xA + vxA * tAB + ax * (tAB ^ 2) / 2,
                    yB == yA + vyA * tAB + ay * (tAB ^ 2) / 2
                );

                DoubleFloat.tolerance = 0.00001;

                {
                    var vals = new List<Equation>() { xA == 0, yA == 0, /* vxA vyA */ vA == 25.0, /* thA == 70.0, */ /* xB == 20.497, */ /* yB */ /* vxB */ vyB == 0, /* tAB */ ax == 0, ay == -9.8, Pi == Math.PI };

                    var zeros = vals.Where(eq => eq.b == 0).ToList();

                    {
                        // thA = ... || thA = ...

                        var expr = eqs
                            .SubstituteEqLs(zeros)
                            .EliminateVariables(yB, vxA, vyA, vxB, tAB)
                            .DeepSelect(DoubleAngleFormulaFunc)
                            .IsolateVariable(thA);

                        // th_delta = ...

                        var th1 = ((expr as Or).args[0] as Equation).b;
                        var th2 = ((expr as Or).args[1] as Equation).b;

                        var th_delta = new Symbol("th_delta");

                        eqs
                            .Add(th_delta == (th1 - th2).AlgebraicExpand())
                            .SubstituteEqLs(zeros)

                            .EliminateVariables(yB, vxA, vyA, vxB, tAB)

                            .DeepSelect(DoubleAngleFormulaFunc)
                            .EliminateVariable(xB)

                            .AssertEqTo(th_delta == asin(sin(2 * thA)) - Pi / 2)

                            .SubstituteEq(thA == (70).ToRadians())
                            .SubstituteEq(Pi == Math.PI)

                            .AssertEqTo(th_delta == -0.87266462599716454)
                            ;
                    }

                    {
                        // tAB = ...

                        var tAB_eq = eqs
                            .SubstituteEqLs(zeros)
                            .EliminateVariables(yB, vxA, vyA, vxB, xB)
                            .IsolateVariable(tAB);

                        new And(
                            new Or(thA == (20).ToRadians(), thA == (70).ToRadians()),
                            tAB_eq,
                            tAC == tAB * 2)
                            .LogicalExpand()
                            .EliminateVariables(thA, tAB)

                            .AssertEqTo(new Or(
                                tAC == -2 * sin(Pi / 9) * vA / ay,
                                tAC == -2 * sin(7 * Pi / 18) * vA / ay))

                            .SubstituteEqLs(vals)
                            .AssertEqTo(
                                new Or(
                                    tAC == 1.7450007312534115,
                                    tAC == 4.794350106050552));
                    }
                }

                DoubleFloat.tolerance = null;
            }

            #endregion

            #region PSE 5E P4.13

            {
                // An artillery shell is fired with an initial velocity of
                // 300 m/s at 55.0° above the horizontal. It explodes on a
                // mountainside 42.0 s after firing. What are the x and y
                // coordinates of the shell where it explodes, relative to its
                // firing point?

                Func<MathObject, MathObject> sqrt = obj => obj ^ (new Integer(1) / 2);

                var xA = new Symbol("xA");
                var yA = new Symbol("yA");

                var vxA = new Symbol("vxA");
                var vyA = new Symbol("vyA");

                var vA = new Symbol("vA");
                var thA = new Symbol("thA");

                var xB = new Symbol("xB");
                var yB = new Symbol("yB");

                var vxB = new Symbol("vxB");
                var vyB = new Symbol("vyB");

                var tAB = new Symbol("tAB");

                var ax = new Symbol("ax");
                var ay = new Symbol("ay");

                var Pi = new Symbol("Pi");

                var eqs = new And(
                    vxA == vA * cos(thA),
                    vyA == vA * sin(thA),

                    vxB == vxA + ax * tAB,
                    vyB == vyA + ay * tAB,

                    xB == xA + vxA * tAB + ax * (tAB ^ 2) / 2,
                    yB == yA + vyA * tAB + ay * (tAB ^ 2) / 2
                );

                DoubleFloat.tolerance = 0.00001;

                {
                    var vals = new List<Equation>() { xA == 0, yA == 0, /* vxA vyA */ vA == 300.0, thA == (55).ToRadians(), /* xB yB vxB vyB */ tAB == 42, ax == 0, ay == -9.8, Pi == Math.PI };

                    var zeros = vals.Where(eq => eq.b == 0).ToList();

                    {
                        eqs
                            .SubstituteEqLs(zeros)
                            .EliminateVariable(vxA)
                            .EliminateVariable(vyA)

                            .AssertEqTo(
                                new And(
                                    vxB == cos(thA) * vA,
                                    vyB == ay * tAB + sin(thA) * vA,
                                    xB == cos(thA) * tAB * vA,
                                    yB == ay * (tAB ^ 2) / 2 + sin(thA) * tAB * vA))

                            .SubstituteEqLs(vals)

                            .AssertEqTo(
                                new And(
                                    vxB == 172.07293090531385,
                                    vyB == -165.85438671330249,
                                    xB == 7227.0630980231817,
                                    yB == 1677.7157580412968))

                            ;
                    }
                }

                DoubleFloat.tolerance = null;
            }

            #endregion

            #region PSE 5E P4.15

            {
                // A projectile is fired in such a way that its horizontal
                // range is equal to three times its maximum height.
                //
                // What is the angle of projection?
                // Give your answer to three significant figures.

                Func<MathObject, MathObject> sqrt = obj => obj ^ (new Integer(1) / 2);

                var xA = new Symbol("xA");
                var yA = new Symbol("yA");

                var vxA = new Symbol("vxA");
                var vyA = new Symbol("vyA");

                var vA = new Symbol("vA");
                var thA = new Symbol("thA");

                var xB = new Symbol("xB");
                var yB = new Symbol("yB");

                var vxB = new Symbol("vxB");
                var vyB = new Symbol("vyB");

                var xC = new Symbol("xC");
                var yC = new Symbol("yC");

                var vxC = new Symbol("vxC");
                var vyC = new Symbol("vyC");

                var tAB = new Symbol("tAB");
                var tBC = new Symbol("tBC");

                var ax = new Symbol("ax");
                var ay = new Symbol("ay");

                var Pi = new Symbol("Pi");

                var eqs = new And(

                    xC - xA == 3 * yB,

                    tAB == tBC,

                    vxA == vA * cos(thA),
                    vyA == vA * sin(thA),

                    vxB == vxA + ax * tAB,
                    vyB == vyA + ay * tAB,

                    xB == xA + vxA * tAB + ax * (tAB ^ 2) / 2,
                    yB == yA + vyA * tAB + ay * (tAB ^ 2) / 2,

                    vxC == vxB + ax * tBC,
                    vyC == vyB + ay * tBC,

                    xC == xB + vxB * tBC + ax * (tBC ^ 2) / 2,
                    yC == yB + vyB * tBC + ay * (tBC ^ 2) / 2

                );

                DoubleFloat.tolerance = 0.00001;

                {
                    var vals = new List<Equation>()
                    {
                        xA == 0, yA == 0, /* vxA vyA vA thA */ /* xB yB vxB */ vyB == 0, /* tAB tBC */
                        /* xC */ yC == 0,

                        ax == 0, ay == -9.8, Pi == Math.PI
                    };

                    var zeros = vals.Where(eq => eq.b == 0).ToList();

                    eqs
                        .SubstituteEqLs(zeros)
                        .EliminateVariables(xC, tAB, vxA, vyA, vxB, xB, yB, vxC, vyC, tBC)
                        .IsolateVariable(thA)
                        .AssertEqTo(thA == new Atan(new Integer(4) / 3));
                }

                DoubleFloat.tolerance = null;
            }

            #endregion

            #region PSE 5E P4.17

            {
                // A cannon with a muzzle speed of 1000 m/s is used to
                // start an avalanche on a mountain slope. The target is
                // 2000 m from the cannon horizontally and 800 m above
                // the cannon.
                //
                // At what angle, above the horizontal, should the cannon be fired?

                Func<MathObject, MathObject> sqrt = obj => obj ^ (new Integer(1) / 2);

                var xA = new Symbol("xA");
                var yA = new Symbol("yA");

                var vxA = new Symbol("vxA");
                var vyA = new Symbol("vyA");

                var vA = new Symbol("vA");
                var thA = new Symbol("thA");

                var xB = new Symbol("xB");
                var yB = new Symbol("yB");

                var vxB = new Symbol("vxB");
                var vyB = new Symbol("vyB");

                var xC = new Symbol("xC");
                var yC = new Symbol("yC");

                var vxC = new Symbol("vxC");
                var vyC = new Symbol("vyC");

                var tAB = new Symbol("tAB");
                var tBC = new Symbol("tBC");

                var ax = new Symbol("ax");
                var ay = new Symbol("ay");

                var Pi = new Symbol("Pi");

                var phi = new Symbol("phi");

                var eqs = new And(

                    vxA == vA * cos(thA),
                    vyA == vA * sin(thA),

                    vxB == vxA + ax * tAB,
                    vyB == vyA + ay * tAB,

                    xB == xA + vxA * tAB + ax * (tAB ^ 2) / 2,
                    yB == yA + vyA * tAB + ay * (tAB ^ 2) / 2
                );

                DoubleFloat.tolerance = 0.00001;

                {
                    var vals = new List<Equation>()
                    {
                        xA ==    0, yA ==   0, /* vxA vyA */ vA == 1000, /* thA */
                        xB == 2000, yB == 800.0, /* vxB vyB */
                        /* tAB */ ax == 0, ay == -9.8, Pi == Math.PI
                    };

                    var zeros = vals.Where(eq => eq.b == 0).ToList();

                    {
                        eqs
                            .SubstituteEqLs(zeros)
                            .EliminateVariables(vxA, vyA, vxB, vyB, tAB)

                            .MultiplyBothSidesBy(cos(thA) ^ 2).AlgebraicExpand()
                            .Substitute(cos(thA) ^ 2, (1 + cos(2 * thA)) / 2)
                            .DeepSelect(DoubleAngleFormulaFunc).AlgebraicExpand()
                            .AddToBothSides(-sin(2 * thA) * xB / 2)
                            .AddToBothSides(-yB / 2)
                            .MultiplyBothSidesBy(2 / xB).AlgebraicExpand()

                            // yB / xB = tan(phi)
                            // yB / xB = sin(phi) / cos(phi)

                            // phi = atan(yB / xB)

                            .Substitute(cos(2 * thA) * yB / xB, cos(2 * thA) * sin(phi) / cos(phi))
                            .MultiplyBothSidesBy(cos(phi)).AlgebraicExpand()
                            .DeepSelect(SumDifferenceFormulaFunc)
                            .IsolateVariable(thA)

                            .Substitute(phi, new Atan(yB / xB).Simplify())

                            .AssertEqTo(
                                new Or(
                                    thA == -(asin(ay * cos(atan(yB / xB)) * (vA ^ -2) * xB + -1 * cos(atan(yB / xB)) * yB / xB) - atan(yB / xB)) / 2,
                                    thA == -(-asin(ay * cos(atan(yB / xB)) * (vA ^ -2) * xB - cos(atan(yB / xB)) * yB / xB) - atan(yB / xB) + Pi) / 2))

                            .SubstituteEqLs(vals)

                            .AssertEqTo(
                                new Or(
                                    thA == 0.39034573609628065,
                                    thA == -1.5806356857788124))
                            ;
                    }
                }

                DoubleFloat.tolerance = null;
            }

            #endregion

            #endregion

            #region PSE 5E Example 4.3
            {
                var thA = new Symbol("thA"); // angle at point A
                var vA = new Symbol("vA"); // velocity at point A

                var g = new Symbol("g"); // magnitude of gravity

                var _g = new Point(0, -g); // gravity vector

                var objA =
                    new Obj()
                    {
                        position = new Point(0, 0),
                        velocity = Point.FromAngle(thA, vA),
                        acceleration = _g,
                        time = new Integer(0)
                    };

                var objB =
                    new Obj()
                    {
                        velocity = new Point(objA.velocity.x, 0),
                        acceleration = _g
                    };

                var timeB = Calc.Time(objA, objB);
                var timeC = timeB * 2;

                objB = objA.AtTime(timeB);
                var objC = objA.AtTime(timeC);

                //Console.WriteLine("How far does he dump in the horizontal direction?");

                AssertIsTrue(objC.position.x == 2 * Trig.Cos(thA) * Trig.Sin(thA) * (vA ^ 2) / g);

                //Console.WriteLine("What is the maximum height reached?");

                AssertIsTrue(objB.position.y == (Trig.Sin(thA) ^ 2) * (vA ^ 2) / 2 / g);

                // Console.WriteLine("Distance jumped: ");

                var deg = 3.14159 / 180.0;

                AssertIsTrue(
                    objC.position.x
                    // .Substitute(thA, Trig.ToRadians(20))
                    .Substitute(thA, 20 * deg)
                    .Substitute(g, 9.8)
                    .Substitute(Trig.Pi, 3.14159)
                    .Substitute(vA, 11)
                    ==
                    7.9364536850196412);

                //Console.WriteLine("Maximum height reached: ");

                AssertIsTrue(
                    objB.position.y
                    .Substitute(g, 9.8)
                    .Substitute(thA, Trig.ToRadians(20))
                    .Substitute(Trig.Pi, 3.14159)
                    .Substitute(vA, 11)
                    ==
                    0.72215756424454336);
            }
            #endregion

            #region PSE 5E EXAMPLE 4.5
            {
                // A stone is thrown from the top of a building upward at an
                // angle of 30.0° to the horizontal and with an initial speed of
                // 20.0 m/s, as shown in Figure 4.12. If the height of the building
                // is 45.0 m, (a) how long is it before the stone hits the ground?
                // (b) What is the speed of the stone just before it strikes the
                // ground?

                var thA = new Symbol("thA"); // angle at point A
                var vA = new Symbol("vA"); // velocity at point A

                var g = new Symbol("g"); // magnitude of gravity

                var _g = new Point(0, -g); // gravity vector

                var objA = new Obj()
                {
                    position = new Point(0, 0),
                    velocity = Point.FromAngle(thA, vA),
                    acceleration = _g,
                    time = new Integer(0)
                };

                var objB = new Obj()
                {
                    velocity = new Point(objA.velocity.x, 0),
                    acceleration = _g,
                };

                var timeB = Calc.Time(objA, objB);

                objB = objA.AtTime(timeB);

                var timeC = timeB * 2;

                var objC = objA.AtTime(timeC);

                var yD = new Symbol("yD");

                var objD = new Obj()
                {
                    position = new Point(null, yD),
                    velocity = new Point(objA.velocity.x, null),
                    acceleration = _g
                };

                var timeAD = Calc.Time(objA, objD, 1);

                objD = objA.AtTime(timeAD);

                // "How long is it before the stone hits the ground?".Disp();

                // "Symbolic answer:".Disp();

                AssertIsTrue(
                    timeAD
                    ==
                    -1 * (g ^ -1) * (-1 * Trig.Sin(thA) * vA + -1 * (((Trig.Sin(thA) ^ 2) * (vA ^ 2) + -2 * g * yD) ^ (new Integer(1) / 2))));

                // "Numeric answer:".Disp();

                AssertEqual(
                    (DoubleFloat)
                    timeAD
                        .Substitute(g, 9.8)
                        .Substitute(thA, (30).ToRadians())
                        .Substitute(Trig.Pi, 3.14159)
                        .Substitute(vA, 20)
                        .Substitute(yD, -45),
                    new DoubleFloat(4.21804787012706),
                    0.0001);

                // "What is the speed of the stone just before it strikes the ground?".Disp();

                // "Symbolic answer:".Disp();

                AssertIsTrue(
                    objD.velocity.Norm()
                    ==
                    (((Trig.Cos(thA) ^ 2) * (vA ^ 2) + (Trig.Sin(thA) ^ 2) * (vA ^ 2) + -2 * g * yD) ^ (new Integer(1) / 2)));

                // "Numeric answer:".Disp();

                AssertEqual(
                    (DoubleFloat)
                    objD.velocity.Norm()
                        .Substitute(g, 9.8)
                        .Substitute(thA, (30).ToRadians())
                        .Substitute(Trig.Pi, 3.14159)
                        .Substitute(vA, 20)
                        .Substitute(yD, -45),
                    new DoubleFloat(35.805027579936315),
                    0.1);
            }
            #endregion

            #region PSE 5E EXAMPLE 4.6
            {
                // An Alaskan rescue plane drops a package of emergency rations
                // to a stranded party of explorers, as shown in Figure
                // 4.13. If the plane is traveling horizontally at 40.0 m/s and is
                // 100 m above the ground, where does the package strike the
                // ground relative to the point at which it was released?

                var xA = new Symbol("xA");      // position.x at point A

                var yA = new Symbol("yA");      // position.y at point A

                var thA = new Symbol("thA");    // angle at point A

                var vA = new Symbol("vA");      // velocity at point A

                var g = new Symbol("g");        // magnitude of gravity

                var _g = new Point(0, -g);      // gravity vector

                var objA = new Obj()            // obj at the initial position
                {
                    position = new Point(xA, yA),
                    velocity = Point.FromAngle(thA, vA),
                    acceleration = _g,
                    time = 0
                };

                var objB = new Obj()            // obj at the final position
                {
                    position = new Point(null, 0),
                    velocity = new Point(objA.velocity.x, null),
                    acceleration = _g
                };

                var timeB = Calc.Time(objA, objB, 1);

                objB = objA.AtTime(timeB);

                //"Where does the package strike the ground relative to the point at which it was released?".Disp(); "".Disp();

                //"symbolic:".Disp();

                //objB.position.x.Disp(); "".Disp();

                AssertIsTrue(
                    objB.position.x
                    ==
                    xA - cos(thA) / g * vA * (-sin(thA) * vA - (((sin(thA) ^ 2) * (vA ^ 2) + 2 * g * yA) ^ new Integer(1) / 2)));

                //"numeric:".Disp();

                //objB.position.x
                //    .Substitute(xA, 0)
                //    .Substitute(yA, 100)
                //    .Substitute(vA, 40)
                //    .Substitute(thA, 0.0)
                //    .Substitute(g, 9.8)
                //    .Disp();

                AssertEqual(
                    objB.position.x
                        .Substitute(xA, 0)
                        .Substitute(yA, 100)
                        .Substitute(vA, 40)
                        .Substitute(thA, 0.0)
                        .Substitute(g, 9.8),
                    180.70158058105025);

                //"".Disp();

                //("What are the horizontal and vertical components " +
                // "of the velocity of the package just before it hits the ground?").Disp(); "".Disp();

                //"symbolic velocity.x:".Disp();

                //objB.velocity.x.Disp(); "".Disp();

                AssertIsTrue(objB.velocity.x == cos(thA) * vA);

                //"symbolic velocity.y:".Disp();

                //objB.velocity.y.Disp(); "".Disp();

                AssertIsTrue(
                    objB.velocity.y
                    ==
                    -1 * (((sin(thA) ^ 2) * (vA ^ 2) + 2 * g * yA) ^ (new Integer(1) / 2)));

                //"numeric velocity.x:".Disp();

                //objB.velocity.x
                //    .Substitute(xA, 0)
                //    .Substitute(yA, 100)
                //    .Substitute(vA, 40)
                //    .Substitute(thA, 0.0)
                //    .Substitute(g, 9.8)
                //    .Disp(); "".Disp();

                AssertEqual(
                    objB.velocity.x
                        .Substitute(xA, 0)
                        .Substitute(yA, 100)
                        .Substitute(vA, 40)
                        .Substitute(thA, 0.0)
                        .Substitute(g, 9.8),
                    40);

                //"numeric velocity.y:".Disp();

                //objB.velocity.y
                //    .Substitute(xA, 0)
                //    .Substitute(yA, 100)
                //    .Substitute(vA, 40)
                //    .Substitute(thA, 0.0)
                //    .Substitute(g, 9.8)
                //    .Disp(); "".Disp();

                AssertEqual(
                    objB.velocity.y
                        .Substitute(xA, 0)
                        .Substitute(yA, 100)
                        .Substitute(vA, 40)
                        .Substitute(thA, 0.0)
                        .Substitute(g, 9.8),
                    -44.271887242357316);
            }
            #endregion

            #region PSE 5E EXAMPLE 4.7

            {
                // A ski jumper leaves the ski track moving in the horizontal
                // direction with a speed of 25.0 m/s, as shown in Figure 4.14.
                // The landing incline below him falls off with a slope of 35.0°.
                // Where does he land on the incline?

                var thA = new Symbol("thA");    // angle at point A

                var vA = new Symbol("vA");      // velocity at point A

                var g = new Symbol("g");        // magnitude of gravity

                var _g = new Point(0, -g);      // gravity vector

                var th = new Symbol("th");      // angle of incline

                var objA = new Obj()
                {
                    position = new Point(0, 0),
                    velocity = Point.FromAngle(thA, vA),
                    acceleration = _g,
                    time = 0
                };

                Func<MathObject, MathObject> numeric = obj =>
                    obj
                        .Substitute(vA, 25)
                        .Substitute(thA, 0.0)
                        .Substitute(th, (-35).ToRadians())
                        .Substitute(Trig.Pi, 3.14159)
                        .Substitute(g, 9.8);

                var intersection = objA.ProjectileInclineIntersection(th);

                Action nl = () => "".Disp();

                // "Where does he land on the incline?".Disp(); nl();

                // "x position (symbolic):".Disp();

                // intersection.x.Disp(); nl();

                AssertIsTrue(
                    intersection.x
                    ==
                    -2 * (cos(th) ^ -1) * (cos(thA) ^ 2) * (g ^ -1) * (sin(th) + -1 * cos(th) * (cos(thA) ^ -1) * sin(thA)) * (vA ^ 2));

                //"y position (symbolic):".Disp();

                //intersection.y.Disp(); nl();

                AssertIsTrue(
                    intersection.y
                    ==
                    -2 * (cos(th) ^ -2) * (cos(thA) ^ 2) / g * sin(th) * (sin(th) + -1 * cos(th) * (cos(thA) ^ -1) * sin(thA)) * (vA ^ 2));

                //"x position (numeric):".Disp();

                //numeric(intersection.x).Disp(); nl();

                AssertEqual(numeric(intersection.x), 89.3120879153208);

                //"y position (numeric):".Disp();

                //numeric(intersection.y).Disp(); nl();

                AssertEqual(numeric(intersection.y), -62.536928534704884);

                var objB = new Obj()
                {
                    position = intersection,
                    acceleration = _g
                };

                //"Determine how long the jumper is airborne".Disp(); nl();

                //"symbolic:".Disp();

                var timeB = Calc.Time(objA, objB, 1);

                // timeB.Disp(); nl();

                Func<MathObject, MathObject> sqrt = obj => obj ^ (new Integer(1) / 2);

                AssertIsTrue(
                    timeB
                    ==
                    -1 / g *
                    (-sin(thA) * vA -
                        sqrt(
                            (sin(thA) ^ 2) * (vA ^ 2) + 4 * (cos(th) ^ -2) * (cos(thA) ^ 2) * sin(th) *
                            (sin(th) - cos(th) / cos(thA) * sin(thA)) *
                            (vA ^ 2))));

                //"numeric:".Disp();

                //numeric(timeB).Disp(); nl();

                AssertEqual(numeric(timeB), 3.5724835166128317);

                objB = objA.AtTime(timeB);

                //"Determine his vertical component of velocity just before he lands".Disp();
                //nl();

                //"symbolic:".Disp();

                //objB.velocity.y.Disp(); nl();

                AssertIsTrue(
                    objB.velocity.y
                    ==
                    -sqrt(
                        (sin(thA) ^ 2) * (vA ^ 2)
                        +
                        4 * (cos(th) ^ -2) * (cos(thA) ^ 2) * sin(th) *
                        (sin(th) - cos(th) * (cos(thA) ^ -1) * sin(thA)) *
                        (vA ^ 2)));

                //"numeric:".Disp();

                //numeric(objB.velocity.y).Disp();

                AssertEqual(
                    numeric(objB.velocity.y),
                    -35.010338462805755);
            }

            #endregion

            #region PSE 5E PROBLEM 4.11

            {
                // One strategy in a snowball fight is to throw a first snowball at a
                // high angle over level ground. While your opponent is watching the
                // first one, you throw a second one at a low angle and timed to arrive
                // at your opponent before or at the same time as the first one. Assume
                // both snowballs are thrown with a speed of 25.0 m/s. The first one is
                // thrown at an angle of 70.0° with respect to the horizontal.
                //
                // (a) At what angle should the second (low-angle) snowball be thrown
                // if it is to land at the same point as the first?
                //
                // (b) How many seconds later should the second snowball be thrown if it
                // is to land at the same time as the first?

                var xA = new Symbol("xA");      // position.x at point A
                var yA = new Symbol("yA");      // position.y at point A
                var th1A = new Symbol("th1A");  // angle of snowball 1 at point A
                var vA = new Symbol("vA");      // velocity at point A

                var g = new Symbol("g");        // magnitude of gravity
                var _g = new Point(0, -g);      // gravity vector

                //Func<MathObject, MathObject> numeric = obj =>
                //    obj
                //        .Substitute(xA, 0)
                //        .Substitute(xB, 1.4)
                //        .Substitute(yA, 0.86)
                //        .Substitute(g, 9.8)
                //        .Substitute(Trig.Pi, 3.14159);

                var obj1A = new Obj()           // snowball 1 at initial point
                {
                    position = new Point(xA, yA),
                    velocity = Point.FromAngle(th1A, vA),
                    acceleration = _g,
                    time = 0
                };

                var obj1B = new Obj()            // snowball 1 at final point
                {
                    position = new Point(null, 0),
                    velocity = new Point(obj1A.velocity.x, null),
                    acceleration = _g
                };

                var time1B = Calc.Time(obj1A, obj1B, 1);

                obj1B = obj1A.AtTime(time1B);

                var obj2A = new Obj()           // snowball 2 at initial point
                {
                    position = obj1A.position,
                    speed = vA,
                    acceleration = _g
                };

                var obj2B = new Obj()           // snowball 2 at final point
                {
                    position = obj1B.position,
                    acceleration = _g
                };

                //Calc.InitialAngle(obj2A, obj2B, 1, 0)
                //    .Substitute(yA, 0)
                //    .Substitute(th1A, (70).ToRadians())
                //    .Substitute(vA, 25)
                //    .Substitute(Trig.Pi, 3.14159)
                //    .Substitute(g, 9.8)
                //    .ToDegrees()
                //    .Substitute(Trig.Pi, 3.14159)
                //    .Disp();

                var th2 = Calc.InitialAngle(obj2A, obj2B, 0, 0);

                //("At what angle should the second (low-angle) snowball " +
                //"be thrown if it is to land at the same point as the first?").Disp();

                //"".Disp();

                //"symbolic:".Disp();

                //th2.Disp(); "".Disp();

                //"numeric:".Disp();

                AssertEqual(
                    th2
                        .ToDegrees()
                        .Substitute(yA, 0)
                        .Substitute(th1A, (70).ToRadians())
                        .Substitute(vA, 25)
                        .Substitute(g, 9.8)
                        .Substitute(Trig.Pi, Math.PI),
                    20.000000000000007);

                //"".Disp();

                obj2A.velocity = Point.FromAngle(th2, vA);

                var time2B = Calc.Time(obj2A, obj2B, 1);

                //("How many seconds later should the second snowball be thrown if it " +
                //"is to land at the same time as the first?").Disp();

                //"".Disp();

                //"symbolic:".Disp();

                //(time1B - time2B).Disp(); "".Disp();

                //"numeric:".Disp();

                //(time1B - time2B)
                //    .Substitute(yA, 0)
                //    .Substitute(th1A, (70).ToRadians())
                //    .Substitute(vA, 25)
                //    .Substitute(Trig.Pi, 3.14159)
                //    .Substitute(g, 9.8)
                //    .Disp();

                AssertEqual(
                    (time1B - time2B)
                        .Substitute(yA, 0)
                        .Substitute(th1A, (70).ToRadians())
                        .Substitute(vA, 25)
                        .Substitute(Trig.Pi, 3.14159)
                        .Substitute(g, 9.8),
                    3.0493426265020469);

                //Console.ReadLine();
            }

            #endregion

            #region PSE 5E PROBLEM 4.17

            {
                // A cannon with a muzzle speed of 1 000 m/s is used to
                // start an avalanche on a mountain slope. The target is
                // 2 000 m from the cannon horizontally and 800 m above
                // the cannon. At what angle, above the horizontal, should
                // the cannon be fired?

                var xA = new Symbol("xA");      // position.x at point A
                var yA = new Symbol("yA");      // position.y at point A
                var thA = new Symbol("thA");  // angle of snowball 1 at point A
                var vA = new Symbol("vA");      // velocity at point A

                var xB = new Symbol("xB");      // position.x at point A
                var yB = new Symbol("yB");      // position.y at point A

                var g = new Symbol("g");        // magnitude of gravity
                var _g = new Point(0, -g);      // gravity vector

                var objA = new Obj()
                {
                    position = new Point(xA, yA),
                    speed = vA,
                    acceleration = _g,
                    time = 0
                };

                var objB = new Obj()
                {
                    position = new Point(xB, yB),
                    acceleration = _g
                };

                //"At what angle, above the horizontal, should the cannon be fired?".Disp();

                AssertEqual(
                    Calc.InitialAngle(objA, objB)
                        .ToDegrees()
                        .Substitute(xA, 0)
                        .Substitute(yA, 0)
                        .Substitute(xB, 2000.0)
                        .Substitute(yB, 800)
                        .Substitute(vA, 1000)
                        .Substitute(g, 9.8)
                        .Substitute(Trig.Pi, Math.PI),
                    22.365163229244317);

                //Calc.InitialAngle(objA, objB)
                //    .ToDegrees()
                //    .Substitute(xA, 0)
                //    .Substitute(yA, 0)
                //    .Substitute(xB, 2000.0)
                //    .Substitute(yB, 800)
                //    .Substitute(vA, 1000)
                //    .Substitute(g, 9.8)
                //    .Substitute(Trig.Pi, Math.PI)
                //    .Disp();
            }

            #endregion

            #region PSE 5E PROBLEM 4.24
            {
                // A bag of cement of weight 325 N hangs from three
                // wires as shown in Figure P5.24. Two of the wires make
                // angles th1 = 60.0° and th2 = 25.0° with the horizontal. If
                // the system is in equilibrium, find the tensions
                // T1, T2, and T3 in the wires.

                var F1 = new Symbol("F1");
                var F2 = new Symbol("F2");
                var F3 = new Symbol("F3");

                var th1 = new Symbol("th1");
                var th2 = new Symbol("th2");
                var th3 = new Symbol("th3");

                var _F1 = new Point() { angle = th1 };
                var _F2 = new Point() { angle = th2 };
                var _F3 = new Point() { magnitude = F3, angle = th3 };

                var m = new Symbol("m");

                var obj = new Obj();

                obj.acceleration.x = 0;
                obj.acceleration.y = 0;

                obj.mass = m;

                obj.forces.Add(_F1);
                obj.forces.Add(_F2);
                obj.forces.Add(_F3);

                //"F1 magnitude, symbolic:".Disp(); "".Disp();

                //obj.ForceMagnitude(_F1).Disp(); "".Disp();

                //"F1 magnitude, numeric:".Disp(); "".Disp();

                //obj.ForceMagnitude(_F1)
                //    .Substitute(F3, 325)
                //    .Substitute(th1, (180 - 60).ToRadians())
                //    .Substitute(th2, (25).ToRadians())
                //    .Substitute(th3, (270).ToRadians())
                //    .Substitute(Trig.Pi, Math.PI)
                //    .Disp();

                AssertEqual(
                    obj.ForceMagnitude(_F1)
                        .Substitute(F3, 325)
                        .Substitute(th1, (180 - 60).ToRadians())
                        .Substitute(th2, (25).ToRadians())
                        .Substitute(th3, (270).ToRadians())
                        .Substitute(Trig.Pi, Math.PI),
                    295.67516405290525);

                // "".Disp();

                //"F3 magnitude, numeric:".Disp(); "".Disp();

                //obj.ForceMagnitude(_F2)
                //    .Substitute(F3, 325)
                //    .Substitute(th1, (180 - 60).ToRadians())
                //    .Substitute(th2, (25).ToRadians())
                //    .Substitute(th3, (270).ToRadians())
                //    .Substitute(Trig.Pi, Math.PI)
                //    .Disp();

                AssertEqual(
                    obj.ForceMagnitude(_F2)
                        .Substitute(F3, 325)
                        .Substitute(th1, (180 - 60).ToRadians())
                        .Substitute(th2, (25).ToRadians())
                        .Substitute(th3, (270).ToRadians())
                        .Substitute(Trig.Pi, Math.PI),
                    163.12072360079395);
            }
            #endregion

            #region PSE 5E PROBLEM 5.26
            {
                // You are a judge in a children’s kite-flying contest, and
                // two children will win prizes for the kites that pull most
                // strongly and least strongly on their strings. To measure
                // string tensions, you borrow a weight hanger, some slotted
                // weights, and a protractor from your physics teacher
                // and use the following protocol, illustrated in Figure
                // P5.26: Wait for a child to get her kite well-controlled,
                // hook the hanger onto the kite string about 30 cm from
                // her hand, pile on weights until that section of string is
                // horizontal, record the mass required, and record the
                // angle between the horizontal and the string running up
                // to the kite. (a) Explain how this method works. As you
                // construct your explanation, imagine that the children’s
                // parents ask you about your method, that they might
                // make false assumptions about your ability without concrete
                // evidence, and that your explanation is an opportunity to
                // give them confidence in your evaluation tech-nique.
                // (b) Find the string tension if the mass required
                // to make the string horizontal is 132 g and the angle of
                // the kite string is 46.3°.

                var F1 = new Symbol("F1");
                var F2 = new Symbol("F2");
                var F3 = new Symbol("F3");

                var th1 = new Symbol("th1");
                var th2 = new Symbol("th2");
                var th3 = new Symbol("th3");

                var _F1 = new Point() { angle = th1 };
                var _F2 = new Point() { angle = th2 };
                var _F3 = new Point() { magnitude = F3, angle = th3 };

                var m = new Symbol("m");

                var obj = new Obj();

                obj.acceleration.x = 0;
                obj.acceleration.y = 0;

                obj.mass = m;

                obj.forces.Add(_F1);
                obj.forces.Add(_F2);
                obj.forces.Add(_F3);

                //"Tension in line to kite:".Disp(); "".Disp();

                //obj.ForceMagnitude(_F2)
                //    .Substitute(th1, (180).ToRadians())
                //    .Substitute(th2, (46.3 * Math.PI / 180))
                //    .Substitute(th3, (270).ToRadians())
                //    .Substitute(F3, 0.132 * 9.8)
                //    .Substitute(Trig.Pi, Math.PI)
                //    .Disp();

                AssertEqual(
                    obj.ForceMagnitude(_F2)
                        .Substitute(th1, (180).ToRadians())
                        .Substitute(th2, (46.3 * Math.PI / 180))
                        .Substitute(th3, (270).ToRadians())
                        .Substitute(F3, 0.132 * 9.8)
                        .Substitute(Trig.Pi, Math.PI),
                    1.7892929261294661);

                //Console.ReadLine();
            }
            #endregion

            #region PSE 5E PROBLEM 5.28
            {
                // A fire helicopter carries a 620-kg bucket of water at the
                // end of a cable 20.0 m long. As the aircraft flies back
                // from a fire at a constant speed of 40.0 m/s, the cable
                // makes an angle of 40.0° with respect to the vertical.
                // (a) Determine the force of air resistance on the bucket.
                // (b) After filling the bucket with sea water, the pilot re-
                // turns to the fire at the same speed with the bucket now
                // making an angle of 7.00° with the vertical. What is the
                // mass of the water in the bucket?

                var F1 = new Symbol("F1"); // force of air resistance
                var F2 = new Symbol("F2"); // force of cable
                var F3 = new Symbol("F3"); // force of gravity

                var th1 = new Symbol("th1");
                var th2 = new Symbol("th2");
                var th3 = new Symbol("th3");

                var _F1 = new Point() { angle = th1 };
                var _F2 = new Point() { angle = th2 };
                var _F3 = new Point() { magnitude = F3, angle = th3 };

                var m = new Symbol("m");

                var obj = new Obj();

                obj.acceleration.x = 0;
                obj.acceleration.y = 0;

                obj.mass = m;

                obj.forces.Add(_F1);
                obj.forces.Add(_F2);
                obj.forces.Add(_F3);

                //"Force of air resistance on the bucket:".Disp(); "".Disp();

                var FAir =
                    obj.ForceMagnitude(_F1)
                        .Substitute(F3, 620 * 9.8)
                        .Substitute(th1, (180).ToRadians())
                        .Substitute(th2, (90 - 40).ToRadians())
                        .Substitute(th3, (270).ToRadians())
                        .Substitute(Trig.Pi, Math.PI);

                AssertEqual(
                    obj.ForceMagnitude(_F1)
                        .Substitute(F3, 620 * 9.8)
                        .Substitute(th1, (180).ToRadians())
                        .Substitute(th2, (90 - 40).ToRadians())
                        .Substitute(th3, (270).ToRadians())
                        .Substitute(Trig.Pi, Math.PI),
                    5098.3693590331513);

                //"".Disp();

                _F1.magnitude = FAir;

                _F3.magnitude = null;

                var FBucketWithWater =
                    obj.ForceMagnitude(_F3)
                        .Substitute(th1, (180).ToRadians())
                        .Substitute(th2, (90 - 7).ToRadians())
                        .Substitute(th3, (270).ToRadians())
                        .Substitute(Trig.Pi, Math.PI);

                //"What is the mass of the water in the bucket?".Disp(); "".Disp();

                //(FBucketWithWater / 9.8 - 620).Disp();

                AssertEqual(
                    (FBucketWithWater / 9.8 - 620),
                    3617.0292120139611);
            }
            #endregion

            #region PSE 5E PROBLEM 5.30
            {
                // A simple accelerometer is constructed by suspending a
                // mass m from a string of length L that is tied to the top
                // of a cart. As the cart is accelerated the string-mass
                // system makes a constant angle th with the vertical.
                // (a) Assuming that the string mass is negligible compared
                // with m, derive an expression for the cart’s acceleration
                // in terms of and show that it is independent of
                // the mass mand the length L.
                // (b) Determine the acceleration of the cart when th = 23.0°.

                var F1 = new Symbol("F1"); // force of string
                var F2 = new Symbol("F2"); // force of gravity

                var th1 = new Symbol("th1");
                var th2 = new Symbol("th2"); ;

                var _F1 = new Point() { angle = th1 };
                var _F2 = new Point() { angle = th2, magnitude = F2 };

                var m = new Symbol("m");

                var g = new Symbol("g");

                var obj = new Obj() { mass = m };

                obj.acceleration.y = 0;

                obj.forces.Add(_F1);
                obj.forces.Add(_F2);

                _F1.magnitude = obj.ForceMagnitude(_F1);

                //("Derive an expression for the cart’s acceleration in terms " +
                //"of and show that it is independent of the mass mand the length L:").Disp();

                //"".Disp();

                //obj.AccelerationX()
                //    .Substitute(F2, m * g)
                //    .Substitute(Trig.Cos(th2), 0)
                //    .Substitute(Trig.Sin(th2), -1)
                //    .Disp();

                //"".Disp();

                //"Determine the acceleration of the cart when th = 23.0°".Disp(); "".Disp();

                //obj.AccelerationX()
                //    .Substitute(F2, m * g)
                //    .Substitute(Trig.Cos(th2), 0)
                //    .Substitute(Trig.Sin(th2), -1)
                //    .Substitute(th1, (90 - 23).ToRadians())
                //    .Substitute(Trig.Pi, Math.PI)
                //    .Substitute(g, 9.8)
                //    .Disp();

                AssertEqual(
                    obj.AccelerationX()
                        .Substitute(F2, m * g)
                        .Substitute(Trig.Cos(th2), 0)
                        .Substitute(Trig.Sin(th2), -1)
                        .Substitute(th1, (90 - 23).ToRadians())
                        .Substitute(Trig.Pi, Math.PI)
                        .Substitute(g, 9.8),
                    4.1598531988541261);
            }
            #endregion

            #region PSE 5E PROBLEM 5.31
            {
                // Two people pull as hard as they can on ropes attached
                // to a boat that has a mass of 200 kg. If they pull in the
                // same direction, the boat has an acceleration of
                // 1.52 m/s^2 to the right. If they pull in opposite directions,
                // the boat has an acceleration of 0.518 m/s^2
                // to the left. What is the force exerted by each person on the
                // boat? (Disregard any other forces on the boat.)

                // Trig.Cos(new DoubleFloat(Math.PI)).Disp();

                var m = new Symbol("m");

                var aAx = new Symbol("aAx");
                var aBx = new Symbol("aBx");

                var objA = new Obj() { mass = m };

                objA.acceleration.x = aAx;

                var _F1A = new Point() { angle = 0 };
                var _F2A = new Point() { angle = 0 };

                objA.forces.Add(_F1A);
                objA.forces.Add(_F2A);

                var objB = new Obj() { mass = m };

                objB.acceleration.x = aBx;

                var _F1B = new Point() { angle = 0 };
                var _F2B = new Point() { angle = new DoubleFloat(Math.PI) };

                objB.forces.Add(_F1B);
                objB.forces.Add(_F2B);

                //"force 1 magnitude (symbolic):".Disp(); "".Disp();

                //Calc.ForceMagnitude(objA, objB, _F1A, _F1B)
                //    .Substitute(Trig.Cos(0), 1)
                //    .Disp();

                //"force 1 magnitude (numeric):".Disp(); "".Disp();

                //Calc.ForceMagnitude(objA, objB, _F1A, _F1B)
                //    .Substitute(Trig.Cos(0), 1)
                //    .Substitute(m, 200)
                //    .Substitute(aAx, 1.52)
                //    .Substitute(aBx, -0.518)
                //    .Disp();

                AssertEqual(
                    Calc.ForceMagnitude(objA, objB, _F1A, _F1B)
                        .Substitute(Trig.Cos(0), 1)
                        .Substitute(m, 200)
                        .Substitute(aAx, 1.52)
                        .Substitute(aBx, -0.518),
                    100.19999999999999);

                //"".Disp();

                //"force 2 magnitude (symbolic):".Disp(); "".Disp();

                //Calc.ForceMagnitude(objA, objB, _F2A, _F2B)
                //    .Substitute(Trig.Cos(0), 1)
                //    .Disp();

                //"force 2 magnitude (numeric):".Disp(); "".Disp();

                //Calc.ForceMagnitude(objA, objB, _F2A, _F2B)
                //    .Substitute(Trig.Cos(0), 1)
                //    .Substitute(m, 200)
                //    .Substitute(aAx, 1.52)
                //    .Substitute(aBx, -0.518)
                //    .Disp();

                //"".Disp();

                AssertEqual(
                    Calc.ForceMagnitude(objA, objB, _F2A, _F2B)
                        .Substitute(Trig.Cos(0), 1)
                        .Substitute(m, 200)
                        .Substitute(aAx, 1.52)
                        .Substitute(aBx, -0.518),
                    203.8);

            }
            #endregion

            Console.WriteLine("Testing complete");

            Console.ReadLine();
        }
예제 #13
0
        static void Main(string[] args)
        {
            // Two people pull as hard as they can on ropes attached
            // to a boat that has a mass of 200 kg. If they pull in the
            // same direction, the boat has an acceleration of
            // 1.52 m/s^2 to the right. If they pull in opposite directions,
            // the boat has an acceleration of 0.518 m/s^2
            // to the left. What is the force exerted by each person on the
            // boat? (Disregard any other forces on the boat.)

            // Trig.Cos(new DoubleFloat(Math.PI)).Disp();

            var m = new Symbol("m");

            var aAx = new Symbol("aAx");
            var aBx = new Symbol("aBx");

            var objA = new Obj() { mass = m };

            objA.acceleration.x = aAx;

            var _F1A = new Point() { angle = 0 };
            var _F2A = new Point() { angle = 0 };

            objA.forces.Add(_F1A);
            objA.forces.Add(_F2A);

            var objB = new Obj() { mass = m };

            objB.acceleration.x = aBx;

            var _F1B = new Point() { angle = 0 };
            var _F2B = new Point() { angle = new DoubleFloat(Math.PI) };

            objB.forces.Add(_F1B);
            objB.forces.Add(_F2B);

            "force 1 magnitude (symbolic):".Disp(); "".Disp();

            Calc.ForceMagnitude(objA, objB, _F1A, _F1B)
                .Substitute(Trig.Cos(0), 1)
                .Disp();

            "force 1 magnitude (numeric):".Disp(); "".Disp();

            Calc.ForceMagnitude(objA, objB, _F1A, _F1B)
                .Substitute(Trig.Cos(0), 1)
                .Substitute(m, 200)
                .Substitute(aAx, 1.52)
                .Substitute(aBx, -0.518)
                .Disp();

            "".Disp();

            "force 2 magnitude (symbolic):".Disp(); "".Disp();

            Calc.ForceMagnitude(objA, objB, _F2A, _F2B)
                .Substitute(Trig.Cos(0), 1)
                .Disp();

            "force 2 magnitude (numeric):".Disp(); "".Disp();

            Calc.ForceMagnitude(objA, objB, _F2A, _F2B)
                .Substitute(Trig.Cos(0), 1)
                .Substitute(m, 200)
                .Substitute(aAx, 1.52)
                .Substitute(aBx, -0.518)
                .Disp();

            "".Disp();

            Console.ReadLine();
        }
예제 #14
0
        public static MathObject Time(Obj a, Obj b, int solution = 0)
        {
            if (a.velocity.x != null &&
                b.velocity.x != null &&
                a.acceleration.x != null &&
                a.acceleration.x != new DoubleFloat(0.0) &&
                a.acceleration.x != new Integer(0))
                return (b.velocity.x - a.velocity.x) / a.acceleration.x;

            if (a.velocity.y != null &&
                b.velocity.y != null &&
                a.acceleration.y != null &&
                a.acceleration.y != new DoubleFloat(0.0) &&
                a.acceleration.y != new Integer(0))
                return (b.velocity.y - a.velocity.y) / a.acceleration.y;

            // yf = yi + vyi * t + 1/2 * ay * t^2
            // 0 = 1/2 * ay * t^2 + vyi * t + yi - yf
            // apply quadratic equation to find t

            if (a.position.y != null &&
                b.position.y != null &&
                a.velocity.y != null &&
                a.acceleration.y != null &&
                a.acceleration.y != new Integer(0) &&
                a.acceleration.y != new DoubleFloat(0.0))
            {
                var half = new Integer(1) / 2;

                return
                    Misc.QuadraticEquation(
                        half * a.acceleration.y,
                        a.velocity.y,
                        a.position.y - b.position.y,
                        solution);
            }

            throw new Exception();
        }
예제 #15
0
        public static Point InitialVelocity(Obj a, Obj b)
        {
            if (a.time != null && b.time != null)
            {
                var dt = b.time - a.time;

                if (Misc.NotNull(
                    a.position.x,
                    a.position.y,
                    b.position.x,
                    b.position.y,
                    a.acceleration.x,
                    a.acceleration.y))
                {
                    var half = new Integer(1) / 2;

                    return
                        (b.position - a.position - half * a.acceleration * (dt ^ 2))
                        /
                        dt;
                }
            }

            throw new Exception();
        }
예제 #16
0
        static void Main(string[] args)
        {
            // A ski jumper leaves the ski track moving in the horizontal
            // direction with a speed of 25.0 m/s, as shown in Figure 4.14.
            // The landing incline below him falls off with a slope of 35.0°.
            // Where does he land on the incline?

            var thA = new Symbol("thA");    // angle at point A

            var vA = new Symbol("vA");      // velocity at point A

            var g = new Symbol("g");        // magnitude of gravity

            var _g = new Point(0, -g);      // gravity vector

            var th = new Symbol("th");      // angle of incline

            var objA = new Obj()
            {
                position = new Point(0, 0),
                velocity = Point.FromAngle(thA, vA),
                acceleration = _g,
                time = 0
            };

            Func<MathObject, MathObject> numeric = obj =>
                obj
                    .Substitute(vA, 25)
                    .Substitute(thA, 0.0)
                    .Substitute(th, (-35).ToRadians())
                    .Substitute(Trig.Pi, 3.14159)
                    .Substitute(g, 9.8);

            var intersection = objA.ProjectileInclineIntersection(th);

            Action nl = () => "".Disp();

            "Where does he land on the incline?".Disp(); nl();

            "x position (symbolic):".Disp();

            intersection.x.Disp(); nl();

            "y position (symbolic):".Disp();

            intersection.y.Disp(); nl();

            "x position (numeric):".Disp();

            numeric(intersection.x).Disp(); nl();

            "y position (numeric):".Disp();

            numeric(intersection.y).Disp(); nl();

            var objB = new Obj()
            {
                position = intersection,
                acceleration = _g
            };

            "Determine how long the jumper is airborne".Disp(); nl();

            "symbolic:".Disp();

            var timeB = Calc.Time(objA, objB, 1);

            timeB.Disp(); nl();

            "numeric:".Disp();

            numeric(timeB).Disp(); nl();

            objB = objA.AtTime(timeB);

            "Determine his vertical component of velocity just before he lands".Disp();
            nl();

            "symbolic:".Disp();

            objB.velocity.y.Disp(); nl();

            "numeric:".Disp();

            numeric(objB.velocity.y).Disp();

            Console.ReadLine();
        }
예제 #17
0
        static void Main(string[] args)
        {
            // One strategy in a snowball fight is to throw a first snowball at a
            // high angle over level ground. While your opponent is watching the
            // first one, you throw a second one at a low angle and timed to arrive
            // at your opponent before or at the same time as the first one. Assume
            // both snowballs are thrown with a speed of 25.0 m/s. The first one is
            // thrown at an angle of 70.0° with respect to the horizontal.
            //
            // (a) At what angle should the second (low-angle) snowball be thrown
            // if it is to land at the same point as the first?
            //
            // (b) How many seconds later should the second snowball be thrown if it
            // is to land at the same time as the first?

            var xA = new Symbol("xA");      // position.x at point A
            var yA = new Symbol("yA");      // position.y at point A
            var th1A = new Symbol("th1A");  // angle of snowball 1 at point A
            var vA = new Symbol("vA");      // velocity at point A

            var g = new Symbol("g");        // magnitude of gravity
            var _g = new Point(0, -g);      // gravity vector

            //Func<MathObject, MathObject> numeric = obj =>
            //    obj
            //        .Substitute(xA, 0)
            //        .Substitute(xB, 1.4)
            //        .Substitute(yA, 0.86)
            //        .Substitute(g, 9.8)
            //        .Substitute(Trig.Pi, 3.14159);

            var obj1A = new Obj()           // snowball 1 at initial point
            {
                position = new Point(xA, yA),
                velocity = Point.FromAngle(th1A, vA),
                acceleration = _g,
                time = 0
            };

            var obj1B = new Obj()            // snowball 1 at final point
            {
                position = new Point(null, new DoubleFloat(0.0)),
                velocity = new Point(obj1A.velocity.x, null),
                acceleration = _g
            };

            var time1B = Calc.Time(obj1A, obj1B, 1);

            obj1B = obj1A.AtTime(time1B);

            var obj2A = new Obj()           // snowball 2 at initial point
            {
                position = obj1A.position,
                speed = vA,
                acceleration = _g
            };

            var obj2B = new Obj()           // snowball 2 at final point
            {
                position = obj1B.position,
                acceleration = _g
            };

            var th2 = Calc.InitialAngle(obj2A, obj2B, 0, 0);

            ("At what angle should the second (low-angle) snowball " +
            "be thrown if it is to land at the same point as the first?").Disp();

            "".Disp();

            "symbolic:".Disp();

            th2.Disp(); "".Disp();

            "numeric:".Disp();

            th2
                .ToDegrees()
                .Substitute(yA, 0)
                .Substitute(th1A, (70).ToRadians())
                .Substitute(vA, 25)
                .Substitute(g, 9.8)
                .Substitute(Trig.Pi, Math.PI)
                .Disp();

            "".Disp();

            obj2A.velocity = Point.FromAngle(th2, vA);

            var time2B = Calc.Time(obj2A, obj2B, 1);

            ("How many seconds later should the second snowball be thrown if it " +
            "is to land at the same time as the first?").Disp();

            "".Disp();

            "symbolic:".Disp();

            (time1B - time2B).Disp(); "".Disp();

            "numeric:".Disp();

            (time1B - time2B)
                .Substitute(yA, 0.0)
                .Substitute(th1A, (70).ToRadians())
                .Substitute(vA, 25.0)
                .Substitute(Trig.Pi, 3.14159)
                .Substitute(g, 9.8)
                .Substitute(0, 0.0)
                .Disp();

            Console.ReadLine();
        }
예제 #18
0
        static void Main(string[] args)
        {
            // A stone is thrown from the top of a building upward at an
            // angle of 30.0° to the horizontal and with an initial speed of
            // 20.0 m/s, as shown in Figure 4.12. If the height of the building
            // is 45.0 m, (a) how long is it before the stone hits the ground?
            // (b) What is the speed of the stone just before it strikes the
            // ground?

            var thA = new Symbol("thA"); // angle at point A
            var vA = new Symbol("vA"); // velocity at point A

            var g = new Symbol("g"); // magnitude of gravity

            var _g = new Point(0, -g); // gravity vector

            var objA = new Obj()
            {
                position = new Point(0, 0),
                velocity = Point.FromAngle(thA, vA),
                acceleration = _g,
                time = 0
            };

            var objB = new Obj()
            {
                velocity = new Point(objA.velocity.x, 0),
                acceleration = _g,
            };

            var timeB = Calc.Time(objA, objB);

            objB = objA.AtTime(timeB);

            var timeC = timeB * 2;

            var objC = objA.AtTime(timeC);

            var yD = new Symbol("yD");

            var objD = new Obj()
            {
                position = new Point(null, yD),
                velocity = new Point(objA.velocity.x, null),
                acceleration = _g
            };

            var timeAD = Calc.Time(objA, objD, 1);

            objD = objA.AtTime(timeAD);

            "How long is it before the stone hits the ground?".Disp();

            "".Disp();

            "Symbolic answer:".Disp();

            timeAD.Disp();

            "".Disp();

            "Numeric answer:".Disp();

            timeAD
                .Substitute(g, 9.8)
                .Substitute(thA, (30).ToRadians())
                .Substitute(Trig.Pi, 3.14159)
                .Substitute(vA, 20)
                .Substitute(yD, -45)
                .Disp();

            "".Disp();

            "What is the speed of the stone just before it strikes the ground?".Disp();

            "".Disp();

            "Symbolic answer:".Disp();

            objD.velocity.Norm().Disp();

            "".Disp();

            "Numeric answer:".Disp();

            objD.velocity.Norm()
                .Substitute(g, 9.8)
                .Substitute(thA, (30).ToRadians())
                .Substitute(Trig.Pi, 3.14159)
                .Substitute(vA, 20)
                .Substitute(yD, -45)
                .Disp();

            Console.ReadKey();
        }
예제 #19
0
        static void Main(string[] args)
        {
            // A fire helicopter carries a 620-kg bucket of water at the
            // end of a cable 20.0 m long. As the aircraft flies back
            // from a fire at a constant speed of 40.0 m/s, the cable
            // makes an angle of 40.0° with respect to the vertical.
            // (a) Determine the force of air resistance on the bucket.
            // (b) After filling the bucket with sea water, the pilot re-
            // turns to the fire at the same speed with the bucket now
            // making an angle of 7.00° with the vertical. What is the
            // mass of the water in the bucket?

            var F1 = new Symbol("F1"); // force of air resistance
            var F2 = new Symbol("F2"); // force of cable
            var F3 = new Symbol("F3"); // force of gravity

            var th1 = new Symbol("th1");
            var th2 = new Symbol("th2");
            var th3 = new Symbol("th3");

            var _F1 = new Point() { angle = th1 };
            var _F2 = new Point() { angle = th2 };
            var _F3 = new Point() { magnitude = F3, angle = th3 };

            var m = new Symbol("m");

            var obj = new Obj();

            obj.acceleration.x = 0;
            obj.acceleration.y = 0;

            obj.mass = m;

            obj.forces.Add(_F1);
            obj.forces.Add(_F2);
            obj.forces.Add(_F3);

            "Force of air resistance on the bucket:".Disp(); "".Disp();

            var FAir =
                obj.ForceMagnitude(_F1)
                    .Substitute(F3, 620 * 9.8)
                    .Substitute(th1, (180).ToRadians())
                    .Substitute(th2, (90-40).ToRadians())
                    .Substitute(th3, (270).ToRadians())
                    .Substitute(Trig.Pi, Math.PI)
                    .Disp();

            "".Disp();

            _F1.magnitude = FAir;

            _F3.magnitude = null;

            var FBucketWithWater =
                obj.ForceMagnitude(_F3)
                    .Substitute(th1, (180).ToRadians())
                    .Substitute(th2, (90 - 7).ToRadians())
                    .Substitute(th3, (270).ToRadians())
                    .Substitute(Trig.Pi, Math.PI);

            "What is the mass of the water in the bucket?".Disp(); "".Disp();

            (FBucketWithWater / 9.8 - 620).Disp();

            Console.ReadLine();
        }
예제 #20
0
        static void Main(string[] args)
        {
            // An Alaskan rescue plane drops a package of emergency rations
            // to a stranded party of explorers, as shown in Figure
            // 4.13. If the plane is traveling horizontally at 40.0 m/s and is
            // 100 m above the ground, where does the package strike the
            // ground relative to the point at which it was released?

            var xA = new Symbol("xA");      // position.x at point A

            var yA = new Symbol("yA");      // position.y at point A

            var thA = new Symbol("thA");    // angle at point A

            var vA = new Symbol("vA");      // velocity at point A

            var g = new Symbol("g");        // magnitude of gravity

            var _g = new Point(0, -g);      // gravity vector

            var objA = new Obj()            // obj at the initial position
            {
                position = new Point(xA, yA),
                velocity = Point.FromAngle(thA, vA),
                acceleration = _g,
                time = 0
            };

            var objB = new Obj()            // obj at the final position
            {
                position = new Point(null, 0),
                velocity = new Point(objA.velocity.x, null),
                acceleration = _g
            };

            var timeB = Calc.Time(objA, objB, 1);

            objB = objA.AtTime(timeB);

            "Where does the package strike the ground relative to the point at which it was released?".Disp(); "".Disp();

            "symbolic:".Disp();

            objB.position.x.Disp(); "".Disp();

            "numeric:".Disp();

            objB.position.x
                .Substitute(xA, 0)
                .Substitute(yA, 100)
                .Substitute(vA, 40)
                .Substitute(thA, 0.0)
                .Substitute(g, 9.8)
                .Disp();

            ("What are the horizontal and vertical components " +
             "of the velocity of the package just before it hits the ground?").Disp(); "".Disp();

            "symbolic velocity.x:".Disp();

            objB.velocity.x.Disp(); "".Disp();

            "symbolic velocity.y:".Disp();

            objB.velocity.y.Disp(); "".Disp();

            "numeric velocity.x:".Disp();

            objB.velocity.x
                .Substitute(xA, 0)
                .Substitute(yA, 100)
                .Substitute(vA, 40)
                .Substitute(thA, 0.0)
                .Substitute(g, 9.8)
                .Disp(); "".Disp();

            "numeric velocity.y:".Disp();

            objB.velocity.y
                .Substitute(xA, 0)
                .Substitute(yA, 100)
                .Substitute(vA, 40)
                .Substitute(thA, 0.0)
                .Substitute(g, 9.8)
                .Disp(); "".Disp();

            Console.ReadLine();
        }