Via @tjlang, "You had a bug in the attached script, which caused the projections to fail in the southern hemisphere (everything was erroneously rotated 180 degrees around the projection center). The specific issue was the definition of localy in the TangentPlaneCartesianSystem class. I fixed it with a simple if-then statement (see lines 277-280) and now the projections essentially match what Basemap does."
localy = dot(P, northCenterECEF[:,newaxis] )
if ctrLat >= 0:
localy = -localy / norm(localy) # negation gets x and y pointing in the right direction
else:
localy = localy / norm(localy) # No negation in southern hemisphere
Via @tjlang, "You had a bug in the attached script, which caused the projections to fail in the southern hemisphere (everything was erroneously rotated 180 degrees around the projection center). The specific issue was the definition of localy in the TangentPlaneCartesianSystem class. I fixed it with a simple if-then statement (see lines 277-280) and now the projections essentially match what Basemap does."