{"abstract":"Eastings do not shrink toward the poles.","category":"Map projection transforms","checks":8,"contract":"Input [lon, lat, lon0, lat0] degrees; sphere R = 6371000 viewed from infinity above (lon0, lat0). cos c = sin(p0)sin(p) + cos(p0)cos(p)cos(dl); points with cos c < 0 are on the far side and return None. Otherwise x = R cos(p) sin(dl), y = R (cos(p0) sin(p) - sin(p0) cos(p) cos(dl)), rounded to 2 decimals.","evaluation_group":"w2-map-projection-transforms-orthographic-visibility","failed_approach":"Dropping the latitude factor altogether is right only on the equator.","family":"w2-map-projection-transforms-orthographic-visibility-easting-latitude","id":"FA-70196","implementations":{"attempt":{"sha256":"dc338e8109930a1bd120f9fa89478321186ec10462fb8bf8fcb831f2b7a0705d","source":"\"\"\"Failure Map reference implementation. Python standard library only.\"\"\"\nimport json\nimport math\nN = 1\nobservations = []\ndef solve(x):\n    lon, lat, lon0, lat0 = x\n    R = 6371000.0\n    phi, phi0 = math.radians(lat), math.radians(lat0)\n    dl = math.radians(lon - lon0)\n    cosc = math.sin(phi0) * math.sin(phi) + math.cos(phi0) * math.cos(phi) * math.cos(dl)\n    if cosc < 0:\n        return None\n    px = R * math.sin(dl)\n    py = R * (math.cos(phi0) * math.sin(phi) - math.sin(phi0) * math.cos(phi) * math.cos(dl))\n    return [round(px, 2), round(py, 2)]\ndef check(label, actual, expected):\n    observations.append({\"check\": label, \"actual\": actual, \"expected\": expected, \"passed\": actual == expected})\nfixtures = [[('control #0', [104.501, -37.02, 140.0, 40.0], [-2953829.02, -5600456.08]), ('control #1', [-47.135, -1.795, 45.0, -60.0], [-6363453.3, -305228.13]), ('control #2', [-94.306, -16.588, 0.0, 70.0], None), ('control #3', [64.166, 9.956, 45.0, 40.0], [2060140.33, -2966163.09]), ('control #4', [-146.902, -55.084, -100.0, 40.0], None), ('control #5', [-138.834, -74.487, -100.0, 40.0], None), ('control #6', [88.968, 40.467, 140.0, 0.0], [-3768474.08, 4134842.57]), ('control #7', [-48.181, 83.804, -100.0, -60.0], None)], [('control #1', [-47.135, -1.795, 45.0, -60.0], [-6363453.3, -305228.13]), ('control #3', [64.166, 9.956, 45.0, 40.0], [2060140.33, -2966163.09]), ('control #5', [-138.834, -74.487, -100.0, 40.0], None), ('control #6', [88.968, 40.467, 140.0, 0.0], [-3768474.08, 4134842.57]), ('control #7', [-48.181, 83.804, -100.0, -60.0], None), ('control #8', [53.54, -27.151, 140.0, 40.0], None), ('control #9', [201.351, -1.256, 140.0, 0.0], [5589676.0, -139649.64]), ('control #10', [-38.255, 79.909, -100.0, 70.0], [983271.21, 1648730.24])], [('control #3', [64.166, 9.956, 45.0, 40.0], [2060140.33, -2966163.09]), ('control #6', [88.968, 40.467, 140.0, 0.0], [-3768474.08, 4134842.57]), ('control #8', [53.54, -27.151, 140.0, 40.0], None), ('control #9', [201.351, -1.256, 140.0, 0.0], [5589676.0, -139649.64]), ('control #10', [-38.255, 79.909, -100.0, 70.0], [983271.21, 1648730.24]), ('control #11', [-57.222, 56.396, -100.0, 0.0], [2394735.5, 5306295.07]), ('control #12', [31.276, 31.413, 140.0, -60.0], None), ('control #13', [189.902, -48.732, 140.0, 40.0], None)], [('control #6', [88.968, 40.467, 140.0, 0.0], [-3768474.08, 4134842.57]), ('control #9', [201.351, -1.256, 140.0, 0.0], [5589676.0, -139649.64]), ('control #11', [-57.222, 56.396, -100.0, 0.0], [2394735.5, 5306295.07]), ('control #12', [31.276, 31.413, 140.0, -60.0], None), ('control #13', [189.902, -48.732, 140.0, 40.0], None), ('control #14', [-112.053, 44.567, 0.0, 70.0], [-4206814.33, 3130521.2]), ('control #15', [191.466, 36.244, 140.0, 0.0], [4019339.93, 3766695.71]), ('control #16', [-43.54, 73.198, 45.0, -35.0], None)], [('control #9', [201.351, -1.256, 140.0, 0.0], [5589676.0, -139649.64]), ('control #10', [-38.255, 79.909, -100.0, 70.0], [983271.21, 1648730.24]), ('control #14', [-112.053, 44.567, 0.0, 70.0], [-4206814.33, 3130521.2]), ('control #15', [191.466, 36.244, 140.0, 0.0], [4019339.93, 3766695.71]), ('control #16', [-43.54, 73.198, 45.0, -35.0], None), ('control #17', [86.105, 83.034, 140.0, -60.0], None), ('control #18', [-91.691, 21.145, 0.0, 0.0], None), ('control #19', [31.28, -77.337, 45.0, -35.0], [-331248.01, -4313662.3])]]\nfor label, args, expected in fixtures[N-1]:\n    check(label, solve(args), expected)\nprint(json.dumps({\"observations\": observations, \"passed\": all(x[\"passed\"] for x in observations)}, ensure_ascii=False))\nraise SystemExit(0 if all(x[\"passed\"] for x in observations) else 1)\n"},"broken":{"sha256":"2c76ec22f7d7405d912fd50fc6717bff66ee06111f26fead312ef48b33ee8684","source":"\"\"\"Failure Map reference implementation. Python standard library only.\"\"\"\nimport json\nimport math\nN = 1\nobservations = []\ndef solve(x):\n    lon, lat, lon0, lat0 = x\n    R = 6371000.0\n    phi, phi0 = math.radians(lat), math.radians(lat0)\n    dl = math.radians(lon - lon0)\n    cosc = math.sin(phi0) * math.sin(phi) + math.cos(phi0) * math.cos(phi) * math.cos(dl)\n    if cosc < 0:\n        return None\n    px = R * math.cos(phi0) * math.sin(dl)\n    py = R * (math.cos(phi0) * math.sin(phi) - math.sin(phi0) * math.cos(phi) * math.cos(dl))\n    return [round(px, 2), round(py, 2)]\ndef check(label, actual, expected):\n    observations.append({\"check\": label, \"actual\": actual, \"expected\": expected, \"passed\": actual == expected})\nfixtures = [[('control #0', [104.501, -37.02, 140.0, 40.0], [-2953829.02, -5600456.08]), ('control #1', [-47.135, -1.795, 45.0, -60.0], [-6363453.3, -305228.13]), ('control #2', [-94.306, -16.588, 0.0, 70.0], None), ('control #3', [64.166, 9.956, 45.0, 40.0], [2060140.33, -2966163.09]), ('control #4', [-146.902, -55.084, -100.0, 40.0], None), ('control #5', [-138.834, -74.487, -100.0, 40.0], None), ('control #6', [88.968, 40.467, 140.0, 0.0], [-3768474.08, 4134842.57]), ('control #7', [-48.181, 83.804, -100.0, -60.0], None)], [('control #1', [-47.135, -1.795, 45.0, -60.0], [-6363453.3, -305228.13]), ('control #3', [64.166, 9.956, 45.0, 40.0], [2060140.33, -2966163.09]), ('control #5', [-138.834, -74.487, -100.0, 40.0], None), ('control #6', [88.968, 40.467, 140.0, 0.0], [-3768474.08, 4134842.57]), ('control #7', [-48.181, 83.804, -100.0, -60.0], None), ('control #8', [53.54, -27.151, 140.0, 40.0], None), ('control #9', [201.351, -1.256, 140.0, 0.0], [5589676.0, -139649.64]), ('control #10', [-38.255, 79.909, -100.0, 70.0], [983271.21, 1648730.24])], [('control #3', [64.166, 9.956, 45.0, 40.0], [2060140.33, -2966163.09]), ('control #6', [88.968, 40.467, 140.0, 0.0], [-3768474.08, 4134842.57]), ('control #8', [53.54, -27.151, 140.0, 40.0], None), ('control #9', [201.351, -1.256, 140.0, 0.0], [5589676.0, -139649.64]), ('control #10', [-38.255, 79.909, -100.0, 70.0], [983271.21, 1648730.24]), ('control #11', [-57.222, 56.396, -100.0, 0.0], [2394735.5, 5306295.07]), ('control #12', [31.276, 31.413, 140.0, -60.0], None), ('control #13', [189.902, -48.732, 140.0, 40.0], None)], [('control #6', [88.968, 40.467, 140.0, 0.0], [-3768474.08, 4134842.57]), ('control #9', [201.351, -1.256, 140.0, 0.0], [5589676.0, -139649.64]), ('control #11', [-57.222, 56.396, -100.0, 0.0], [2394735.5, 5306295.07]), ('control #12', [31.276, 31.413, 140.0, -60.0], None), ('control #13', [189.902, -48.732, 140.0, 40.0], None), ('control #14', [-112.053, 44.567, 0.0, 70.0], [-4206814.33, 3130521.2]), ('control #15', [191.466, 36.244, 140.0, 0.0], [4019339.93, 3766695.71]), ('control #16', [-43.54, 73.198, 45.0, -35.0], None)], [('control #9', [201.351, -1.256, 140.0, 0.0], [5589676.0, -139649.64]), ('control #10', [-38.255, 79.909, -100.0, 70.0], [983271.21, 1648730.24]), ('control #14', [-112.053, 44.567, 0.0, 70.0], [-4206814.33, 3130521.2]), ('control #15', [191.466, 36.244, 140.0, 0.0], [4019339.93, 3766695.71]), ('control #16', [-43.54, 73.198, 45.0, -35.0], None), ('control #17', [86.105, 83.034, 140.0, -60.0], None), ('control #18', [-91.691, 21.145, 0.0, 0.0], None), ('control #19', [31.28, -77.337, 45.0, -35.0], [-331248.01, -4313662.3])]]\nfor label, args, expected in fixtures[N-1]:\n    check(label, solve(args), expected)\nprint(json.dumps({\"observations\": observations, \"passed\": all(x[\"passed\"] for x in observations)}, ensure_ascii=False))\nraise SystemExit(0 if all(x[\"passed\"] for x in observations) else 1)\n"},"fixed":{"sha256":"161c1af54c0ff96fb4d72bb64710070ee81cb1c3d67511ff345992ae37cf663d","source":"\"\"\"Failure Map reference implementation. Python standard library only.\"\"\"\nimport json\nimport math\nN = 1\nobservations = []\ndef solve(x):\n    lon, lat, lon0, lat0 = x\n    R = 6371000.0\n    phi, phi0 = math.radians(lat), math.radians(lat0)\n    dl = math.radians(lon - lon0)\n    cosc = math.sin(phi0) * math.sin(phi) + math.cos(phi0) * math.cos(phi) * math.cos(dl)\n    if cosc < 0:\n        return None\n    px = R * math.cos(phi) * math.sin(dl)\n    py = R * (math.cos(phi0) * math.sin(phi) - math.sin(phi0) * math.cos(phi) * math.cos(dl))\n    return [round(px, 2), round(py, 2)]\ndef check(label, actual, expected):\n    observations.append({\"check\": label, \"actual\": actual, \"expected\": expected, \"passed\": actual == expected})\nfixtures = [[('control #0', [104.501, -37.02, 140.0, 40.0], [-2953829.02, -5600456.08]), ('control #1', [-47.135, -1.795, 45.0, -60.0], [-6363453.3, -305228.13]), ('control #2', [-94.306, -16.588, 0.0, 70.0], None), ('control #3', [64.166, 9.956, 45.0, 40.0], [2060140.33, -2966163.09]), ('control #4', [-146.902, -55.084, -100.0, 40.0], None), ('control #5', [-138.834, -74.487, -100.0, 40.0], None), ('control #6', [88.968, 40.467, 140.0, 0.0], [-3768474.08, 4134842.57]), ('control #7', [-48.181, 83.804, -100.0, -60.0], None)], [('control #1', [-47.135, -1.795, 45.0, -60.0], [-6363453.3, -305228.13]), ('control #3', [64.166, 9.956, 45.0, 40.0], [2060140.33, -2966163.09]), ('control #5', [-138.834, -74.487, -100.0, 40.0], None), ('control #6', [88.968, 40.467, 140.0, 0.0], [-3768474.08, 4134842.57]), ('control #7', [-48.181, 83.804, -100.0, -60.0], None), ('control #8', [53.54, -27.151, 140.0, 40.0], None), ('control #9', [201.351, -1.256, 140.0, 0.0], [5589676.0, -139649.64]), ('control #10', [-38.255, 79.909, -100.0, 70.0], [983271.21, 1648730.24])], [('control #3', [64.166, 9.956, 45.0, 40.0], [2060140.33, -2966163.09]), ('control #6', [88.968, 40.467, 140.0, 0.0], [-3768474.08, 4134842.57]), ('control #8', [53.54, -27.151, 140.0, 40.0], None), ('control #9', [201.351, -1.256, 140.0, 0.0], [5589676.0, -139649.64]), ('control #10', [-38.255, 79.909, -100.0, 70.0], [983271.21, 1648730.24]), ('control #11', [-57.222, 56.396, -100.0, 0.0], [2394735.5, 5306295.07]), ('control #12', [31.276, 31.413, 140.0, -60.0], None), ('control #13', [189.902, -48.732, 140.0, 40.0], None)], [('control #6', [88.968, 40.467, 140.0, 0.0], [-3768474.08, 4134842.57]), ('control #9', [201.351, -1.256, 140.0, 0.0], [5589676.0, -139649.64]), ('control #11', [-57.222, 56.396, -100.0, 0.0], [2394735.5, 5306295.07]), ('control #12', [31.276, 31.413, 140.0, -60.0], None), ('control #13', [189.902, -48.732, 140.0, 40.0], None), ('control #14', [-112.053, 44.567, 0.0, 70.0], [-4206814.33, 3130521.2]), ('control #15', [191.466, 36.244, 140.0, 0.0], [4019339.93, 3766695.71]), ('control #16', [-43.54, 73.198, 45.0, -35.0], None)], [('control #9', [201.351, -1.256, 140.0, 0.0], [5589676.0, -139649.64]), ('control #10', [-38.255, 79.909, -100.0, 70.0], [983271.21, 1648730.24]), ('control #14', [-112.053, 44.567, 0.0, 70.0], [-4206814.33, 3130521.2]), ('control #15', [191.466, 36.244, 140.0, 0.0], [4019339.93, 3766695.71]), ('control #16', [-43.54, 73.198, 45.0, -35.0], None), ('control #17', [86.105, 83.034, 140.0, -60.0], None), ('control #18', [-91.691, 21.145, 0.0, 0.0], None), ('control #19', [31.28, -77.337, 45.0, -35.0], [-331248.01, -4313662.3])]]\nfor label, args, expected in fixtures[N-1]:\n    check(label, solve(args), expected)\nprint(json.dumps({\"observations\": observations, \"passed\": all(x[\"passed\"] for x in observations)}, ensure_ascii=False))\nraise SystemExit(0 if all(x[\"passed\"] for x in observations) else 1)\n"}},"limitations":"Stipulated deterministic toy contract on a bounded input domain; results are rounded as stated and no conformance with any published standard or library is claimed. This reproducer isolates one failure mechanism. Results cover the supplied fixtures. Variants within a family share a test contract and should remain grouped when constructing evaluation splits. Related mechanisms with a shared evaluation_group must also remain together; these controlled models are not independent production incidents.","method":"Deterministic executable model with adversarial boundary fixtures.","provenance":{"created_by":"Failure Map","dependencies":"Python standard library","family":"w2-map-projection-transforms-orthographic-visibility-easting-latitude","generated_at":"2026-09-29T14:48:18.338911+00:00","license":"CC0-1.0","python":"3.12.14","seed":1,"split":"open-access"},"relevance":"Globe widgets and inset locator maps draw only the visible hemisphere; wrong culling shows features through the planet.","repair":"At the easting latitude step restore `px = R * math.cos(phi) * math.sin(dl)`, leaving the rest of the model unchanged.","root_cause":"The easting uses the view-centre latitude instead of the point latitude.","sha256":"07732ee2505b97a76c37f7cc0538124c44f63f59991a5168b91e321dba2187df","title":"Orthographic globe view with back-side culling: easting latitude · case 01","variant":1,"variant_policy":"Five numbered records share a model and may reuse boundary fixtures.","verification":{"attempt":{"elapsed_ms":40.685,"exit_code":1,"observations":[{"actual":[-3699568.0,-5600456.08],"check":"control #0","expected":[-2953829.02,-5600456.08],"passed":false},{"actual":[-6366577.4,-305228.13],"check":"control #1","expected":[-6363453.3,-305228.13],"passed":false},{"actual":null,"check":"control #2","expected":null,"passed":true},{"actual":[2091638.7,-2966163.09],"check":"control #3","expected":[2060140.33,-2966163.09],"passed":false},{"actual":null,"check":"control #4","expected":null,"passed":true},{"actual":null,"check":"control #5","expected":null,"passed":true},{"actual":[-4953435.42,4134842.57],"check":"control #6","expected":[-3768474.08,4134842.57],"passed":false},{"actual":null,"check":"control #7","expected":null,"passed":true}],"passed":false,"stderr":"","stdout":"{\"observations\": [{\"check\": \"control #0\", \"actual\": [-3699568.0, -5600456.08], \"expected\": [-2953829.02, -5600456.08], \"passed\": false}, {\"check\": \"control #1\", \"actual\": [-6366577.4, -305228.13], \"expected\": [-6363453.3, -305228.13], \"passed\": false}, {\"check\": \"control #2\", \"actual\": null, \"expected\": null, \"passed\": true}, {\"check\": \"control #3\", \"actual\": [2091638.7, -2966163.09], \"expected\": [2060140.33, -2966163.09], \"passed\": false}, {\"check\": \"control #4\", \"actual\": null, \"expected\": null, \"passed\": true}, {\"check\": \"control #5\", \"actual\": null, \"expected\": null, \"passed\": true}, {\"check\": \"control #6\", \"actual\": [-4953435.42, 4134842.57], \"expected\": [-3768474.08, 4134842.57], \"passed\": false}, {\"check\": \"control #7\", \"actual\": null, \"expected\": null, \"passed\": true}], \"passed\": false}\n"},"broken":{"elapsed_ms":41.283,"exit_code":1,"observations":[{"actual":[-2834033.51,-5600456.08],"check":"control #0","expected":[-2953829.02,-5600456.08],"passed":false},{"actual":[-3183288.7,-305228.13],"check":"control #1","expected":[-6363453.3,-305228.13],"passed":false},{"actual":null,"check":"control #2","expected":null,"passed":true},{"actual":[1602288.2,-2966163.09],"check":"control #3","expected":[2060140.33,-2966163.09],"passed":false},{"actual":null,"check":"control #4","expected":null,"passed":true},{"actual":null,"check":"control #5","expected":null,"passed":true},{"actual":[-4953435.42,4134842.57],"check":"control #6","expected":[-3768474.08,4134842.57],"passed":false},{"actual":null,"check":"control #7","expected":null,"passed":true}],"passed":false,"stderr":"","stdout":"{\"observations\": [{\"check\": \"control #0\", \"actual\": [-2834033.51, -5600456.08], \"expected\": [-2953829.02, -5600456.08], \"passed\": false}, {\"check\": \"control #1\", \"actual\": [-3183288.7, -305228.13], \"expected\": [-6363453.3, -305228.13], \"passed\": false}, {\"check\": \"control #2\", \"actual\": null, \"expected\": null, \"passed\": true}, {\"check\": \"control #3\", \"actual\": [1602288.2, -2966163.09], \"expected\": [2060140.33, -2966163.09], \"passed\": false}, {\"check\": \"control #4\", \"actual\": null, \"expected\": null, \"passed\": true}, {\"check\": \"control #5\", \"actual\": null, \"expected\": null, \"passed\": true}, {\"check\": \"control #6\", \"actual\": [-4953435.42, 4134842.57], \"expected\": [-3768474.08, 4134842.57], \"passed\": false}, {\"check\": \"control #7\", \"actual\": null, \"expected\": null, \"passed\": true}], \"passed\": false}\n"},"fixed":{"elapsed_ms":37.963,"exit_code":0,"observations":[{"actual":[-2953829.02,-5600456.08],"check":"control #0","expected":[-2953829.02,-5600456.08],"passed":true},{"actual":[-6363453.3,-305228.13],"check":"control #1","expected":[-6363453.3,-305228.13],"passed":true},{"actual":null,"check":"control #2","expected":null,"passed":true},{"actual":[2060140.33,-2966163.09],"check":"control #3","expected":[2060140.33,-2966163.09],"passed":true},{"actual":null,"check":"control #4","expected":null,"passed":true},{"actual":null,"check":"control #5","expected":null,"passed":true},{"actual":[-3768474.08,4134842.57],"check":"control #6","expected":[-3768474.08,4134842.57],"passed":true},{"actual":null,"check":"control #7","expected":null,"passed":true}],"passed":true,"stderr":"","stdout":"{\"observations\": [{\"check\": \"control #0\", \"actual\": [-2953829.02, -5600456.08], \"expected\": [-2953829.02, -5600456.08], \"passed\": true}, {\"check\": \"control #1\", \"actual\": [-6363453.3, -305228.13], \"expected\": [-6363453.3, -305228.13], \"passed\": true}, {\"check\": \"control #2\", \"actual\": null, \"expected\": null, \"passed\": true}, {\"check\": \"control #3\", \"actual\": [2060140.33, -2966163.09], \"expected\": [2060140.33, -2966163.09], \"passed\": true}, {\"check\": \"control #4\", \"actual\": null, \"expected\": null, \"passed\": true}, {\"check\": \"control #5\", \"actual\": null, \"expected\": null, \"passed\": true}, {\"check\": \"control #6\", \"actual\": [-3768474.08, 4134842.57], \"expected\": [-3768474.08, 4134842.57], \"passed\": true}, {\"check\": \"control #7\", \"actual\": null, \"expected\": null, \"passed\": true}], \"passed\": true}\n"}},"verified":true,"visibility":"public"}