Example #1
0
 /// <summary>
 /// Wrap a position equation around a cylinder.
 /// </summary>
 /// <param name="radius">Radius of the cylinder</param>
 /// <param name="ang0">Starting angle offset (radians) on the cylinder. 0 = z-axis</param>
 /// <param name="maxWrap">Maximum angle value (radians) of the wrap. After this, the function will continue along the tangent. Starting offset not included. Absolute value tested.</param>
 /// <param name="axisOff">Offset angle (radians) of the axis of the cylinder from the y-axis</param>
 /// <param name="position">Position equation</param>
 /// <returns></returns>
 public static tv3 CylinderWrap(efloat radius, efloat ang0, efloat maxWrap, efloat axisOff, ev2 position) =>
 EEx.Resolve(radius, ang0, axisOff, position, (r, a0, axis, _v2) => {
     var cs    = new TExV2();
     var xyd   = new TExV2();
     var v2    = new TExV2(_v2);
     var v3    = new TExV3();
     var a     = ExUtils.VFloat();
     var aRem  = ExUtils.VFloat();
     var aMax  = ExUtils.VFloat();
     var a_cs  = new TExV2();
     var a0_cs = new TExV2();
     return(Ex.Block(new[] { v3, cs, xyd, a, aRem, aMax, a_cs, a0_cs },
                     aMax.Is(maxWrap),
                     cs.Is(CosSin(axis)),
                     xyd.Is(ConvertBasis(v2, cs)),
                     a.Is(xyd.x.Div(r)),
                     aRem.Is(E0),
                     Ex.IfThen(Abs(a).GT(aMax), Ex.Block(
                                   Ex.IfThen(a.LT0(), MulAssign(aMax, EN1)),
                                   aRem.Is(a.Sub(aMax)),
                                   a.Is(aMax)
                                   )),
                     a0_cs.Is(CosSin(a0)),
                     a_cs.Is(CosSin(a.Add(a0))),
                     xyd.x.Is(r.Mul(a_cs.y.Sub(a0_cs.y).Add(aRem.Mul(a_cs.x)))),
                     v3.Is(TP3(DeconvertBasis(xyd, cs))),
                     v3.z.Is(r.Mul(a_cs.x.Sub(a0_cs.x).Sub(aRem.Mul(a_cs.y)))),
                     v3
                     ));
 });
Example #2
0
        public static void TestV2Utils()
        {
            var exv2   = new TExV2();
            var exb    = new TExV2();
            var r      = VFloat();
            var rot    = Ex.Lambda <Func <Vector2, float, Vector2> >(Rotate(r, exv2), exv2, r).Compile();
            var norm   = Ex.Lambda <Func <Vector2, Vector2> >(Norm(exv2), exv2).Compile();
            var conv   = Ex.Lambda <Func <Vector2, Vector2, Vector2> >(ConvertBasis(exv2, exb), exv2, exb).Compile();
            var deconv = Ex.Lambda <Func <Vector2, Vector2, Vector2> >(DeconvertBasis(exv2, exb), exv2, exb).Compile();

            for (float x = -3; x < 3; x += 0.5f)
            {
                for (float y = -3; y < 3; y += 0.5f)
                {
                    var v2 = new Vector2(x, y);
                    for (float ang = -300; ang < 400; ang += 24)
                    {
                        var dir = M.CosSinDeg(ang);
                        VecEq(rot(new Vector2(x, y), ang), M.RotateVectorDeg(x, y, ang));
                        VecEq(M.ConvertBasis(v2, dir), conv(v2, dir));
                        VecEq(M.DeconvertBasis(v2, dir), deconv(v2, dir));
                        VecEq(deconv(conv(v2, dir), dir), v2);
                    }
                    VecEq(norm(new Vector2(x, y)), (new Vector2(x, y)).normalized);
                }
            }
        }
Example #3
0
 /// <summary>
 /// Note: requires that normalVec and planeVec are perpendicular.
 /// </summary>
 public static tv3 RotateInPlane(tfloat rot, tv3 normalVec, ev3 planeVec) => EEx.Resolve(planeVec, p => {
     var cs    = new TExV2();
     var cross = new TExV3();
     return(Ex.Block(new ParameterExpression[] { cs, cross },
                     cs.Is(CosSinDeg(rot)),
                     cross.Is(CrossProduct(normalVec, p)),
                     cs.x.Mul(p).Add(cs.y.Mul(v3Mag(p).Div(v3Mag(cross)).Mul(cross)))
                     ));
 });
