Source code for src.tools.coordinates

"""Tools for performing vector and coordinate conversions."""

import math

_CONV = 180.0/math.pi

[docs]def sphericalToCartesian(magnitude, azimuthal, polar): """Convert a vector from spherical to Cartesian coordinates. Parameters ---------- magnitude : float The magnitude of the vector. azimuthal : float The angle in degrees of the vector, measured downward from the positive z-axis. polar : float The angle in degrees of the vector, measured counter-clockwise from the positive x-axis. Returns ------- float The x-coordinate of the vector. float The y-coordinate of the vector. float THe z-coordinate of the vector. """ azimuthal = azimuthal*math.pi/180.0 polar = polar*math.pi/180.0 xval = magnitude * math.sin(azimuthal) * math.cos(polar) yval = magnitude * math.sin(azimuthal) * math.sin(polar) zval = magnitude * math.cos(azimuthal) return [xval, yval, zval]
[docs]def cartesianToSpherical(xComp, yComp, zComp, negateMagnitude=False, tolerance=1E-10): """Convert a vector from Cartesian to spherical coordinates. Parameters ---------- xComp : float The x-component of the vector. yComp : float The y-component of the vector. zComp : float The z-component of the vector. negateMagnitude : bool Whether to prefer a negative value of the magnitude, accounting for the reversed direction by adding 180 degrees to the azimuthal angle. tolerance : float How maximum absolute value a number may have and still be treated as zero. Returns ------- float The magnitude of the vector. float The azimuthal angle in degrees. float The polar angle in degrees. """ ans = None mag = math.sqrt(xComp*xComp + yComp*yComp + zComp*zComp) if mag < tolerance: ans = [0.0, 0.0, 0.0] proj2 = xComp*xComp + yComp*yComp if ans is None and proj2 < tolerance: ans = [mag, 0.0, 0.0] elif abs(zComp) < tolerance: if abs(xComp) < tolerance: ans = [mag, 90.0, 90.0] if abs(yComp) < tolerance: ans = [mag, 90.0, 0.0] else: ans = [mag, 90.0, math.acos(xComp/mag)*_CONV] else: azimuth = math.acos(zComp/mag) ans = [mag, azimuth*_CONV, math.acos(xComp/(mag*math.sin(azimuth)))*_CONV] if negateMagnitude: ans = [-1*ans[0], 180+ans[1], ans[2]] return ans
[docs]def equalEnough(numA, numB, tol=0.000001): """Return whether two numbers are close enough to be considered equal.""" return math.fabs(numA - numB) <= tol
[docs]def clean(point): """Return a float with digits farther out than fifth place truncated.""" tmp = [] for pts in point: tmp.append(float('%.5f' % pts)) return (tmp[0], tmp[1], tmp[2])