public void TestDotProduct() { UnitCartesian first = new UnitCartesian(1.0, 3.0, -2.0); UnitCartesian second = new UnitCartesian(4.0, -2.0, -1.0); Assert.AreEqual(0, first.Dot(second), Constants.Epsilon15); Assert.AreEqual(0, second.Dot(first), Constants.Epsilon15); Cartesian result = new Cartesian(4.0, -2.0, -1.0); Assert.AreEqual(0, first.Dot(result)); }
/// <summary> /// 单圈Lambert方程求解(转移角度:[0,2*pi)) /// <para>Gm,r,v,tof单位要一致</para> /// <para>根据初始位置速度r1,v1确定转移轨道的方向,进而确定转移轨道的角度theta!</para> /// <para>程序内部调用采用R.H.Gooding 方法的子程序VLamb</para> /// </summary> /// <param name="Gm">引力常数</param> /// <param name="r1">初始位置矢量</param> /// <param name="v1">初始速度矢量</param> /// <param name="r2">末态位置矢量</param> /// <param name="v2">末态速度矢量</param> /// <param name="tof">转移时间</param> /// <param name="dv1">初始速度增量</param> /// <param name="dv2">末态速度增量</param> public static void Lambert_RhGooding(double Gm, Cartesian r1, Cartesian v1, Cartesian r2, Cartesian v2, double tof, out Cartesian dv1, out Cartesian dv2) { double cos_theta = r1.Dot(r2) / r1.Magnitude / r2.Magnitude; // 由初始位置速度矢量计算角动量方向,并计算转移轨道的的法向方向 UnitCartesian h1 = r1.Cross(v1).Normalize(); Cartesian h12 = r1.Cross(r2); // 若始末位置在同一直线上,则令转移轨道的角动量方向同初始角动量方向相同 if (h12.Magnitude / r1.Magnitude / r2.Magnitude < 1e-10) { h12 = h1; } else { h12 = h12.Normalize(); } // 根据初始角动量方向和始末位置的叉乘方向,计算转移轨道的转移角度theta,使其在[0,2*pi]范围内 // 也即确定转移轨道的角动量与初始角动量方向一致 double test_dir = h1.Dot(h12); double theta = Math.Acos(cos_theta); if (test_dir < 0) { theta = 2.0 * Math.PI - theta; h12 = -h12; } // 求解Lambert方程 int n; double vr11, vt11, vr12, vt12, vr21, vt21, vr22, vt22; VLAMB(Gm, r1.Magnitude, r2.Magnitude, theta, tof, out n, out vr11, out vt11, out vr12, out vt12, out vr21, out vt21, out vr22, out vt22); if (n != 1) { throw new Exception("单圈Lambert方程求解出错,解个数应为1!"); } // 确定始末位置的单位速度方向(垂直于位置矢径) UnitCartesian vi_ = h12.Cross(r1).Normalize(); UnitCartesian vf_ = h12.Cross(r2).Normalize(); // 解 dv1 = vt11 * vi_ + vr11 * r1.Normalize() - v1; // dv2 = vt12 * vf_ + vr12 * r2.Normalize() - v2; // dv1 = vt11 * vi_ + vr11 * r1.Normalize(); dv2 = vt12 * vf_ + vr12 * r2.Normalize(); }