Example #4
0
 public static ExTP LNearestEnemy() => b => {
     var loc = new TExV2();
     return(Ex.Block(new ParameterExpression[] { loc },
                     Ex.IfThen(Ex.Not(Enemy.findNearest.Of(b.loc, loc)),
                               loc.Is(Ex.Constant(new Vector2(0f, 50f)))
                               ),
                     loc
                     ));
 };
Example #5
0
        /// <summary>
        /// Home towards a target location at a fixed speed.
        /// </summary>
        /// <remarks>
        /// Use with StopSampling to home for only a few seconds.
        /// <para>This is primarily for use with non-rotational velocity.
        /// Rotational use creates: contracting spirals (0,90), circle around player [90], expanding spiral (90,180).</para>
        /// </remarks>
        /// <param name="speed">Speed</param>
        /// <param name="location">Target location</param>
        /// <returns></returns>
        public static ExTP VHome(ExBPY speed, ExTP location)
        {
            TExV2 l = new TExV2();

            return(bpi => Ex.Block(new ParameterExpression[] { l },
                                   Ex.Assign(l, location(bpi).Sub(bpi.loc)),
                                   l.Mul(Ex.Divide(speed(bpi), Sqrt(Ex.Add(SqrMag(l), EPS))))
                                   ));
        }
Example #6
0
 public static tv3 FromSphere(tfloat radius, ev2 sphere) => radius.Mul(EEx.ResolveV2(sphere, s => {
     var cst = new TExV2();
     var csp = new TExV2();
     return(Ex.Block(new ParameterExpression[] { cst, csp },
                     cst.Is(CosSinDeg(s.x)),
                     csp.Is(CosSinDeg(s.y)),
                     V3(cst.x.Mul(csp.y), cst.y.Mul(csp.y), csp.x)
                     ));
 }));
Example #7
0
 public static ExCoordF CartesianRot(ExTP erv) => (c, s, bpi, nrv, fxy) => {
     var v2 = new TExV2();
     return(Ex.Block(new ParameterExpression[] { v2 },
                     Ex.Assign(v2, erv(bpi)),
                     fxy(Ex.Subtract(Ex.Multiply(c, v2.x), Ex.Multiply(s, v2.y)),
                         Ex.Add(Ex.Multiply(s, v2.x), Ex.Multiply(c, v2.y))),
                     Expression.Empty()
                     ));
 };
Example #8
0
        /// <summary>
        /// Multiply the x-component of a parametric equation by a function of input.
        /// </summary>
        /// <param name="f">Function of input</param>
        /// <param name="tp">Parametric equation</param>
        /// <returns></returns>
        public static ExTP MultiplyX(ExBPY f, ExTP tp)
        {
            var v  = TExV2.Variable();
            var by = ExUtils.VFloat();

            return(bpi => Ex.Block(
                       new[] { v, by },
                       Ex.Assign(v, tp(bpi)),
                       MulAssign(v.x, f(bpi)),
                       v
                       ));
        }
Example #9
0
        /// <summary>
        /// Add a function of input to the y-component of a parametric equation.
        /// </summary>
        /// <param name="f">Function of input</param>
        /// <param name="tp">Parametric equation</param>
        /// <returns></returns>
        public static ExTP AddY(ExBPY f, ExTP tp)
        {
            var v  = TExV2.Variable();
            var by = ExUtils.VFloat();

            return(bpi => Ex.Block(
                       new[] { v, by },
                       Ex.Assign(v, tp(bpi)),
                       ExUtils.AddAssign(v.y, f(bpi)),
                       v
                       ));
        }
