1

I am writing python code that uses Cartesian methods and trigonometry to move, resize and rotate shapes on a plane, and to track and report these shenanigans.

It will not be computationally intensive - typically a user-instruction would lead to a single move/rotate/resize operation.

I would like to know what is the most appropriate variable type to use for the shape coordinate and dimension pairs, and why.

The types I have considered are

x = 10
y = -15

list_coords = [x, y]
tuple_coords = (x, y)

import numpy as np
array_coords = np.array([x, y])

import cmath as cm
complex_coords = x + j*y

If you know of other good options, please also tell me about it.

Thanks!

levraininjaneer
  • 1,157
  • 2
  • 18
  • 38

2 Answers2

2

Short answer, Tuple

From "What's the difference between lists and tuples?" thread,

Tuples are heterogeneous data structures (i.e., their entries have different meanings), while lists are homogeneous sequences.

Tuples have structure, lists have order. Using this distinction makes code more explicit and understandable.

As tuples consists of heterogeneous entities, instead of an order of homogeius entities, tuple is a great way to deal with coordinate systems. Also the coordinate operations like addition & substraction is fairly simple with tuples.

Example:

import operator
a = (1,2,3)
b = (5,6,7)
c = tuple(map(operator.add, a, b))

Also tuple is immutable. This seems inconvenient at first, but using immutable data like this in functional programming techniques has substantial advantages.

nipunasudha
  • 2,427
  • 2
  • 21
  • 46
  • 1
    Thanks, my intuition was also telling me that a tuple sounds right, but I was (a) ignorant of the map/operator -like stuff you can do and (b) as you say, a bit put off by the fact that I can’t do tuple_coord[0] = 12. But I am starting to think that this inconvenience kind-of reflects the nature of coordinates in that they are related, and if an operation could change the one it could almost always potentially change the other. – levraininjaneer Oct 16 '17 at 13:39
0

Lots of options. Consider a polygon. In most GIS programs the first and last point are repeated to form closure, as in the polygon 'a' below using numpy

import numpy as np
a = np.array([[0., 0.], [0., 1000.], [1000., 1000.], [1000., 0.], [ 0., 0.]])
a
array([[    0.,     0.],
       [    0.,  1000.],
       [ 1000.,  1000.],
       [ 1000.,     0.],
       [    0.,     0.]])

The dtype for the above is a simple float64. You can convert it to a structured array by assigning an appropriate data type as follows:

b = np.zeros((a.shape[0]), dtype=[('Xs', '<f8'), ('Ys', '<f8')])
b['Xs'] = a[:,0]; b['Ys'] = a[:,1]
b 
array([(0.0, 0.0), (0.0, 1000.0), (1000.0, 1000.0), (1000.0, 0.0), (0.0, 0.0)], 
      dtype=[('Xs', '<f8'), ('Ys', '<f8')])

You can go one step further and produce a 'recarray' if you prefer to use object.property notation with your objects.

c = b.view(np.recarray)

With the standard array with the uniform dtype, you can access the X values using slicing, with the structured array you add the ability to slice by column name, and finally, with the recarray you can use object.property notation.

args = [a[:,0], b['Xs'], c.Xs]  # ---- get the X coordinates
print('{}\n{}\n{}'.format(*args))
[    0.     0.  1000.  1000.     0.]
[    0.     0.  1000.  1000.     0.]
[    0.     0.  1000.  1000.     0.]

You can get a polygon centroid from the unique points in the array..

np.mean(a[:-1], axis=0)
array([ 500.,  500.])

In fact it is easy to get unique points from an array given the right form

np.unique(b)

array([(0.0, 0.0), (0.0, 1000.0), (1000.0, 0.0), (1000.0, 1000.0)], 
      dtype=[('Xs', '<f8'), ('Ys', '<f8')])

You may have noticed that I have been switching back and forth between conventional ndarrays, those with named fields and recarrays. That is because you can use the same data and just view it in different ways if you like.

NaN
  • 2,212
  • 2
  • 18
  • 23