You are on page 1of 22

Lecture 13: Geometry Steven Skiena Department of Computer Science State University of New York Stony Brook, NY 117944400

http://www.cs.sunysb.edu/skiena

Geometry
This chapter will deal with programming problems associated with real geometry lines, points, circles, and so forth. Although you did geometry in high school, it can be surprisingly difcult to program even very simple things. One reason is that oating point arithmetic introduces numerical uncertainty. Another difculty of geometric programming is that certain obvious operations you do with a pencil, such as nding the intersection of two lines, requires non-trivial programming to do correctly with a computer.

Degeneracy
Special cases or degeneracies require extra attention when doing geometric programming. For these reasons I recommend you carefully study my code fragments before writing your own. There is more geometry to come next week, when we consider problems associated with line segments and polygons a eld known as computational geometry,

Lines
Straight lines are the shortest distance between any two points. Lines are of innite length in both directions, as opposed to line segments, which are nite. We limit our discussion here to lines in the plane. Every line l is completely represented by any pair of points (x1, y1) and (x2, y2) which lie on it. Lines are also completely described by equations such as y = mx + b, where m is the slope of the line and b is the y -intercept, i.e., the unique point (0, b) where it crosses the x-axis.

Line Type
Vertical lines cannot be described by such equations, however, because dividing by x means dividing by zero. The equation x = c denotes a vertical line that crosses the x-axis at the point (c, 0). We use the more general formula ax + by + c = 0 as the foundation of our line type because it covers all possible lines in the plane:
typedef struct double double double } line; { a; b; c; /* x-coefficient */ /* y-coefficient */ /* constant term */

Multiplying these coefcients by any non-zero constant yields an alternate representation for any line. We establish a canonical representation by insisting that the y -coefcient equal 1 if it is non-zero. Otherwise, we set the x-coefcient to 1:
points_to_line(point { if (p1[X] == l->a l->b l->c } else { l->b l->a l->c } } p1, point p2, line *l) p2[X]) { = 1; = 0; = -p1[X]; = 1; = -(p1[Y]-p2[Y])/(p1[X]-p2[X]); = -(l->a * p1[X]) - (l->b * p1[Y]);

point_and_slope_to_line(point p, double m, line *l) { l->a = -m; l->b = 1; l->c = -((l->a*p[X]) + (l->b*p[Y])); }

Line Intersection
Two distinct lines have one intersection point unless they are parallel; in which case they have none. Parallel lines share the same slope but have different intercepts and by denition never cross.
bool parallelQ(line l1, line l2) { return ( (fabs(l1.a-l2.a) <= EPSILON) && (fabs(l1.b-l2.b) <= EPSILON) ); }

The intersection point of lines l1 : y = m1x + b1 and l2 : y2 = m2x + b2 is the point where they are equal, namely, x= b2 b1 , m1 m2 y = m1 b2 b1 + b1 m1 m2

Implementation
intersection_point(line l1, line l2, point p) { if (same_lineQ(l1,l2)) { printf("Warning: Identical lines, all points intersect.\n"); p[X] = p[Y] = 0.0; return; } if (parallelQ(l1,l2) == TRUE) { printf("Error: Distinct parallel lines do not intersect.\n"); return; } p[X] = (l2.b*l1.c - l1.b*l2.c) / (l2.a*l1.b - l1.a*l2.b); if (fabs(l1.b) > EPSILON) /* test for vertical line */ p[Y] = - (l1.a * (p[X]) + l1.c) / l1.b; else p[Y] = - (l2.a * (p[X]) + l2.c) / l2.b; }

Angles
An angle is the union of two rays sharing a common endpoint. The entire range of angles spans from 0 to 2 radians or, equivalently, 0 to 360 degrees. Most trigonometric libraries assume angles are measured in radians. A right angle measures 90o or /2 radians. Any two non-parallel lines intersect each other at a given angle. Lines l1 : a1x + b1y + c1 = 0 and l2 : a2x + b2y + c2 = 0, written in the general form, intersect at the angle given by: a 1 b2 a 2 b1 tan = a 1 a 2 + b1 b2

For lines in slope-intercept form this reduces to tan = (m2 m1)/(m1m2 + 1). Two lines are perpendicular if they cross at right angles to each other. The line perpendicular to l : y = mx + b is y = (1/m)x + b, for all values of b.

Closest Point
A very useful subproblem is identifying the point on line l which is closest to a given point p. This closest point lies on the line through p which is perpendicular to l, and hence can be found using the routines we have already developed:
closest_point(point p_in, line l, point p_c) { line perp; /* perpendicular to l through (x,y) */ if (fabs(l.b) <= EPSILON) { p_c[X] = -(l.c); p_c[Y] = p_in[Y]; return; } if (fabs(l.a) <= EPSILON) { p_c[X] = p_in[X]; p_c[Y] = -(l.c); return; } /* vertical line */

/* horizontal line */

point_and_slope_to_line(p_in,1/l.a,&perp); /* normal case */ intersection_point(l,perp,p_c); }

Triangles
Each pair of rays with a common endpoint denes an internal angle of a radians and an external angle of 2 a radians. The three internal (smaller) angles of any triangle add up to 180o = radians. The Pythagorean theorem enables us to calculate the length of the third side of any right triangle given the length of the other two. Specically, |a|2 + |b|2 = |c|2, where a and b are the two shorter sides, and c is the longest side or hypotenuse. We can go farther to analyze triangles using trigonometry.

Trigonometry

The trigonometric functions sine and cosine are dened as the x- and y -coordinates of points on the unit circle centered at (0, 0). The tangent is the ratio of sine over cosine. These functions enable us to relate the lengths of any two sides of a right triangle T with the non-right angles of T . The non-hypotenuse edges can be labeled as opposite or adjacent edges in relation to a given angle a. Then |opposite| |op |adjacent| , sin(a) = , tan(a) = cos(a) = |hypotenuse| |hypotenuse| |ad Use the famous Indian Chief Soh-Cah-Toa to remember these relations. Cah means Cosine equals Adjacent over Hypotenuse, for example.

Solving Triangles
The Law of Sines provides the relationship between sides and angles in any triangle. For angles A, B , C , and opposing edges a, b, c a b c = = sin A sin B sin C The Law of Cosines is a generalization of the Pythagorean theorem beyond right angles. For any triangle with angles A, B , C , and opposing edges a, b, c, a2 = b2 + c2 2bc cos A Solving triangles is the art of deriving the unknown angles and edge lengths of a triangle given a subset of such measurements.

Area of a Triangle
The area A(T ) of a triangle T is given by A(T ) = (1/2)ab, where a is the altitude and b is the base of the triangle. Another approach to computing the area of a triangle is directly from its coordinate representation. Using linear algebra and determinants, it can be shown that the signed area A(T ) of triangle T = (a, b, c) is ax ay 1 2 A(T ) = bx by 1 = axby ay bx + ay cx axcy + bxcy cxby cx cy 1 This formula generalizes nicely to compute d! times the volume of a simplex in d dimensions.

Note that the signed areas can be negative, so we must take the absolute value to compute the actual area. The sign of this area can be used to build important primitives for computational geometry.
double signed_triangle_area(point a, point b, point c) { return( (a[X]*b[Y] - a[Y]*b[X] + a[Y]*c[X] - a[X]*c[Y] + b[X]*c[Y] - c[X]*b[Y]) / 2.0 ); } double triangle_area(point a, point b, point c) { return( fabs(signed_triangle_area(a,b,c)) ); }

Circles
A circle is dened as the set of points at a given distance (or radius) from its center, (xc, yc). A circle can be represented in two basic ways, either as triples of boundary points or by its center/radius. For most applications, the center/radius representation is most convenient:
typedef struct { point c; double r; } circle; /* center of circle */ /* radius of circle */

The equation of a circle of radius r follows directly from its center/radius representation, r = (x xc)2 + (y yc)2. Many important quantities associated with circles are easy to compute. Specically, A = r2 and C = 2r.

A tangent line l intersects the boundary of c but not its interior. The point of contact between c and l lies on the line perpendicular to l through the center of c. We can compute the unknown tangent length x using the Pythagorean theorem. From x, we can compute either the tangent point or the angle a. The distance d from O to the center is computed using the distance formula. Two circles c1 and c2 of distinct radii r1 and r2 will intersect if and only if the distance between their centers is at most r1 + r2 . The points of intersection form triangles with the two centers whose edge lengths are totally determined (r1, r2, and the distance between the centers), so the angles and coordinates can be computed as needed.

111301 (Dog and Gopher)


Find a hole for a slow gopher to hide from a fast dog. Is the closest hole really the safest spot for the gopher?

111302 (Rope Crisis in Ropeland!)


What is the length of the shortest rope between two points around a circular post?

111305 (Birthday Cake)


How do you cut a circular cake such that both pieces are the same area and contain the same number of cherries? There is always a solution to this problem if we remove the constraint that the cutline have integer coordinates can you prove it? Is there a more efcient solution than trying all possible A, B pairs?

111308 (How Big Is It?)


What is the tightest way to order a non-overlapping collection of circles so as to minimize the shadow of them? Is it better to order the circles from largest to smallest, or to interleave them? Does the order ever not matter? Will backtracking work for this problem?

You might also like