Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 14 additions & 7 deletions ch7/polygon.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,7 @@ def __init__(self, x, y): # constructor
self.x = x
self.y = y

def __sub__(self, b): #tovec(a,b)==b-a
return point(self.x-b.x, self.y-b.y)
def __lt__(self, b): #self<b mod for floats :)
return (self.x<b.x) if self.x!=b.x else (self.y<b.y)
def __lt__(self, b): return (self.x, self.y) < (b.x, b.y)

def __str__(self): return "{} {}".format(self.x, self.y)
def __hash__(self):return hash((self.x,self.y))
Expand All @@ -28,6 +25,13 @@ def __hash__(self):return hash((self.x,self.y))
# bool operator <(const point &p) const {
# return x < p.x || (abs(x-p.x) < EPS && y < p.y); } };

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

def toVec(a, b):
return vec(b.x-a.x, b.y-a.y)
# struct vec { double x, y; // name: `vec' is different from STL vector
# vec(double _x, double _y) : x(_x), y(_y) {} };

Expand All @@ -39,12 +43,15 @@ def dist(p1, p2): # Euclidean distance

# returns the perimeter of polygon P, which is the sum of
# Euclidian distances of consecutive line segments (polygon edges)
# def perimeter(P) return math.fsum(dist(P[i], P[i+1]) for i in range(len(P)-1))
def perimeter(P):
ans = 0.0
for i in range(len(P)-1): # note: P[n-1] = P[0]
ans += dist(P[i], P[i+1]) # as we duplicate P[0]
return ans

def area(P):
return math.fsum(cross(P[i], P[i+1]) for i in range(len(P)-1))/2
# // returns the area of polygon P
# double area(const vector<point> &P) {
# double ans = 0.0;
Expand Down Expand Up @@ -73,7 +80,7 @@ def cross(a, b): return a.x*b.y-a.y*b.x
# return fabs(ans)/2.0;
# }

def ccw(p, q, r): return (cross(q-p, r-p) > 0)
def ccw(p, q, r): return (cross(toVec(p,q),toVec(p,r)) > 0)
# note python i used class opperators for tovec (Agis Daniels)
# // note: to accept collinear points, we have to change the `> 0'
# // returns true if point r is on the left side of line pq
Expand Down Expand Up @@ -181,8 +188,8 @@ def CH_Andrew(ps):
def f(B): #f is a mapping of the two loops since its dup code
for p in P:
while len(H)>B and not ccw(H[-2], H[-1], p): H.pop()
H.append(p)
H.pop()
H.append(p)
H.pop()
f(1); P=P[::-1]; f(len(H)+1); return H #4 line low, rev, up, ret
#c++ implementation below
# vector<point> CH_Andrew(vector<point> &Pts) { // overall O(n log n)
Expand Down