/// <summary> /// Cozzi and Ring method using Newton Raphson from 3D Engine Design for Virtual Globes book /// </summary DVec3 ScaleToGeodeticSurface(DVec3 P) { double beta = 1.0 / Math.Sqrt( (P.x * P.x) * ra2 + (P.y * P.y) * rb2 + (P.z * P.z) * rc2 ); double n = DVec3.length(new DVec3(beta * P.x * ra2, beta * P.y * rb2, beta * P.z * rc2)); double alpha = (1.0 - beta) * (DVec3.length(P) / n); double x2 = P.x * P.x; double y2 = P.y * P.y; double z2 = P.z * P.z; double da = 0.0; double db = 0.0; double dc = 0.0; double s = 0.0; double dSdA = 1.0; do { alpha -= (s / dSdA); da = 1.0 + (alpha * ra2); db = 1.0 + (alpha * rb2); dc = 1.0 + (alpha * rc2); double da2 = da * da; double db2 = db * db; double dc2 = dc * dc; double da3 = da * da2; double db3 = db * db2; double dc3 = dc * dc2; s = x2 / (a2 * da2) + y2 / (b2 * db2) + z2 / (c2 * dc2) - 1.0; dSdA = -2.0 * (x2 / (a4 * da3) + y2 / (b4 * db3) + z2 / (c4 * dc3)); } while (Math.Abs(s) > 1e-10); return(new DVec3(P.x / da, P.y / db, P.z / dc)); }
/// <summary> /// Normalise the vector and return the unit vector pointing in the same direction /// </summary> /// <param name="v"></param> /// <returns></returns> public static DVec3 normalize(DVec3 v) { double mag = DVec3.length(v); return(new DVec3(v.x / mag, v.y / mag, v.z / mag)); }