Example #10
0
        public static ExCoordF Polar2(ExTP radThetaDeg)
        {
            var rt     = new TExV2();
            var lookup = new TExV2();

            return((c, s, bpi, nrv, fxy) => Ex.Block(new ParameterExpression[] { rt, lookup },
                                                     Ex.Assign(rt, radThetaDeg(bpi)),
                                                     Ex.Assign(lookup, ExM.CosSinDeg(rt.y)),
                                                     fxy(Ex.Subtract(Ex.Multiply(c, lookup.x), Ex.Multiply(s, lookup.y)).Mul(rt.x),
                                                         Ex.Add(Ex.Multiply(s, lookup.x), Ex.Multiply(c, lookup.y)).Mul(rt.x)),
                                                     Expression.Empty()
                                                     ));
        }
Example #11
0
        public static ExCoordF Polar(ExBPY r, ExBPY theta)
        {
            var vr     = ExUtils.VFloat();
            var lookup = new TExV2();

            return((c, s, bpi, nrv, fxy) => Ex.Block(new[] { vr, lookup },
                                                     Ex.Assign(lookup, ExM.CosSinDeg(theta(bpi))),
                                                     Ex.Assign(vr, r(bpi)),
                                                     fxy(Ex.Subtract(Ex.Multiply(c, lookup.x), Ex.Multiply(s, lookup.y)).Mul(vr),
                                                         Ex.Add(Ex.Multiply(s, lookup.x), Ex.Multiply(c, lookup.y)).Mul(vr)),
                                                     Expression.Empty()
                                                     ));
        }
Example #12
0
        /// <summary>
        /// Multiply a unit vector at a given angle from the target function by the magnitude,
        /// and add it to the target function.
        /// </summary>
        /// <param name="angle">Angle offset (degrees)</param>
        /// <param name="magnitude">Magnitude of offset vector</param>
        /// <param name="tp">Target function</param>
        /// <returns></returns>
        public static ExTP AddAtAngle(ExBPY angle, ExBPY magnitude, ExTP tp)
        {
            TExV2 v2     = TExV2.Variable();
            TExV2 v2norm = TExV2.Variable();
            var   mag    = ExUtils.VFloat();

            return(bpi => Ex.Block(new[] { v2, v2norm, mag },
                                   Ex.Assign(v2, tp(bpi)),
                                   Ex.Assign(v2norm, Rotate(angle(bpi), Norm(v2))),
                                   Ex.Assign(mag, magnitude(bpi)),
                                   Ex.Assign(v2norm.x, v2.x.Add(v2norm.x.Mul(mag))),
                                   Ex.Assign(v2norm.y, v2.y.Add(v2norm.y.Mul(mag))),
                                   v2norm
                                   ));
        }
Example #13
0
        public static void TestCylinder()
        {
            var xz = TP3(bpi => XZrY(ExC(3f), ExC(2f), bpi.t, 5f));
            var yz = TP3(bpi => YZrX(ExC(3f), ExC(2f), bpi.t, 5f));
            var xy = TP3(bpi => XYrZ(ExC(3f), ExC(2f), bpi.t, 5f));
            var b  = new ParametricInfo()
            {
                t = 1f
            };
            var c = 2f * Mathf.Cos(b.t * M.TAU / 3f);
            var s = 2f * Mathf.Sin(b.t * M.TAU / 3f);

            VecEq(new Vector3(c, 5f, s), xz(b));
            VecEq(new Vector3(5f, c, s), yz(b));
            VecEq(new Vector3(c, s, 5f), xy(b));

            var f1  = VFloat();
            var f2  = VFloat();
            var f3  = VFloat();
            var f4  = VFloat();
            var v21 = new TExV2();
            var cyl = Ex.Lambda <Func <float, float, float, float, Vector2, Vector3> >(CylinderWrap(f1, f2, f3, f4, v21), f1, f2, f3, f4, v21).Compile();

            VecEq(cyl(2f, M.HPI, M.PI, 0f, new Vector2(1f, 0f)), new Vector3(Mathf.Cos(1f / 2f) * 2f - 2f, 0f, -2f * Mathf.Sin(1f / 2f)));
            VecEq(cyl(2f, M.HPI, M.PI, 0f, new Vector2(1f + 2 * M.PI, 0f)), new Vector3(-4f, 0f, 1f));

            for (float r = 1; r < 3; r += 0.8f)
            {
                for (float ang0 = -1; ang0 < 2; ang0 += 0.8f)
                {
                    for (float maxWrap = 0.5f; maxWrap < 5f; maxWrap += 1.1f)
                    {
                        for (float axis = -2; axis < 5; axis += 0.9f)
                        {
                            for (float x = -3; x < 10; x += 1.3f)
                            {
                                for (float y = -2; y < 3; y += 0.5f)
                                {
                                    var v2 = new Vector2(x, y);
                                    VecEq(cyl(r, ang0, maxWrap, axis, v2), M.CylinderWrap(r, ang0, maxWrap, axis, v2), $"Cyl({r},{ang0},{maxWrap},{axis},<{x},{y}>)");
                                }
                            }
                        }
                    }
                }
            }
        }
