The Python Book
 
angle point atan
20151022

Angle between 2 points

Calculate the angle in radians, between the horizontal through the 1st point and a line through the two points

def angle(p0,p1):
    dx=float(p1.x)-float(p0.x)
    dy=float(p1.y)-float(p0.y)
    if dx==0:
        if dy==0:
            return 0.0
        elif dy<0:
            return math.atan(float('-inf'))
        else:
            return math.atan(float('inf'))
    return math.atan(dy/dx)
collinear point
20151022

Generate an array of collinear points plus some random points

  • generate a number of points (integers) that are on the same line
  • randomly intersperse these coordinates with a set of random points
  • watchout: may generate dupes! (the random points, not the collinear points)

Source:

import random

p=[(5,5),(1,10)]    # points that define the line 

# warning: this won't work for vertical line!!!
slope= (float(p[1][1])-float(p[0][1]))/(float(p[1][0])-float(p[0][0]) )
intercept= float(p[0][1])-slope*float(p[0][0])

ar=[]
for x in range(0,25):     
    y=slope*float(x)+intercept

    # only keep the y's that are integers
    if (y%2)==0: 
        ar.append((x,int(y)))
    
    # intersperse with random coordinates
    r=3+random.randrange(0,5)  

    # only add random points when random nr is even
    if r%2==0: 
        ar.extend( [ (random.randrange(0,100),random.randrange(0,100)) for j in range(r) ])  
    
print ar

Sample output:

[(1, 10), (97, 46), (94, 12), (33, 10), (9, 71), (9, 0), (28, 34), 
(2, 94), (30, 29), (69, 28), (82, 31), (79, 86), (88, 46), (59, 24), 
(2, 78), (54, 88), (94, 78), (99, 37), (75, 48), (91, 1), (67, 61), 
(12, 11), (55, 55), (58, 82), (95, 99), (56, 27), (12, 18), (99, 25), 
(77, 84), (31, 39), (64, 84), (4, 13), (80, 63), (43, 27), (78, 43), 
(24, 32), (17, -10), (73, 15), (6, 97), (0, 74), (16, 97), (6, 77), 
(60, 77), (19, 83), (19, 82), (19, 40), (58, 63), (64, 62), (14, 53),
(57, 21), (49, 24), (66, 94), (82, 1), (29, 39), (55, 64), (85, 68), 
(39, 24)]
point class
20151022

Define a point class

  • with an x and y member
  • with methods to 'autoprint'

Definition

import math

class P:
    x=0
    y=0
    def __init__(self,x,y):
        self.x=x
        self.y=y

    # gets called when a print is executed
    def __str__(self):
        return "x:{} y:{}".format(self.x,self.y)

    # gets called eg. when a print is executed on an array of P's
    def __repr__(self):
        return "x:{} y:{}".format(self.x,self.y)


# convert an array of arrays or tuples to array of points
def convert(in_ar) :
    out_ar=[]
    for el in in_ar:
        out_ar.append( P(el[0],el[1]) )
    return out_ar

How to initialize

Eg. create a list of points

# following initialisations lead to the same array of points (note the convert)
p=[P(0,0),P(0,1),P(-0.866025,-0.5),P(0.866025,0.5)]
q=convert( [[0,0],[0,1],[-0.866025,-0.5],[0.866025,0.5]] )  
r=convert( [(0,0),(0,1),(-0.866025,-0.5),(0.866025,0.5)] )

print type(p), ' | ' , p[2].x, p[2].y,  ' | ', p[2]
print type(q), ' | ' , q[2].x, q[2].y,  ' | ', q[2]
print type(r), ' | ' , r[2].x, r[2].y,  ' | ', r[2]

Output:

<type 'list'>  |  -0.866025 -0.5  |  x:-0.866025 y:-0.5
<type 'list'>  |  -0.866025 -0.5  |  x:-0.866025 y:-0.5
<type 'list'>  |  -0.866025 -0.5  |  x:-0.866025 y:-0.5

How to use

eg. Calculate the angle between :

  • the horizontal line through the first point
  • and the line through the two points

Then convert the result from radians to degrees: (watchout: won't work for dx==0)

print math.atan( ( p[3].y - p[0].y ) / ( p[3].x - p[0].x ) ) * 180.0/math.pi

Output:

30.0000115676
 
Notes by Willem Moors. Generated on momo:/home/willem/sync/20151223_datamungingninja/pythonbook at 2019-07-31 19:22