# Computational Geometry

## Presentation on theme: "Computational Geometry"— Presentation transcript:

Computational Geometry
ACM Workshop Computational Geometry

Basics Given two lines L1: A(x1,y1) B(x2,y2) L2: C(x3,y3) D(x4,y4)
Q. Find if they are perpendicular: Method1: Calculate m1=(B.y-A.y)/(B.x-A.x) m2=(D.y-C.y)/(D.x-C.x) If(m1*m2==-1) then “Perpendicular”

Basics Method 2: Check if dotProduct is zero:
Problem with this approach: 1.Check for divisibility by zero 2. Loss of precision in divisibilty Method 2: Check if dotProduct is zero: int dotProduct(Point A,Point B,Point C,Point D) { int x1,y1,x2,y2; x1=B.x-A.x; y1=B.y-A.y; x2=D.x – C.x; y2 = D.y – C.y; return (x1*x2+y1*y2); }

Basics Q. How to calculate cross product:
int crossProduct(Point A, Point B, Point C , Point D) { int x1,y1,x2,y2; x1=B.x-A.x; y1=B.y-A.y; x2=D.x – C.x; y2 = D.y – C.y; return (x1*y2-x2*y1); }

Question Find the distance between a line AB and point C
A(x1,y1) , B(x2,y2), C(x3,y3) A B A C

Solution Area of parallelogram = AB x AC
Area of triangle = (AB x AC)/2 (Base * Height)/2 = (AB x AC)/2 Height = (AB x AC)/|AB| B A C

