# Collinearity of points

• This is an attempt at determining collinearity of a series of points. Rather than compare tangents, one stackoverflower suggested calculating areas of triangles. Other strategies?

``````def polygon_area(points):
area = 0
q = points[-1]
for p in points:
area += p * q - p * q
q = p
return area / 2

def plot(points):
if len(points) < 3:
return None
a = 0
for pi, p in enumerate(points[:-2]):
npt = points[pi+1]
nnpt = points[pi+2]
a += abs(polygon_area([points[pi], npt, nnpt]))
return a

pts = [
(725,417),
(548, 440),
(414, 458),
(261, 479)
]

# tolerance for error
margin = 200

v = plot(pts)

print("plotted area", v)
fontSize(100)
if -.5*margin < v < .5*margin:
text("colinear",(100,100))
else:
text("not colinear",(100,100))

# draw the dots
fill(0,0,1)
stroke(1,0,0)
translate(100,100)
newPath()
moveTo(pts)
for p in pts[1:]:
lineTo(p)
drawPath()

ds = 10
fill(0,0,1)
stroke(None)
for p in pts:
oval(p-.5*ds, p-.5*ds, ds, ds)
``````

• what would be 'compare tangents'?

comparing angles is probably more expensive?

``````def get_angle(p1, p2): return atan2((p2 - p1), (p2 - p1))

pts = [
(725,417),
(548, 440),
(414, 458),
(261, 479)
]

angles = [ get_angle(point, pts[p+1]) for p, point in enumerate(pts[:-1])]
angle = get_angle(pts, pts[-1])

# tolerance for error
margin = pi/180

fontSize(100)
if all(abs(a - angle) < margin for a in angles):
text("colinear",(100,100))
else:
text("not colinear",(100,100))

# draw the dots
fill(0,0,1)
stroke(1,0,0)
translate(100,100)
newPath()
moveTo(pts)
for p in pts[1:]:
lineTo(p)
drawPath()

ds = 10
fill(0,0,1)
stroke(None)
for p in pts:
oval(p-.5*ds, p-.5*ds, ds, ds)
``````

• That animation of the KABK crown I did: was looking into this question so as to avoid having to define the collinear = invalid segments explicitly — having the code test the combinations is a more elegant solution.