bool FindDirections(double u, double v, out Vector3d dir1, out Vector3d dir2, out Vector3d refA1, out Vector3d refA2) { RefSurface.Evaluate(u, v, 1, out var _, out var refDerivatives); refA1 = refDerivatives[0]; refA2 = refDerivatives[1]; ActSurface.Evaluate(u, v, 1, out var _, out var actDerivatives); var actA1 = actDerivatives[0]; var actA2 = actDerivatives[1]; var e = default(Vector3d); e[0] = actA1 * refA1 - refA1.SquareLength; e[1] = actA2 * refA2 - refA2.SquareLength; e[2] = 0.5 * (actA1 * refA2 + actA2 * refA1) - refA1 * refA2; e.Transform(TransformToLocalCartesian(refA1, refA2)); e.Transform(Material); var tmp = Math.Sqrt(Math.Pow(e[0] - e[1], 2) + 4 * Math.Pow(e[2], 2)); var n1 = 0.5 * (e[0] + e[1] + tmp); var n2 = 0.5 * (e[0] + e[1] - tmp); if (n1 * n2 < 0) { dir1 = Vector3d.Unset; dir2 = Vector3d.Unset; return(false); } var normal = Vector3d.CrossProduct(refA1, refA2); if (Math.Abs(e[2]) < 1e-8) { dir1 = refA1 / refA1.Length; } else { var alpha = Math.Atan2(2 * e[2], e[0] - e[1]) / 2; dir1 = refA1 / refA1.Length; dir1.Rotate(alpha, normal); } dir2 = dir1; var angle = Math.Atan(Math.Sqrt(n2 / n1)); dir1.Rotate(angle, normal); dir2.Rotate(-angle, normal); return(true); }
bool FindDirections(double u, double v, out Vector3d dir1, out Vector3d dir2, out Vector3d refA1, out Vector3d refA2) { RefSurface.Evaluate(u, v, 1, out var _, out var refDerivatives); refA1 = refDerivatives[0]; refA2 = refDerivatives[1]; ActSurface.Evaluate(u, v, 1, out var _, out var actDerivatives); var actA1 = actDerivatives[0]; var actA2 = actDerivatives[1]; var e = default(Vector3d); e[0] = actA1 * refA1 - refA1.SquareLength; e[1] = actA2 * refA2 - refA2.SquareLength; e[2] = 0.5 * (actA1 * refA2 + actA2 * refA1) - refA1 * refA2; e.Transform(TransformToLocalCartesian(refA1, refA2)); e.Transform(Material); var normal = Vector3d.CrossProduct(refA1, refA2); if (Math.Abs(e[2]) < 1e-8) { dir1 = refA1 / refA1.Length; } else { var alpha = Math.Atan2(2 * e[2], e[0] - e[1]) / 2; dir1 = refA1 / refA1.Length; dir1.Rotate(alpha, normal); } dir2 = dir1; dir2.Rotate(Math.PI / 2, normal); return(true); }