Code Distance between a line segment (AB) and a point (C).
double linePointDist(Point A, Point B, Point C, boolean isSegment){ double dist = cross(B-A,C-A) / distance(A,B); if(isSegment) { int dot1 = dot(B-A,C-B); // AB . BC if(dot1 > 0) return distance(B,C); int dot2 = dot(A-B,C-A); // BA . AC if(dot2 > 0) return distance(A,C); } return abs(dist);

Tips Try to use struct/class for a point and all calculations using p.x and p.y struct Point { int x; int y; } Use templating for extending point with double/float coordinates. Overload operators for cross/dot product, add, subtract. Sometimes, a clever heuristic will save you lot of work and knowledge otherwise required to solve a problem. While comparing two floating point numbers, we take a very small value(epsilon ~ 10^-6) for comparison.

Triangulation We start triangulating the
Find the area of a polygon. We start triangulating the polygon by dividing into number of triangles. Pick a vertex and two adjacent points. Calculate area of triangle so formed Now the vertex picked is same but other two vertex change. Area of the polygon shown = ABC(AB x AC) +ACD(AC x AD) + ADE(AD x AE) If it were a Concave Polygon?????? A E B C D A

Code int area = 0; //We will triangulate the polygon into triangles with points p[0],p[i],p[i+1] for(int i = 1; i+1<N; i++){ area += cross(p[i]-p[0], p[i+1]-p[0]); // p[0]p[i] x p[0]p[i+1] } return abs(area/2.0);

Question Test if a point is interior or exterior

Solution Drawing a ray from given point out to infinity in some direction. Each time the ray crossed the boundary of the polygon, it would cross from the interior to the exterior, or vice versa Odd number of time crosses: Interior Even : Exterior To implement, pick multiple large random number for a far point and vote for the best answer

Code String testPoint(verts, x, y) { int N = lengthof(verts);
int cnt = 0; double x2 = random()* ; double y2 = random()* ; for(int i = 0; i<N; i++){ if(distPointToSegment(verts[i],verts[(i+1)%N],x,y) == 0) return "BOUNDARY"; if(segmentsIntersect((verts[i],verts[(i+1)%N],{x,y},{x2,y2})) cnt++; } if(cnt%2 == 0) return "EXTERIOR"; else return "INTERIOR";

Line-Line Intersection
A = y2-y1 B = x1-x2 C = A*x1+B*y1 A1B2x + B1B2y = B2C1 A2B1x + B1B2y = B1C2 To solve A1x + B1y = C1 A2x + B2y = C2 Multiply 1 by B2 and 1 by B1 So x = (B2C1 – B1C2) / (A1B2 – A2B1)

Code double det = A1*B2 - A2*B1 { if(det == 0){ //Lines are parallel }
else{ double x = (B2*C1 - B1*C2)/det double y = (A1*C2 - A2*C1)/det For line segment, check x,y lies on it or not. min(x1,x2) ≤ x ≤ max(x1,x2) Precision issues: What if we just want to check if two line segments intersect or not??

Counter ClockWise (ccw)
// sign of BA x CA int ccw(Point A, Point B, Point C); return value 0 if BAxCA = 0 => A, B, C are collinear 1 if BAxCA > 0 => Triangle ABC is aligned anti-clockwise -1 if BAxCA < 0 => Triangle ABC is aligned clockwise Application example if(ccw(a, c, d) == ccw(b, c, d)) // a, b lie on the same side of line cd

Check Line intersection
// Line intersection AB and CD if(ccw(A, B, C) == 0 && ccw(A, B, D) == 0){ // A, B, C, D are collinear if( (AB . BC > 0 and AB . BD > 0) || (BA . AC > 0 and BA . AD > 0) ){ // Doesn’t Intersect else // Intersect } if( ccw(A, C, D) != ccw(B, C, D) && ccw(C, A, B) != ccw(D, A, B) )

Line Sweep Algorithm Given N sets of points, find the closest distance between two points.

10 10

10 20 10

12 20 8 8 10

16 6 8

12 4 6 6

8 4

Steps Sort the set according to x-coordinates
Sweep a vertical line across the set of points ,from left to right, performing certain actions every time a point is encountered during the plane sweep Lets say till now the closest pair encountered has a distance of d and now the sweep line is at a new point p. In order to get a distance < d, we need to consider only points within a strip of distance d to the left of the sweep line. Along y axis, we need to consider points within distance +d and –d from the current point p. Thus the strip reduces to d x 2*d rectangle. These points will be stored in an ordered set D (sorted by their y- coordinates)

Actions when a point is encountered
Remove the points further than d to the left of p from the ordered set D that is storing the points in the strip. Determine the point on the left of p that is closest to it in d x 2*d rectangle If the distance between this point and p is less than d (the current minimum distance), then update the closest current pair and d.

Why God Why!!! There can be many points in d x2*d rectangle for a p, so how is complexity O(nlgn)? In the given rectangle, each point(except p) will be at distance > d from each other . If their existed a pair with distance(dnew) less than d, then the minimum distance till now would have been dnew. So what is the maximum number of points that can exist in d x 2*d rectangle such that any two points are at distance at least d ?

Maximum Number of Points to Consider ?
Maximum number of points in d x 2*d can be 6 Imagine a circle of radius d around each point representing the area that we are not allowed to insert another point into We can place points somewhere inside the light blue area or on the edges of the circles Hence we put one more in the middle of the left side leaving the entire box covered except for the remaining two corners and the middle of the right side (all three of these points being right on the boundaries of the circles) So a maximum of 6 points.

Why Use Sets ? We are only removing points which are distance > d along x-axis not along y-axis. Thus giving the width of rectangle as d. But how to maintain it’s height 2*d? We cannot remove all points at a distance > d along y axis because the next point we consider may be directly above the current point which may require those points A set may even contain close to n points when all points are on a vertical line In that set we consider only points with y coordinates (y-d to y+d), and find the minimum distance

Code double lineSweep(Point arr[]) { d = distance(arr[0],arr[1]); l=0;
set.insert(arr[0]); set.insert(arr[1]); for(r=2;r<n;r++) while(point[l].x < (point[r].x – d)) set.erase(point[l]); l++; } for(it=set.lower_bound(point[r].x,point[r].y-d);it <= set.upper_bound(point[r].x,point[r].y+d);it++) if(d>distance(point[r].x,point[r].y,it->x,it->y)) d=dist(point[r].px,point[r].py,it->px,it->py); set.insert(point[r]); return d;