Example #14
0
 public static ExTP LSaveNearestEnemy() => b => {
     var key    = b.Ctx.NameWithSuffix("_LSaveNearestEnemyKey");
     var eid_in = ExUtils.V <int?>();
     var eid    = ExUtils.V <int>();
     var loc    = new TExV2();
     return(Ex.Block(new[] { eid_in, eid, loc },
                     eid_in.Is(Ex.Condition(FiringCtx.Contains <int>(b, key),
                                            FiringCtx.GetValue <int>(b, key).As <int?>(),
                                            Ex.Constant(null).As <int?>())
                               ),
                     Ex.IfThenElse(Enemy.findNearestSave.Of(b.loc, eid_in, eid, loc),
                                   FiringCtx.SetValue <int>(b, key, eid),
                                   loc.Is(Ex.Constant(new Vector2(0f, 50f)))
                                   ),
                     loc
                     ));
 };
Example #15
0
 /// <summary>
 /// Derive a V2RV2 from two vectors and a float.
 /// </summary>
 /// <param name="nrot">Nonrotational x,y</param>
 /// <param name="rot">Rotational x,y</param>
 /// <param name="angle">Rotational angle (degrees)</param>
 /// <returns></returns>
 public static trv2 V2V2F(ev2 nrot, ev2 rot, tfloat angle) => EEx.Resolve(nrot, rot, (_nr, _r) => {
     var nr = new TExV2(_nr);
     var r  = new TExV2(_r);
     return(VRV2(nr.x, nr.y, r.x, r.y, angle));
 });
Example #16
0
 /// <summary>
 /// Derive a V2RV2 from a nonrotational vector and a rotational vector3.
 /// </summary>
 /// <param name="nrot">Nonrotational component</param>
 /// <param name="rot">Rotational component (x,y,angle)</param>
 /// <returns></returns>
 public static trv2 V2V3(ev2 nrot, ev3 rot) => EEx.Resolve(nrot, rot, (_nr, _r) => {
     var nr = new TExV2(_nr);
     var r  = new TExV3(_r);
     return(VRV2(nr.x, nr.y, r.x, r.y, r.z));
 });
Example #17
0
 /// <summary>
 /// Return the angle in radians whose tangent is v2.y/v2.x.
 /// </summary>
 public static tfloat ATanR(ev2 f) => EEx.Resolve(f, v2 => {
     var tv2 = new TExV2(v2);
     return(_AtanYX.Of(tv2.y, tv2.x));
 });
Example #18
0
 /// <summary>
 /// Rotate a V2 by a vector containing cosine and sine values counterclockwise.
 /// </summary>
 public static tv2 RotateV2(ev2 cossin, efloat xv, efloat yv) => EEx.Resolve(cossin, (cs) => {
     var _cs = new TExV2(cs);
     return(RotateCS2(_cs.x, _cs.y, xv, yv));
 });
Example #19
0
 /// <summary>
 /// Rotate a V2 by a vector containing cosine and sine values counterclockwise.
 /// </summary>
 public static tv2 RotateV(ev2 cossin, ev2 v2) => EEx.Resolve(cossin, v2, (cs, vec) => {
     var _cs = new TExV2(cs);
     var tv2 = new TExV2(vec);
     return(RotateCS2(_cs.x, _cs.y, tv2.x, tv2.y));
 });
Example #20
0
 /// <summary>
 /// Rotate a V2 by a calculated cosine and sine value counterclockwise.
 /// </summary>
 public static tv2 RotateCS(tfloat cos, tfloat sin, ev2 v2) => EEx.Resolve(v2, vec => {
     var tv2 = new TExV2(vec);
     return(RotateCS2(cos, sin, tv2.x, tv2.y));
 });