Given a list of points in the 2D plane represented by their coordinates points
, determine if these points form a convex polygon when connected in order. The polygon is considered convex if all its interior angles are less than 180 degrees, or equivalently, if the polygon always turns in the same direction as you traverse its vertices in order.
points
where points[i] = [xi, yi]
represents the coordinates of the ith point.True
if the polygon is convex, otherwise False
.To determine if a polygon is convex, we need to check that as we move around the polygon, the turns between consecutive edges are always in the same direction (either all left or all right). If at any point the direction of the turn changes, the polygon is not convex.
A brute-force approach would be to check the angle at every vertex, but calculating angles is unnecessary. Instead, we can use the cross product of vectors formed by consecutive triplets of points. The sign of the cross product tells us the direction of the turn:
The key insight is that for a convex polygon, the sign of the cross product should not change as we move from one vertex to the next. This leads us away from brute force and toward a simple, efficient check using cross products.
Let's break down the solution step-by-step:
(A, B, C)
, compute the cross product of vectors AB
and BC
.True
; otherwise, return False
.We use the cross product because it is simple to compute (just integer arithmetic) and directly tells us about the orientation of the turn at each vertex.
Let's consider the following points forming a polygon:
points = [[0,0], [0,1], [1,1], [1,0]]
True
.By leveraging the geometric property that a convex polygon's edges always turn in the same direction, we can efficiently determine convexity using the cross product of vectors. This avoids heavy computations and checks the entire polygon in linear time. The elegance of the solution lies in translating a geometric question into a series of simple arithmetic checks, making it both efficient and easy to implement.
class Solution:
def isConvex(self, points):
def cross(o, a, b):
return (a[0] - o[0]) * (b[1] - o[1]) - (a[1] - o[1]) * (b[0] - o[0])
n = len(points)
prev = 0
for i in range(n):
o = points[i]
a = points[(i + 1) % n]
b = points[(i + 2) % n]
cp = cross(o, a, b)
if cp != 0:
if prev == 0:
prev = cp
elif cp * prev < 0:
return False
return True
class Solution {
public:
bool isConvex(vector<vector<int>>& points) {
int n = points.size();
int prev = 0;
for (int i = 0; i < n; ++i) {
vector<int>& o = points[i];
vector<int>& a = points[(i + 1) % n];
vector<int>& b = points[(i + 2) % n];
int cp = (a[0] - o[0]) * (b[1] - o[1]) - (a[1] - o[1]) * (b[0] - o[0]);
if (cp != 0) {
if (prev == 0)
prev = cp;
else if (cp * prev < 0)
return false;
}
}
return true;
}
};
class Solution {
public boolean isConvex(List<List<Integer>> points) {
int n = points.size();
int prev = 0;
for (int i = 0; i < n; ++i) {
List<Integer> o = points.get(i);
List<Integer> a = points.get((i + 1) % n);
List<Integer> b = points.get((i + 2) % n);
int cp = (a.get(0) - o.get(0)) * (b.get(1) - o.get(1)) - (a.get(1) - o.get(1)) * (b.get(0) - o.get(0));
if (cp != 0) {
if (prev == 0)
prev = cp;
else if (cp * prev < 0)
return false;
}
}
return true;
}
}
var isConvex = function(points) {
const n = points.length;
let prev = 0;
function cross(o, a, b) {
return (a[0] - o[0]) * (b[1] - o[1]) - (a[1] - o[1]) * (b[0] - o[0]);
}
for (let i = 0; i < n; ++i) {
const o = points[i];
const a = points[(i + 1) % n];
const b = points[(i + 2) % n];
const cp = cross(o, a, b);
if (cp !== 0) {
if (prev === 0) prev = cp;
else if (cp * prev < 0) return false;
}
}
return true;
};