Points, Lines, Polygons🔗
Line Representations🔗
Standard🔗
- A line: . Used in analytical geometry
Parametric🔗
- A point on line: , where are two points on the line and
Line and Segment Intersection🔗
Check if two segments and intersect
- Orientation Test: Use oreintation function on all combinations
- o1 = orientation(p1, p2, q1)
- o2 = orientation(p1, p2, q2)
- o3 = orientation(q1, q2, p1)
- o4 = orientation(q1, q2, p2)
- If o1 != o2 && o3 != o4 → segments intersect.
- Collinear Case
- Check if one point lies on the other segment using bounding box
bool onSegment(Point p, Point q, Point r) {
return q.x <= max(p.x, r.x) && q.x >= min(p.x, r.x) &&
q.y <= max(p.y, r.y) && q.y >= min(p.y, r.y);
}
Point in Triangle & Point in Polygon🔗
Point in Triangle🔗
Use Barycentric Coordinates or check if point lies on the same side of each triangle edge.
bool point_in_triangle(Point a, Point b, Point c, Point p) {
double A = triangle_area(a, b, c);
double A1 = triangle_area(p, b, c);
double A2 = triangle_area(a, p, c);
double A3 = triangle_area(a, b, p);
return abs((A1 + A2 + A3) - A) < EPS;
}
Point in Polygon🔗
Ray Casting Algorithm🔗
- Shoot a ray from the point to the right.
- Count how many times it intersects with polygon edges.
- If odd → inside, else outside.
Winding Number🔗
- Based on angle the polygon wraps around the point.
- Winding number ≠0 ⇒ point is inside.
// Ray-casting method
bool isInside(vector<Point> &polygon, Point p) {
int n = polygon.size(), cnt = 0;
for (int i = 0; i < n; i++) {
Point a = polygon[i], b = polygon[(i+1)%n];
if (a.y > b.y) swap(a, b);
if (p.y > a.y && p.y <= b.y &&
(b.y - a.y) * (p.x - a.x) < (b.x - a.x) * (p.y - a.y))
cnt ^= 1;
}
return cnt;
}
Convex vs Concave Polygon🔗
- A polygon is convex if all internal angles < 180°.
- All cross products of consecutive edges should have the same sign.
bool isConvex(vector<Point>& poly) {
int n = poly.size();
int sign = 0;
for (int i = 0; i < n; i++) {
Point a = poly[i];
Point b = poly[(i+1)%n];
Point c = poly[(i+2)%n];
int cp = cross({b.x - a.x, b.y - a.y}, {c.x - b.x, c.y - b.y});
if (cp != 0) {
if (sign == 0)
sign = (cp > 0 ? 1 : -1);
else if ((cp > 0 ? 1 : -1) != sign)
return false;
}
}
return true;
}
Polygon Perimeter & Area🔗
Perimeter🔗
double polygon_perimeter(vector<Point> &pts) {
double perim = 0;
int n = pts.size();
for (int i = 0; i < n; i++) {
perim += dist(pts[i], pts[(i + 1) % n]);
}
return perim;
}
Area (Shoelace Method)🔗
double polygon_area(vector<Point> &pts) {
int n = pts.size();
double area = 0;
for (int i = 0; i < n; i++) {
int j = (i + 1) % n;
area += (pts[i].x * pts[j].y) - (pts[j].x * pts[i].y);
}
return abs(area) / 2.0;
}
Convexity Detection🔗
Check if all turns between consecutive triplets are either all left (CCW) or all right (CW) as shown in isConvex() function.
Closest Pair of Points (Divide & Conquer)🔗
Find closest pair in time:
- Sort points by x-coordinate
- Recursively solve for left and right halves
- Combine step: consider only points within distance of mid-line
- Sort those by and check distance within a vertical strip
import math
def dist(p1, p2):
return math.hypot(p1[0] - p2[0], p1[1] - p2[1])
def closest_pair_rec(px, py):
n = len(px)
if n <= 3:
return min(
(dist(px[i], px[j]) for i in range(n) for j in range(i + 1, n)),
default=float('inf')
)
mid = n // 2
mid_x = px[mid][0]
left_px = px[:mid]
right_px = px[mid:]
left_py = list(filter(lambda p: p[0] <= mid_x, py))
right_py = list(filter(lambda p: p[0] > mid_x, py))
d_left = closest_pair_rec(left_px, left_py)
d_right = closest_pair_rec(right_px, right_py)
d = min(d_left, d_right)
strip = [p for p in py if abs(p[0] - mid_x) < d]
# Check at most 6 neighbors ahead in y-sorted strip
for i in range(len(strip)):
for j in range(i + 1, min(i + 7, len(strip))):
d = min(d, dist(strip[i], strip[j]))
return d
def closest_pair(points):
px = sorted(points, key=lambda p: p[0])
py = sorted(points, key=lambda p: p[1])
return closest_pair_rec(px, py)