Skip to main content

konvert

Konvert implements universal conversion graphs for e.g. coordinate transformations.

At the core, konvert represents types connected by conversions on a graph. Such conversion graphs can be expandend incrementally, because it only requires two connections to connect a new type to the graph, This type can then be freely converted to any other type in the graph, by automatically chaining conversions between existing types.

The automatic chaining requires the conversions to be parameter-free. Conversions with additional parameters are called projections, which konvert also helps you manage.

Points

The moule konvert.points includes a conversion graph for coordinate transformations. As an example consider a set of points in two-dimensional Cartesian coordinates:

from konvert.points import Cartesian2D

line = Cartesian2D(x=[0, 1, 2], y=[0, 1, 2])

This points can be converted to other implented 2D point sets, like Polar and Bipolar, by using the to() method

from konvert.points import Polar, Bipolar

lp = line.to(Polar)
lb = line.to(Bipolar)

It can also be lifted up to its 3D description, l3 = line.to(Cartesian3D). The conversion graph can automatically chain conversions, so in fact, any point in the plane can be hoisted up to any point in three-dimensional space. That means, that points in e.g. polar coordinates, can be hoisted up to Cartesian3D.

p0 = Polar(theta=30 * degrees, r=1.5).to(Cartesian3D)

Points in 3D can be represented using the coordinate representations Cartesian3D, Cylindrical, and Spherical. All Cartesian types have some helper methods for easily manipulating points.

p0 = Cartesian3D(1, 1, 1)
q0 = Cartesian3D(1, 1, 0)

# Create normalized version
p1 = p0.normalized()

# Shift p0 by q0
p0.shift(q0)  

# Rotate around an axis thorugh q0.
p0.rotate(theta=45 * degrees, point=q0)

Helpers

Because the points module work extensively with angles, konvert defines a convenience degrees symbol, which converts values and arrays in degrees to radians,

from konvert.points import degrees

theta = 90 * degrees
# theta is now pi/2

theta = numpy.array([45, 60, 90, 180, 360]) * degrees
# theta is now numpy.array([pi/4, pi/3, pi/2, pi, 2*pi])

Map projections

The points module also contains a set of map projections: Azimuthal, AzimuthalEquidistant, Mercator, Orthographic, Stereographic and Equirectangular. Points are represented on the Sphere, in spherical coordinates, or in Equitorial coordinates (lattitude and longitude).

points = Equitorial([40.12, 50.53] * degrees, [33.16, 44.53] * degrees, r=1)

p0 = points.project(Mercator)
p1 = points.project(Stereographic)
...

The points can be easily plotted using matplotlib and the plot utility on Cartesian2D, p0.to(Cartesian2D).plot().

Extending the conversion graph

It is fairly simple to extend an existing conversion graph and an existing projection collection. Let us extend the points graph with a Skew2D coordinate system. Note the use of numpy to efficiently represent and transform coordinates.

import numpy
from konvert.points import Points

class Skew2D(Points):
    _sig = ('x', 'y', 'theta')

    def __init__(self, x, y, theta):
        """ 
        Skew 2D coordinates. Theta is a scalar denominating the skew angle.
        """
        self.x = numpy.array(x)
        self.y = numpy.array(y)
        self.theta = theta

The Skew2D class can be connected to the konvert.points conversion graph by using the following conversion.

from konvert.points import converters, Conversion

@converters.register()
class Skew2DToCartesian2D(Conversion):
    src = Skew2D
    dst = points.Cartesian2D

    @staticmethod
    def convert(skew):
        return points.Cartesian2D(skew.x + numpy.cos(theta) * skew.y, numpy.sin(theta) * skew.y)

The reverse conversion requires the additional theta parameter and must be implemented as a projection.

from konvert.points import projectors, Projection

@projectors.register()
class Cartesian2DToSkew2D(Projection):
    src = points.Cartesian2D
    dst = Skew2D

    @staticmethod
    def project(cart, theta=np.pi / 2):
        y = cart.y / numpy.sin(theta)
        x = cart.x - numpy.cos(theta) * y
        return Skew2D(x, y, theta)

With these two additions we can convet between Skew2D points and any points type in the graph,

p0 = Skew2D(1, 2, theta=45 * degrees)
p1 = p0.to(Cylindrical)

or the opposite way,

p1 = Cylindrical(theta=30 * degrees, phi=45 * degrees, r=10)
p0 = p1.project(OnPlane).project(Cartesian2DToSkew2D, theta=45 * degrees)

Extensions

The conversion graph has been implemented in the conversions module. It is possible to create additional conversion graphs and register existing or new conversions in those graphs. As an example we may create a colors module, which converts between values in the RGB and HSL color space. For this is example we will not bother with vectorizing the entities, and instead just work with single color entries and use the colorsys module in the python standard library.

import colorsys
from konvert.conversions import Conversion, ConversionGraph

converters = ConversionGraph()

class Color(metaclass=ABCMeta):     
     def to(self, type):
        return convertes.convert(self, type)


class RGB(Color):
    def __init__(self, r, g, b):
        self.r = r
        self.g = g
        self.b = b

class HSL(Color):
    def __init__(self, h, s, l):
        self.h = h
        self.s = s
        self.l = l

converters.register()
class RGBToHSL(Conversion):
    src = RGB
    dst = HSL

    @staticmethod
    def convert(rgb):
        hsl = colorsys.rgb_to_hsl(rgb.r, rgb.g, rgb.b)
        return HSL(*hsl)


converters.register()
class HSLToRGB(Conversion):
  src = RGB
  dst = HSL

  @staticmethod
  def convert(hsl):
      rgb = colorsys.hsl_to_rgb(hsl.h, hsl.s, hsl.l)
      return RGB(*rgb)

We can now write RGB(0.1, 0.3, 0.3).to(HSL) and get the correct result.

If we wanted, we could merge this graph into the points conversion graph, or include part of the points graph in the color conversion graph...

Metadata

Release files for konvert 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for konvert 0.1.0
File Size Uploaded
konvert-0.1.0.tar.gz 12.7 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for konvert 0.1.0
File Interpreter ABI Platform
konvert-0.1.0-py2.py3-none-any.whl Python 2, Python 3 none any Details

Total release size: 26.6 kB

Release files / konvert-0.1.0.tar.gz

Download URL konvert-0.1.0.tar.gz
Size 12.7 kB
Tags Source
SHA-256 checksum
How to use checksums
5498ebb5e47b56ef0d473029a4012c8d49f4bb1fd6dccac12a6234b5eda149a7
BLAKE2b-256 checksum
How to use checksums
fb77dfde7163ed524a42a79048ad1283df8780ceeddace1a63adf21e70ed695c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/1.13.0 pkginfo/1.5.0.1 requests/2.22.0 setuptools/40.8.0 requests-toolbelt/0.9.1 tqdm/4.32.2 CPython/3.7.3

Release files / konvert-0.1.0-py2.py3-none-any.whl

Download URL konvert-0.1.0-py2.py3-none-any.whl
Size 13.8 kB
Tags Python 2 Python 3
SHA-256 checksum
How to use checksums
1c19f54c658f280a2c6135694cb48ad3ce4f8720a7e0f16b0e17ad86e209b532
BLAKE2b-256 checksum
How to use checksums
75b4e0b97ac2875170ed8548ce0d503f5c463bac23a8fdf82d1c393dfc671765
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/1.13.0 pkginfo/1.5.0.1 requests/2.22.0 setuptools/40.8.0 requests-toolbelt/0.9.1 tqdm/4.32.2 CPython/3.7.3

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page