import math class Vector: def __init__(self, ls: list): self.vec = ls def __len__(self): return len(self.vec) def __getitem__(self, idx): return self.vec[idx] def __repr__(self): return f'Vector({self.vec})' def add(self, vec): assert len(self) == len(vec) ret = [a+b for a, b in zip(self.vec, vec.vec)] return Vector(ret) def sub(self, vec): assert len(self) == len(vec) ret = [a-b for a, b in zip(self.vec, vec.vec)] return Vector(ret) def mul(self, vec): assert len(self) == len(vec) ret = [a*b for a, b in zip(self.vec, vec.vec)] return Vector(ret) def scalar_mul(self, x): ret = [a*x for a in self.vec] return Vector(ret) def scalar_div(self, x): ret = [a/x for a in self.vec] return Vector(ret) def norm(self): return math.sqrt(sum([x*x for x in self.vec])) def dot(a, b): return sum(a.mul(b)) def cross(a, b): #outer product of 2d vector assert len(a) == 2 and len(b) == 2 first = a[0]*b[1] second = a[1]*b[0] return first-second EPS = 10**(-9) def ccw(p0, p1, p2): # p0からp1に向かうベクトルの向きに対して、p2の位置を返す a = p1.sub(p0) b = p2.sub(p0) if cross(a, b) > EPS: return 1 #'COUNTER_CLOCKWISE' # p0->p1反時計回りの方向にp2 elif cross(a, b) < -EPS: return -1 #'CLOCKWISE' # p0->p1時計回りの方向にp2 elif dot(a, b) < -EPS: return 2 #'ONLINE_BACK' # p2->p0->p1の順で直線上にp2 elif a.norm() < b.norm(): return -2 #'ONLINE_FRONT' # p0->p1->p2の順で直線上にp2 else: return 0 #'ON_SEGMENT' #p0->p2->p1の順で線分p0p1上にp2 def intersect(p0, p1, p2, p3): if ccw(p0, p1, p2) *ccw(p0, p1, p3) <= 0 and ccw(p2, p3, p0) *ccw(p2, p3, p1) <= 0: return True else: return False def getDistanceLP(p0, p1, p): return abs(cross(p1.sub(p0), p.sub(p0)))/p1.sub(p0).norm() def getDistanceSP(p0, p1, p): if dot(p1.sub(p0), p.sub(p0)) < 0: return p.sub(p0).norm() if dot(p0.sub(p1), p.sub(p1)) < 0: return p.sub(p1).norm() return getDistanceLP(p0, p1, p) def area(polygon): s = 0 for i in range(len(polygon)): s += cross(polygon[i-1], polygon[i]) s /= 2 return s def is_convex(polygon, pi_is_ok=False): # 内角が180度以下のとき: pi_is_ok = True # 内角が180度未満のとき: pi_is_ok = False if not pi_is_ok: ccw0 = ccw(polygon[0], polygon[1], polygon[2]) if ccw0 not in {-1, 1}: return False for i in range(len(polygon)): if ccw(polygon[i-2], polygon[i-1], polygon[i]) != ccw0: return False return True else: ccws = set() for i in range(len(polygon)): ccw1 = ccw(polygon[i-2], polygon[i-1], polygon[i]) if ccw1 not in {-1, 1}: continue ccws.add(ccw1) if len(ccws) <= 1: return True else: return False def is_contain(polygon, p): # 2: pがpolygonに含まれる # 1: pがpolygonの辺上 # 0: それ以外 n = len(polygon) in_ = False for i in range(n): a = polygon[i].sub(p) b = polygon[(i+1)%n].sub(p) if abs(cross(a, b)) < EPS and dot(a, b) < EPS: return 1 if a[1] > b[1]: a, b = b, a if a[1] < EPS and EPS < b[1] and cross(a, b) > EPS: in_ = not in_ if in_: return 2 else: return 0 def is_ccw(p0, p1, p2): a = p1.sub(p0) b = p2.sub(p0) if cross(a, b) > EPS: return True else: return False def monotone_chain(points): points.sort(key=lambda x: (x[0], x[1])) if len(points) <= 2: return points upper_conv = [points[0], points[1]] # 後ろから2番目の点と後ろから1番目の点のなすベクトルに対して、新たに加える点が反時計回りだと凸にならない for p in points[2:]: while len(upper_conv) >= 2 and is_ccw(upper_conv[-2], upper_conv[-1], p): upper_conv.pop() upper_conv.append(p) points = points[::-1] lower_conv = [points[0], points[1]] for p in points[2:]: while len(lower_conv) >= 2 and is_ccw(lower_conv[-2], lower_conv[-1], p): lower_conv.pop() lower_conv.append(p) res = upper_conv[1:-1]+lower_conv # 反時計回りで出力 return res[::-1] points = [] for i in range(5): x, y = map(int, input().split()) points.append(Vector([x, y])) conv = monotone_chain(points) if len(conv) != 5: print('NO') exit() for i in range(5): c = ccw(conv[i-2], conv[i-1], conv[i]) if c in {2, -2, 0}: print('NO') exit() else: print('YES')