Finding the angle of any side of a polygon I'm trying to find the angle it would take for me to rotate a polygon so that a specific side is completely horizontal and on the bottom.

For example, a shape like this:


Needs to be rotated so the side with the red square on it is on the bottom and completely horizontal, like this:



So far I've tried several approaches but all end up having strange edge cases where the angle is incorrect.
Deducing the angle and rotating by that angle works quite well in 2D (describe in TLousky's post). This strategy, does not extend very well into three-dimensional realm. I will provide an alternative solution that shows a general strategy that works in a larger set of cases. As a bonus this without needing to think of trigonometry as it can be encoded away.


First identify the vector that you want to be transformed to orientation in your reference space. Let us call this vector $\vec{a}$, or a along vector.
Next you will need to identify a vector that is perpendicular to this vector. Let us call this vector $\vec{b}$, it is sometimes also called a up vector. In three-dimensions you need 3 vectors but once you identify 2 you can compute the third.

Finding out the $\vec{b}$ in 2-D realm is especially easy you could just rotate the vector by $90^{\circ}$ or simply swap the coordinates and make the x coordinate negative (see 1). Alternatively you can use the same procedure as in 3D.

$$\vec{b} = rotate(90^{\circ})\cdot\vec{a} =
      \begin{bmatrix} 
         \cos(\pi/2) &amp; -\sin(\pi/2) \\ 
         \sin(\pi/2) &amp; \cos(\pi/2) 
      \end{bmatrix}
      \begin{bmatrix} 
         x \\ 
         y 
      \end{bmatrix}
         =       
      \begin{bmatrix} 
         -y \\ 
         x 
      \end{bmatrix} 
     \tag{1}$$

In 3-D this usually requires a trick. Since each triangle is flat, one can use this to ones advantage. This gives us a perpendicular direction, now we still need a third one and we can get it by cross product of the 2 known vectors. You now have 3 vector.



Image 1: Vector $\vec{a}$ and derived $\vec{b}$
Normalize the vectors
Use these vectors to produce a a rotation matrix (or a affine matrix wich allows you to specify point to be at zero, your choice). This matrix represents the local coordinate of the rotated object. 
All you now need is to invert this matrix and point matrix multiply your polygon corner vectors for a aligned version of the polygon.


What is especially nifty is the sidestepping of trigonometrical operations. Now i see no point i defining basic matrix operations but i see value in code. So i will use numpy.

import numpy as np, pylab

pts = np.array([
        [0.,0.],[10.,1.],[12.,12.],[-2.,11.],[0.,0.]
      ]).transpose()

f = pylab.figure(facecolor="1.")     
pylab.axis('off')
pylab.axis('equal')
pylab.plot(pts[0], pts[1])  

# 1. Get the vector
vec_a = np.copy(pts[:,2]) - np.copy(pts[:,1])

# 2. up vector
vec_b = np.copy(vec_a[::-1])
vec_b[0] *= -1

# 3. normalize
vec_a /= np.linalg.norm(vec_a)
vec_b /= np.linalg.norm(vec_b)

# 4. build rotation matrix
mtx_R = np.concatenate(([vec_a], [vec_b])).transpose()
mtx_R = np.linalg.inv(mtx_R)

# 5. transform, or set hierarchy transform
pts2 = np.copy(pts)
for i in range(len(pts2[0])):
    pts2[:,i] =  np.dot(mtx_R, pts2[:,i])

pylab.plot(pts2[0],pts2[1])
pylab.show()


I admit it cold be have slightly shorter by refactoring the code and eliminate redundant manipulations but its a demo only so... 



Image 2: Polygon, in blue axis fixed in green.

Same method works well for straightening, skew and other problems such as perspective correction. You can extend this to affine matrices that way you can encode the translation into the calculation with just 1 more lines. In essence you specify what point is at origin and with 2 more operations one could define around what to rotate. Now it just just rotates about the origin.