Topic Link: UVA 12304-2d Geometry in 1!
Nothing to say, according to the operation of the direct treatment.
#include <cstdio> #include <cstring> #include <cmath> #include <vector> #include <algorithm >using namespace Std;const Double pi = 4 * atan (1); const double EPS = 1e-9;inline int dcmp (double x) {if (Fabs (x) < ; EPS) return 0; else return x < 0? -1:1; }inline double getdistance (double x, double y) {return sqrt (x * x + y * y);} struct point {double x, y; Point (Double x = 0, double y = 0): x (x), Y (y) {}void read () {scanf ("%lf%lf", &x, &y);} void Write () {printf ("%lf%lf", x, y);} BOOL operator = = (CONST point& u) Const {return dcmp (x-u.x) = = 0 && dcmp (y-u.y) = = 0;} BOOL operator! = (const point& u) Const {return! ( *this = = u); }bool operator < (const point& u) Const {return x < u.x | | (x = = u.x && y < u.y); }bool operator > (const point& u) Const {return u < *this;} BOOL operator <= (const point& u) Const {return *this < u | | *this = u;} BOOL operator >= (const point& U) const {return *this > U | | *this = = u;} Point operator + (const point& u) {return point (x + u.x, y + u.y);} Point operator-(const point& u) {return point (x-u.x, y-u.y);} Point operator * (const double u) {return point (x * u, y * u);} Point operator/(const double u) {return point (x/u, y/u);}}; typedef point VECTOR;STRUCT Line {Double A, B, C; Line (Double A = 0, double b = 0, double c = 0): A (a), B (b), C (c) {}};struct Circle {point o;double R; Circle (Point o, double r = 0): O (O), R (r) {}point point (double rad) {return point (o.x + cos (rad) *r, O.y + sin (rad) *r);} };namespace punctual {Double getdistance (point A, point B) {double x=a.x-b.x, y=a.y-b.y; return sqrt (x*x + y*y);}}; namespace Vectorial {/* dot product: The product of two vector lengths multiplied by the cosine of their angle, the angle is greater than 90 degrees the product is negative */double Getdot (vector A, vector b) {return a.x * b.x + A.Y * B.Y; }/* Cross product: The cross product is equal to two vectors consisting of a triangle with a direction area of twice times, crosses (V, w) =-cross (W, v) */double Getcross (vector A, vector b) {return a.x * B.Y-A.Y * b.x; }double GetLength (Vector a{return sqrt (Getdot (A, a));} Double Getangle (Vector u) {return atan2 (u.y, u.x);} Double Getangle (vector A, vector b) {return ACOs (Getdot (A, B)/GetLength (a)/GetLength (b));} Vector Rotate (vector A, double rad) {return vector (A.x*cos (RAD)-a.y*sin (RAD), A.x*sin (RAD) +a.y*cos (RAD));} /* unit normal */vector Getnormal (Vector a) {double L = getlength (a); return Vector (-a.y/l, a.x/l);}}; Namespace Linear {using namespace vectorial; Line GetLine (double x1, double y1, double x2, double y2) {return line (y2-y1, x1-x2, y1* (x2-x1)-x1* (y2-y1));} Line GetLine (double A, double b, point u) {return line (A, B, u.y * b-u.x * a);} BOOL Getintersection (line p, line Q, point& o) {if (Fabs (P.A * q.b-q.a * p.b) < EPS) return false;o.x = (Q.C * p. B-P.C * q.b)/(P.A * q.b-q.a * p.b); o.y = (Q.C * p.a-p.c * q.a)/(P.B * q.a-q.b * p.a); return true;} /* Intersection of linear PV and line QW */bool getintersection (point P, Vector v, point Q, Vector W, point& o) {if (dcmp (Getcross (V, w)) = = 0 ) return false; VEctor u = p-q;double k = Getcross (w, u)/Getcross (V, w); o = p + v * K;return true;} /* points P to line ab distance */double getdistancetoline (point P, dot a, bit b) {return fabs (Getcross (b-a, p-a)/GetLength (B-A));} Double getdistancetosegment (point P, point A, point B) {if (a = = b) return getlength (P-A); Vector v1 = b-a, v2 = p-a, V3 = p-b;if (dcmp (Getdot, V1) < 0) return v2 (getlength); else if (V2 (dcmp (Getdot, V 3)) > 0) return GetLength (V3), Else return fabs (Getcross (v1, v2)/GetLength (v1));} /* point P on the line ab projection */point getpointtoline (points P, a, point B) {Vector v = b-a; return a+v* (Getdot (V, p-a)/Getdot (V, v)); }/* to determine if a segment has an intersection */bool haveintersection (Point A1, Point A2, point B1, point B2) {double C1=getcross (a2-a1, b1-a1), c2=getc Ross (A2-A1, B2-A1), C3=getcross (B2-B1, A1-B1), C4=getcross (B2-B1,A2-B1), return dcmp (C1) *dcmp (C2) < 0 && dcmp (C3) *dcmp (C4) < 0;} /* Determine if the point is */bool onsegment on a line segment {return dcmp (Getcross (A-p, b-p)) = = 0 &&Amp DCMP (Getdot (A-p, b-p)) < 0; }}namespace Triangular {using namespace vectorial;double getangle (double A, double b, double c) {return ACOs (a*a+b*b-c* c)/(2*A*B)); }double Getarea (Double A, double b, double c) {double s = (a+b+c)/2; return sqrt (s* (s-a) * (s-b) * (S-C));} Double Getarea (Double A, double h) {return a * H/2;} Double Getarea (Point A, point B, point C) {return fabs (Getcross (b-a, c-a))/2;}}; Namespace polygonal {using namespace vectorial;double Getarea (point* p, int n) {double ret = 0;for (int i = 1; i < n-1 ; i++) ret + = Getcross (P[i]-p[0], p[i+1]-p[0]); return fabs (ret)/2;}}; Namespace Circular {using namespace vectorial;/* line and original intersection */int getlinecircleintersection (point P, point Q, Circle O, Doub le& T1, double& T2, vector<point>& sol) {vector v = q-p;/* need to empty Sol *///sol.clear before use ();d ouble a = v.x, b = p.x-o.o.x, c = v.y, d = p.y-o.o.y;double e = a*a+c*c, F = (a*b+c*d), g = b*b+d*d-o.r*o.r;double Delta = f*f-4*e *g;if (dcmp (Delta) < 0) return 0;if (dcmp (delta) = = 0) {T1 = t2 =-F/(2 * e); Sol.push_back (P + v * t1); return 1;} T1 = (-f-sqrt (delta))/(2 * e); Sol.push_back (p + v * t1); t2 = (-f + sqrt (delta))/(2 * e); Sol.push_back (p + v * T2); return 2;} /* Circle intersection */int getcirclecircleintersection (Circle O1, Circle O2, vector<point>& sol) {Double d = getlength (O1. O-O2.O); if (dcmp (d) = = 0) {if (dcmp (O1.R-O2.R) = = 0) Return-1;return 0;} if (dcmp (O1.R + o2.r-d) < 0) return 0;if (DCMP (fabs)-D) > 0) return O1.R-O2.R a = 0;double (Getangle) ;d ouble da = ACOs ((O1.R*O1.R + D*D-O2.R*O2.R)/(2*o1.r*d)); Point P1 = O1.point (a-da), p2 = O1.point (A+da), Sol.push_back (p1), if (P1 = = p2) return 1;sol.push_back (P2); return 2;} /* tangents */int gettangents (point P, Circle O, vector* v) {Vector U = o.o-p;double d = getlength (u); if (d < O.R) R Eturn 0;else if (dcmp (D-O.R) = = 0) {V[0] = rotate (u, PI/2); return 1;} else {double ang = asin (O.R/D); v[0] = rotate (u ,-ang); v[1] = rotate (U, ang); return 2;}} /* A[i] and b[i] are the tangency points of the section I tangent on O1 and O2 respectively */int gettangents (Circle O1, Circle O2, point* A, point* b) {int cnt = 0;IF (O1.R < O2.R) {swap (O1, O2); swap (A, b);} Double D2 = GetLength (O1.O-O2.O); D2 = D2 * d2;double rdif = O1.R-O2.R, rsum = O1.R + o2.r;if (D2 < RDIF * Rdif) return 0;if (dcmp (d2) = = 0 && DCMP (O1.R-O2.R) = = 0) return-1;double base = Getangle (O2.O-O1.O); if (dcmp (D2-RDIF * rdif) = = 0) {a[cnt] = O1.point ( Base); B[CNT] = O2.point (base); Cnt++;return CNT;} Double ang = ACOs ((O1.R-O2.R)/sqrt (D2)); a[cnt] = O1.point (Base+ang); B[CNT] = O2.point (Base+ang); CNT++;A[CNT] = O1.point (Base-ang); B[CNT] = O2.point (Base-ang); Cnt++;if (dcmp (d2-rsum * rsum) = = 0) {a[cnt] = O1.point (base); b[cnt] = O2.point (base); cnt++;} else if (D2 > Rsum * rsum) {Double ang = ACOs ((O1.R + O2.R)/sqrt (D2)); a[cnt] = O1.point (Base+ang); b[cnt] = O2.point (Base+ang); cnt++;a[cnt ] = O1.point (Base-ang); B[CNT] = O2.point (Base-ang); cnt++;} return CNT;}}; Using NamespacE vectorial;using namespace linear;using namespace Circular; Circle circumscribedcircle (Point P1, point P2, point p3) {Double Bx = p2.x-p1.x, by = P2.Y-P1.Y; Double Cx = p3.x-p1.x, Cy = p3.y-p1.y; Double D = 2 * (Bx * cy-by * Cx); Double CX = (Cy * (BX * bx + by *) – by * (CX * CX + cy * cy))/D + p1.x; Double cy = (BX * (CX * CX + cy * CY)-CX * (BX * bx + by *))/D + p1.y; Point P = Point (CX, CY); Return Circle (P, GetLength (p1-p)); }circle inscribedcircle (Point P1, point P2, point p3) {Double A = GetLength (P2-P3); Double b = getlength (P3-P1); Double c = getlength (P1-P2); Point P = (P1 * A + P2 * b + p3 * c)/(A + B + c); Return Circle (P, Getdistancetoline (P, p1, p2)); } int tangentlinethroughpoint (Circle o, point P, double* rad) {double tmp; Vector v[5];vector<point> sol;int n = gettangents (P, O, v); for (int i = 0; i < n; i++) {Rad[i] = Getangle (V[i], V Ector (1, 0)); if (dcmp (V[I].Y) <= 0) Rad[i] = Pi-rad[i];} return n;} void CircleThroughapointandtangenttoalinewithradius (Circle O, point A, point B) {double T1, t2;vector<point> sol; Vector v = getnormal (A), getlinecircleintersection (A + v * O.R, B + v * o.r, O, T1, T2, sol); getlinecircleintersection (A-V * O.R, B-v * O.R, O, T1, T2, Sol); sort (Sol.begin (), Sol.end ());p rintf ("["); for (int i = 0; I < sol.size (); i++) {if (i) printf (",");p rintf ("(%.6LF,%.6LF)", sol[i].x, SOL[I].Y);} printf ("]\n");} void Circletangenttotwolineswithradius (Point A, point B, point C, point D, double R) {double T1, T2; Point o;vector<point> Sol; Vector V1 = Getnormal (A-B), V2 = Getnormal (c-d); Getintersection (A+v1*r, B-a, C+v2*r, D-c, O); Sol.push_back (o); getinte Rsection (A+v1*r, B-a, C-v2*r, D-c, O); Sol.push_back (o); Getintersection (A-v1*r, B-a, C+v2*r, D-c, O); Sol.push_back (o); Getintersection (A-v1*r, B-a, C-v2*r, D-c, O); Sol.push_back (o); sort (Sol.begin (), Sol.end ());p rintf ("["); for (int i = 0; I < sol.size (); i++) {if (i) printf (",");p rintf ("(%.6LF,%.6LF)", Sol[I].x, SOL[I].Y);} printf ("]\n");} int main () {double R, t[10]; Point A, B, C, D;char Order[105];while (scanf ("%s", order) = = 1) {if (strcmp (Order, "circumscribedcircle") = = 0) {a.read () , B.read (), C.read (); Circle O = Circumscribedcircle (A, B, c);p rintf ("(%.6LF,%.6LF,%.6LF) \ n", o.o.x, O.o.y, O.R);} else if (strcmp (Order, "inscribedcircle") = = 0) {a.read (), B.read (), C.read (); Circle O = Inscribedcircle (A, B, c);p rintf ("(%.6LF,%.6LF,%.6LF) \ n", o.o.x, O.o.y, O.R);} else if (strcmp (Order, "tangentlinethroughpoint") = = 0) {a.read (), scanf ("%lf", &r), B.read (); int n = Tangentlinethrou Ghpoint (Circle (A, R), B, t), sort (T, T + N);p rintf ("["); for (int i = 0; I < n; i++) {if (i) printf (",");p rintf ("%.6lf", T[i] * 180/pi);} printf ("]\n");} else if (strcmp (Order, "circlethroughapointandtangenttoalinewithradius") = = 0) {a.read (), B.read (), C.read (), scanf ("% LF ", &r); Circlethroughapointandtangenttoalinewithradius (Circle (A, R), B, c);} else if (strcmp (Order, "Circletangenttotwolineswithradius") = = 0) {a.read (), B.read (), C.read (), D.read (), scanf ("%lf ", &r); Circletangenttotwolineswithradius (A, B, C, D, r);} else {double R1, r2;a.read (), scanf ("%lf", &r1), B.read (), scanf ("%lf%lf", &r2, &r);vector<point> Sol; Getcirclecircleintersection (Circle (A, r1+r), Circle (b, R2+r), Sol), sort (Sol.begin (), Sol.end ());p rintf ("["); for (int i = 0; I < sol.size (); i++) {if (i) printf (",");p rintf ("(%.6LF,%.6LF)", sol[i].x, SOL[I].Y);} printf ("]\n");}} return 0;}
Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.
UVA 12304-2d Geometry in 1! (geometry)