computational geometry. given two lines l1: a(x1,y1) b(x2,y2) l2: c(x3,y3) d(x4,y4) q. find if they...

30
ACM Workshop Computational Geometry

Upload: jeffery-bigsby

Post on 14-Dec-2015

220 views

Category:

Documents


5 download

TRANSCRIPT

Page 1: Computational Geometry. 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)

ACM WorkshopComputational Geometry

Page 2: Computational Geometry. 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)

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

Page 3: Computational Geometry. 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)

Problem with this approach:1.Check for divisibility by zero2. 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

Page 4: Computational Geometry. 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)

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);

}

Basics

Page 5: Computational Geometry. 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)

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

Question

A

B

C

Page 6: Computational Geometry. 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)

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|

Solution

A

B

C

Page 7: Computational Geometry. 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)

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);

}

Code

Page 8: Computational Geometry. 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)

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.

Tips

Page 9: Computational Geometry. 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)

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??????

Triangulation

CD

E

B

A

Page 10: Computational Geometry. 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)

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);

Code

Page 11: Computational Geometry. 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)

Test if a point is interior or exterior

Question

Page 12: Computational Geometry. 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)

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

Solution

Page 13: Computational Geometry. 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)

String testPoint(verts, x, y) {int N = lengthof(verts); int cnt = 0; double x2 = random()*1000+1000; double y2 = random()*1000+1000; 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"; }

Code

Page 14: Computational Geometry. 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)

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)

Line-Line Intersection

Page 15: Computational Geometry. 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)

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??

Code

Page 16: Computational Geometry. 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)

// sign of BA x CAint 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 exampleif(ccw(a, c, d) == ccw(b, c, d)) // a, b lie on the same side of line cd

Counter ClockWise (ccw)

Page 17: Computational Geometry. 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)

// Line intersection AB and CDif(ccw(A, B, C) == 0 && ccw(A, B, D) == 0){

// A, B, C, D are collinearif( (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) )// Intersect

else// Doesn’t Intersect

Check Line intersection

Page 18: Computational Geometry. 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)

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

Line Sweep Algorithm

Page 19: Computational Geometry. 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)

10

Page 20: Computational Geometry. 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)

10

20

Page 21: Computational Geometry. 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)

12

8

20

10

Page 22: Computational Geometry. 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)

8

166

Page 23: Computational Geometry. 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)

12

6

4

Page 24: Computational Geometry. 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)

4

8

Page 25: Computational Geometry. 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)

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)

Steps

Page 26: Computational Geometry. 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)

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.

Actions when a point is encountered

Page 27: Computational Geometry. 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)

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 ?

Why God Why!!!

Page 28: Computational Geometry. 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)

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.

Maximum Number ofPoints to Consider ?

Page 29: Computational Geometry. 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)

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

Why Use Sets ?

Page 30: Computational Geometry. 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)

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;

}

Code