/// <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 )); });
/// <summary> /// Derive a Vector2 from a Vector3 by dropping the Z-component. /// </summary> public static ExTP TP(ExTP3 xyz) { var v3 = TExV3.Variable(); return(bpi => Ex.Block(new ParameterExpression[] { v3 }, Ex.Assign(v3, xyz(bpi)), ExUtils.V2(v3.x, v3.y) )); }
/// <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))) )); });
/// <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)); });