# Path: pymicro/view/vol_utils.py
# def compute_affine_transform(fixed, moving):
#     """Compute the affine transform by point set registration.
# 
#     The affine transform is the composition of a translation and a linear map.
#     The two ordered lists of points must be of the same length larger or equal to 3.
#     The order of the points in the two list must match.
#     
#     The 2D affine transform :math:`\mathbf{A}` has 6 parameters (2 for the translation and 4 for the linear transform).
#     The best estimate of :math:`\mathbf{A}` can be computed using at least 3 pairs of matching points. Adding more 
#     pair of points will improve the quality of the estimate. The matching pairs are usually obtained by selecting 
#     unique features in both images and measuring their coordinates.
# 
#     :param list fixed: a list of the reference points.
#     :param list moving: a list of the moving points to register on the fixed point.
#     :returns translation, linear_map: the computed translation and linear map affine transform. 
# 
#     Thanks to Will Lenthe for helping with this code.
#     """
#     assert len(fixed) == len(moving)
#     assert len(fixed) >= 3
#     fixed_centroid = np.average(fixed, 0)
#     moving_centroid = np.average(moving, 0)
#     # offset every point by the center of mass of all the points in the set
#     fixed_from_centroid = fixed - fixed_centroid
#     moving_from_centroid = moving - moving_centroid
#     covariance = moving_from_centroid.T.dot(fixed_from_centroid)
#     variance = moving_from_centroid.T.dot(moving_from_centroid)
#     # compute the full affine transform: translation + linear map
#     linear_map = np.linalg.inv(variance).dot(covariance).T
#     translation = fixed_centroid - linear_map.dot(moving_centroid)
#     return translation, linear_map


from math import pi, cos, sin
from matplotlib import pyplot as plt, colors as mcol
from pymicro.view.vol_utils import compute_affine_transform
import numpy as np
import random
for i in range(n):
    ref_points[i, 0] = random.randint(0, 10)
    ref_points[i, 1] = random.randint(0, 10)
    print(ref_points[i])
    plt.plot(ref_points[i, 0], ref_points[i, 1], 'o', color=colors[i], markersize=10, markeredgecolor='none',
             label='reference points' if i == 0 else '')
plt.grid()
plt.axis([0, 20, 0, 20])
plt.xlabel('X coordinate')
plt.ylabel('Y coordinate')
plt.legend(numpoints=1)
plt.savefig('pointset_registration_1.png', format='png')

# compute the affine transform by composing R, S and T
s = 1.4
angle = 22 * pi / 180.
tx, ty = 5, 3
S = np.array([[s, 0.0, 0.0],
              [0.0, s, 0.0],
              [0.0, 0.0, 1.0]])
R = np.array([[cos(angle), -sin(angle), 0.0],
              [sin(angle), cos(angle), 0.0],
              [0.0, 0.0, 1.0]])
T = np.array([[1.0, 0.0, tx],
              [0.0, 1.0, ty],
              [0.0, 0.0, 1.0]])
A = np.dot(T, np.dot(S, R))
print('full affine transform:\n{:s}'.format(A))

# transform the points

# Path: pymicro/view/vol_utils.py
# def compute_affine_transform(fixed, moving):
#     """Compute the affine transform by point set registration.
# 
#     The affine transform is the composition of a translation and a linear map.
#     The two ordered lists of points must be of the same length larger or equal to 3.
#     The order of the points in the two list must match.
#     
#     The 2D affine transform :math:`\mathbf{A}` has 6 parameters (2 for the translation and 4 for the linear transform).
#     The best estimate of :math:`\mathbf{A}` can be computed using at least 3 pairs of matching points. Adding more 
#     pair of points will improve the quality of the estimate. The matching pairs are usually obtained by selecting 
#     unique features in both images and measuring their coordinates.
# 
#     :param list fixed: a list of the reference points.
#     :param list moving: a list of the moving points to register on the fixed point.
#     :returns translation, linear_map: the computed translation and linear map affine transform. 
# 
#     Thanks to Will Lenthe for helping with this code.
#     """
#     assert len(fixed) == len(moving)
#     assert len(fixed) >= 3
#     fixed_centroid = np.average(fixed, 0)
#     moving_centroid = np.average(moving, 0)
#     # offset every point by the center of mass of all the points in the set
#     fixed_from_centroid = fixed - fixed_centroid
#     moving_from_centroid = moving - moving_centroid
#     covariance = moving_from_centroid.T.dot(fixed_from_centroid)
#     variance = moving_from_centroid.T.dot(moving_from_centroid)
#     # compute the full affine transform: translation + linear map
#     linear_map = np.linalg.inv(variance).dot(covariance).T
#     translation = fixed_centroid - linear_map.dot(moving_centroid)
#     return translation, linear_map


# Path: docs/cookbook/pointset_registration.py
from math import pi, cos, sin
from matplotlib import pyplot as plt, colors as mcol
from pymicro.view.vol_utils import compute_affine_transform
import numpy as np
import random

for i in range(n):
    ref_points[i, 0] = random.randint(0, 10)
    ref_points[i, 1] = random.randint(0, 10)
    print(ref_points[i])
    plt.plot(ref_points[i, 0], ref_points[i, 1], 'o', color=colors[i], markersize=10, markeredgecolor='none',
             label='reference points' if i == 0 else '')
plt.grid()
plt.axis([0, 20, 0, 20])
plt.xlabel('X coordinate')
plt.ylabel('Y coordinate')
plt.legend(numpoints=1)
plt.savefig('pointset_registration_1.png', format='png')

# compute the affine transform by composing R, S and T
s = 1.4
angle = 22 * pi / 180.
tx, ty = 5, 3
S = np.array([[s, 0.0, 0.0],
              [0.0, s, 0.0],
              [0.0, 0.0, 1.0]])
R = np.array([[cos(angle), -sin(angle), 0.0],
              [sin(angle), cos(angle), 0.0],
              [0.0, 0.0, 1.0]])
T = np.array([[1.0, 0.0, tx],
              [0.0, 1.0, ty],
              [0.0, 0.0, 1.0]])
A = np.dot(T, np.dot(S, R))
print('full affine transform:\n{:s}'.format(A))

# transform the points

tsr_points = np.empty_like(ref_points)