public static Vector3 LeftIntersection(this IArc arc, Sweepline sweepline) { var p = arc.LeftNeighbour.Position; var q = arc.Site.Position; var Z = sweepline.Z; if (Vector.AlmostEqual(p, q)) { return(AngleUtilities.EquatorialDirection(p)); } if (Number.AlmostEqual(Z, p.Z) && Number.AlmostEqual(Z, q.Z)) { return(AngleUtilities.EquatorialMidpoint(p, q)); } var A = p.X * (Z - q.Z) - q.X * (Z - p.Z); var B = p.Y * (Z - q.Z) - q.Y * (Z - p.Z); var C = (p.Z - q.Z) * Math.Sign(sweepline.Priority) * Math.Sqrt(1 - Z * Z); var A2PlusB2MinusC2 = Math.Max(A * A + B * B - C * C, 0); var x = (A * C + B * Math.Sqrt(A2PlusB2MinusC2)) / (A * A + B * B); var y = (B * C - A * Math.Sqrt(A2PlusB2MinusC2)) / (A * A + B * B); return(new Vector3(x, y, 0)); }
public static Vector3 PointAt(Vector3 focus, Vector3 vector, Sweepline sweepline) { var p = focus; var n = AngleUtilities.EquatorialDirection(vector); var Z = sweepline.Z; if (Number.AlmostEqual(p.Z, Z) && Vector.AlmostEqual(AngleUtilities.EquatorialDirection(p), n)) { return(p); } if (Number.AlmostEqual(p.Z, Z)) { return(new Vector3(0, 0, 1)); } var tanOfColatitude = (Z - p.Z) / (p.ScalarMultiply(n) - Math.Sign(sweepline.Priority) * Math.Sqrt(1 - Z * Z)); var x = n.X * Math.Abs(tanOfColatitude / Math.Sqrt(1 + tanOfColatitude * tanOfColatitude)); var y = n.Y * Math.Abs(tanOfColatitude / Math.Sqrt(1 + tanOfColatitude * tanOfColatitude)); var z = Math.Sign(tanOfColatitude) / Math.Sqrt(1 + tanOfColatitude * tanOfColatitude); return(new Vector3(x, y, z)); }