Geometry Primitives
Authors: Mihnea Brebenel, Benjamin Qi
Contributor: Rameez Parwez
Basic setup for geometry problems.
You should know operations such as the cross product and dot product.
Resources | ||||
---|---|---|---|---|
CF | short description of operations | |||
CPH | Complex #s, Points & Lines, Polygons, Distances | |||
CF | code, examples | |||
cp-algo | ||||
CPC | basics, polygon area, point in polygon | |||
CF | some material is quite advanced | |||
CP2 |
Location of a Point
Focus Problem – try your best to solve this problem before continuing!
Explanation
To check the location towards the line we use following formula: If it's equal to it means that , and are collinear. Otherwise the value's sign indicated if is under the line - negative - or above the line - positive.
Demonstration
Implementation
Time Complexity: , where is the number of test cases.
C++
#include <bits/stdc++.h>using namespace std;Code Snippet: Point Class (Click to expand)long long collinear(Point p, Point p1, Point p2) {return 1LL * (p.y - p1.y) * (p2.x - p1.x) - 1LL * (p.x - p1.x) * (p2.y - p1.y);}int main() {
Python
class Point:def __init__(self, x: int = 0, y: int = 0):self.x = xself.y = ydef collinear(p: Point, p1: Point, p2: Point) -> int:return (p.y - p1.y) * (p2.x - p1.x) - (p.x - p1.x) * (p2.y - p1.y)
Segment Intersection
Focus Problem – try your best to solve this problem before continuing!
Explanation
We can quickly dismiss the segment intersection by treating them as rectangles having the segments as diagonals which can be easily done. If it turns out the rectangles intersect then we just check if the segment's ends are on different sides of the other segment.
Implementation
C++
#include <bits/stdc++.h>using namespace std;Code Snippet: Point Class (Click to expand)int sign(long long num) {if (num < 0) {return -1;} else if (num == 0) {return 0;
Polygon Area
Focus Problem – try your best to solve this problem before continuing!
Explanation
We can use the Shoelace formula.
Implementation
Time Complexity:
C++
#include <bits/stdc++.h>using namespace std;Code Snippet: Point Class (Click to expand)int main() {int n;cin >> n;vector<Point> points(n);for (auto &p : points) { cin >> p; }
Python
class Point:def __init__(self, x: int = 0, y: int = 0):self.x = xself.y = yn = int(input())points = []for _ in range(n):x, y = map(int, input().split())
Point's Location Relative to Polygon
Focus Problem – try your best to solve this problem before continuing!
Explanation
We can cast a ray from the point going in any fixed direction (people usually go to the right). If the point is located on the outside of the polygon the ray will intersect its edges an even number of times. If the point is on the inside of the polygon then it will intersect the edge an odd number of times.
This approach is called ray casting.
Implementation
C++
#include <bits/stdc++.h>using namespace std;Code Snippet: Point Class (Click to expand)bool on_segment(const Point &p, const Point &p1, const Point &p2) {int a = min(p1.x, p2.x);int b = max(p1.x, p2.x);int x = min(p1.y, p2.y);
Lattice points in polygon
Focus Problem – try your best to solve this problem before continuing!
Explanation
Let's first focus on the lattice points on the polygon's boundary. We'll process each edge individually. The number of intersections of a line with lattice points is the greatest common divisor of and .
Demonstration
Now that we know the number of lattice points on the boundary we can find the number of lattice points inside the polygon using Pick's theorem. Let's denote polygon's area, the number of integer points inside and the number of integer points on its boundary. Then, according to Pick's theorem, we have the following equation: . Changing the order a little bit to get . We've found and, as you've probably already solved Polygon Area from above, can be computed using cross-product.
Implementation
Time Complexity: , where is the maximum difference between coordinates of points.
C++
#include <bits/stdc++.h>using namespace std;Code Snippet: Point Class (Click to expand)int main() {int n;cin >> n;vector<Point> points(n);
Python
from math import gcdclass Point:def __init__(self, x: int = 0, y: int = 0):self.x = xself.y = ydef __sub__(self, other):return Point(self.x - other.x, self.y - other.y)
Status | Source | Problem Name | Difficulty | Tags | |
---|---|---|---|---|---|
YS | Easy | ||||
Kattis | Easy | ||||
Kattis | Easy | ||||
Kattis | Easy | ||||
Kattis | Easy | ||||
LC | Easy | ||||
IOI | Normal | ||||
AC | Hard |
Angles
Focus Problem – try your best to solve this problem before continuing!
Explanation
Working with angles only makes sense in the context of lines and segments. Therefore, let's consider the segments connecting the initial position and each dot: . One such segment is inside the field of view if and only if its slope is bigger than the lower bound and smaller than the upper bound. Since we're working with angles, we'll convert the slopes into radians.
Consider as the angle formed by one line with the axis. Then we have:
The movement of the field of view can be seen as a sliding window applied on the sorted angles of the points. The angle of the field of vies could be large enough to see points from the beginning of the sorted array, thus the array of angles should be duplicated - cyclic array.
Implementation
Time Complexity:
C++
class Solution {public:int visiblePoints(vector<vector<int>> &points, int angle, vector<int> &location) {int extra = 0;vector<double> angles;for (const vector<int> &p : points) {// Ignore points identical to locationif (p == location) {extra++;continue;
Python
class Solution:def visiblePoints(self, points: List[List[int]], angle: int, location: List[int]) -> int:extra = 0angles = []for p in points:# Ignore points identical to locationif p == location:
Status | Source | Problem Name | Difficulty | Tags | |
---|---|---|---|---|---|
LC | Hard |
Misc Problems
Some European Olympiads, like the CEOI, Balkan OI, and the Croatian OI, tend to have a lot of geometry problems. These problems tend to be quite difficult as well, so look for problems there when you run out of problems to practice!
Status | Source | Problem Name | Difficulty | Tags | |
---|---|---|---|---|---|
CF | Hard | ||||
Kattis | Hard | ||||
Kattis | Hard |
Module Progress:
Join the USACO Forum!
Stuck on a problem, or don't understand a module? Join the USACO Forum and get help from other competitive programmers!