Kyopro Library
 
読み取り中…
検索中…
一致する文字列を見つけられません
geo.hpp
[詳解]
1#include"../../kyopro_library/template.hpp"
2
3/// @brief 幾何ライブラリ
4namespace Geometry{
5 using Real=long double;
6 const Real EPS=1e-9;
7
8 bool almostEqual(Real a,Real b){return abs(a-b)<EPS;}
9 bool lessThan(Real a,Real b){return a<b&&!almostEqual(a,b);}
10 bool greaterThan(Real a,Real b){return a>b&&!almostEqual(a,b);}
11 bool lessThanOrEqual(Real a,Real b){return a<b||almostEqual(a,b);}
12 bool greaterThanOrEqual(Real a,Real b){return a>b||almostEqual(a,b);}
13
14 /// @brief 2次元平面上の位置ベクトル
15 struct Point{
16 Real x,y;
17 Point()=default;
18 Point(Real x,Real y):x(x),y(y){}
19
20 Point operator+(const Point&p)const{return Point(x+p.x,y+p.y);}
21 Point operator-(const Point&p)const{return Point(x-p.x,y-p.y);}
22 Point operator*(Real k)const{return Point(x*k,y*k);}
23 Point operator/(Real k)const{return Point(x/k,y/k);}
24
25 /// @brief p との内積を返す
26 Real dot(const Point&p)const{return x*p.x+y*p.y;}
27
28 /// @brief p との外積を返す
29 Real cross(const Point&p)const{return x*p.y-y*p.x;}
30
31 /// @brief p1 と p2 を端点とするベクトルとの外積を返す
32 Real cross(const Point&p1,const Point&p2)const{return(p1.x-x)*(p2.y-y)-(p1.y-y)*(p2.x-x);}
33
34 /// @brief 2乗ノルムを返す
35 Real norm()const{return x*x+y*y;}
36
37 /// @brief ユークリッドノルムを返す
38 Real abs()const{return sqrt(norm());}
39
40 /// @brief 偏角を返す
41 Real arg()const{return atan2(y,x);}
42
43 bool operator==(const Point&p)const{return almostEqual(x,p.x)&&almostEqual(y,p.y);}
44 friend istream&operator>>(istream&is,Point&p){return is>>p.x>>p.y;}
45 };
46
47 /// @brief 直線
48 struct Line{
50 Line()=default;
51 Line(const Point&_a,const Point&_b):a(_a),b(_b){}
52
53 /// @brief 直線 Ax+By=C を定義する
54 Line(const Real&A,const Real&B,const Real&C){
55 if(almostEqual(A,0)){
56 assert(!almostEqual(B,0));
57 a=Point(0,C/B);
58 b=Point(1,C/B);
59 }else if(almostEqual(B,0)){
60 a=Point(C/A,0);
61 b=Point(C/A,1);
62 }else if(almostEqual(C,0)){
63 a=Point(0,C/B);
64 b=Point(1,(C-A)/B);
65 }else{
66 a=Point(0,C/B);
67 b=Point(C/A,0);
68 }
69 }
70
71 bool operator==(const Line&l)const{return a==l.a&&b==l.b;}
72 friend istream&operator>>(istream&is,Line&l){return is>>l.a>>l.b;}
73 };
74
75 /// @brief 線分
76 struct Segment:Line{
77 Segment()=default;
78 using Line::Line;
79 };
80
81 /// @brief 円
82 struct Circle{
83 Point center; ///< 中心
84 Real r; ///< 半径
85
86 Circle()=default;
87 Circle(Real x,Real y,Real r):center(x,y),r(r){}
88 Circle(Point _center,Real r):center(_center),r(r){}
89
90 bool operator==(const Circle&C)const{return center==C.center&&r==C.r;}
91 friend istream&operator>>(istream&is,Circle&C){return is>>C.center>>C.r;}
92 };
93
94 //-----------------------------------------------------------
95
103
104 /// @brief 3点 p0, p1, p2 の進行方向を返す
105 Orientation ccw(const Point&p0,const Point&p1,const Point&p2){
106 Point a=p1-p0;
107 Point b=p2-p0;
108 Real cross_product=a.cross(b);
109 if(greaterThan(cross_product,0))return COUNTER_CLOCKWISE;
110 if(lessThan(cross_product,0))return CLOCKWISE;
111 if(lessThan(a.dot(b),0))return ONLINE_BACK;
113 return ON_SEGMENT;
114 }
115
117 switch(o){
119 return"COUNTER_CLOCKWISE";
120 case CLOCKWISE:
121 return"CLOCKWISE";
122 case ONLINE_BACK:
123 return"ONLINE_BACK";
124 case ONLINE_FRONT:
125 return"ONLINE_FRONT";
126 case ON_SEGMENT:
127 return"ON_SEGMENT";
128 default:
129 return"UNKNOWN";
130 }
131 }
132
133 /// @brief ベクトル p の直線 p1, p2 への正射影ベクトルを返す
134 Point projection(const Point&p1,const Point&p2,const Point&p){
135 Point base=p2-p1;
136 Real r=(p-p1).dot(base)/base.norm();
137 return p1+base*r;
138 }
139
140 /// @brief ベクトル p の直線 l への正射影ベクトルを返す
141 Point projection(const Line&l,const Point&p){
142 Point base=l.b-l.a;
143 Real r=(p-l.a).dot(base)/base.norm();
144 return l.a+base*r;
145 }
146
147 /// @brief ベクトル p の直線 p1, p2 に対する鏡像ベクトルを返す
148 Point reflection(const Point&p1,const Point&p2,const Point&p){
149 Point proj=projection(p1,p2,p);
150 return proj*2-p;
151 }
152
153 /// @brief ベクトル p の直線 l に対する鏡像ベクトルを返す
154 Point reflection(const Line&l,const Point&p){
155 Point proj=projection(l,p);
156 return proj*2-p;
157 }
158
159 //-----------------------------------------------------------
160
161 bool isParallel(const Line&l1,const Line&l2){return almostEqual((l1.b-l1.a).cross(l2.b-l2.a),0);}
162 bool isOrthogonal(const Line&l1,const Line&l2){return almostEqual((l1.b-l1.a).dot(l2.b-l2.a),0);}
163 bool isParallel(const Segment&l1,const Segment&l2){return almostEqual((l1.b-l1.a).cross(l2.b-l2.a),0);}
164 bool isOrthogonal(const Segment&l1,const Segment&l2){return almostEqual((l1.b-l1.a).dot(l2.b-l2.a),0);}
165 bool isParallel(const Line&l1,const Segment&l2){return almostEqual((l1.b-l1.a).cross(l2.b-l2.a),0);}
166 bool isOrthogonal(const Line&l1,const Segment&l2){return almostEqual((l1.b-l1.a).dot(l2.b-l2.a),0);}
167 bool isParallel(const Segment&l1,const Line&l2){return almostEqual((l1.b-l1.a).cross(l2.b-l2.a),0);}
168 bool isOrthogonal(const Segment&l1,const Line&l2){return almostEqual((l1.b-l1.a).dot(l2.b-l2.a),0);}
169 bool isPointOnLine(const Point&p,const Line&l){return almostEqual((l.b-l.a).cross(p-l.a),0.0);}
170 bool isPointOnSegment(const Point&p,const Segment&s){
171 return lessThanOrEqual(min(s.a.x,s.b.x),p.x)&&
172 lessThanOrEqual(p.x,max(s.a.x,s.b.x))&&
173 lessThanOrEqual(min(s.a.y,s.b.y),p.y)&&
174 lessThanOrEqual(p.y,max(s.a.y,s.b.y))&&
176 }
177 bool isIntersecting(const Segment&s1,const Segment&s2){
178 Point p0p1=s1.b-s1.a;
179 Point p0p2=s2.a-s1.a;
180 Point p0p3=s2.b-s1.a;
181 Point p2p3=s2.b-s2.a;
182 Point p2p0=s1.a-s2.a;
183 Point p2p1=s1.b-s2.a;
184 Real d1=p0p1.cross(p0p2);
185 Real d2=p0p1.cross(p0p3);
186 Real d3=p2p3.cross(p2p0);
187 Real d4=p2p3.cross(p2p1);
188 if(lessThan(d1*d2,0)&&lessThan(d3*d4,0))return true;
189 if(almostEqual(d1,0.0)&&isPointOnSegment(s2.a,s1))return true;
190 if(almostEqual(d2,0.0)&&isPointOnSegment(s2.b,s1))return true;
191 if(almostEqual(d3,0.0)&&isPointOnSegment(s1.a,s2))return true;
192 if(almostEqual(d4,0.0)&&isPointOnSegment(s1.b,s2))return true;
193 return false;
194 }
196 assert(isIntersecting(s1,s2));
197 auto cross=[](Point p,Point q){return p.x*q.y-p.y*q.x;};
198 Point base=s2.b-s2.a;
199 Real d1=abs(cross(base,s1.a-s2.a));
200 Real d2=abs(cross(base,s1.b-s2.a));
201 Real t=d1/(d1+d2);
202 return s1.a+(s1.b-s1.a)*t;
203 }
204 Real distancePointToSegment(const Point&p,const Segment&s){
206 if(isPointOnSegment(proj,s)){
207 return(p-proj).abs();
208 }else{
209 return min((p-s.a).abs(),(p-s.b).abs());
210 }
211 }
218
219 //-----------------------------------------------------------
220
221 Real getPolygonArea(const vector<Point>&points){
222 int n=points.size();
223 Real area=0.0;
224 for(int i=0;i<n;++i){
225 int j=(i+1)%n;
226 area+=points[i].x*points[j].y;
227 area-=points[i].y*points[j].x;
228 }
229 return abs(area)/2.0;
230 }
231 bool isConvex(const vector<Point>&points){
232 int n=points.size();
233 bool has_positive=false,has_negative=false;
234 for(int i=0;i<n;++i){
235 int j=(i+1)%n;
236 int k=(i+2)%n;
237 Point a=points[j]-points[i];
238 Point b=points[k]-points[j];
239 Real cross_product=a.cross(b);
240 if(greaterThan(cross_product,0))has_positive=true;
241 if(lessThan(cross_product,0))has_negative=true;
242 }
243 return!(has_positive&&has_negative);
244 }
245 bool isPointOnPolygon(const vector<Point>&polygon,const Point&p){
246 int n=polygon.size();
247 for(int i=0;i<n;++i){
248 Point a=polygon[i];
249 Point b=polygon[(i+1)%n];
250 Segment s(a,b);
251 if(isPointOnSegment(p,s))return true;
252 }
253 return false;
254 }
255 bool isPointInsidePolygon(const vector<Point>&polygon,const Point&p){
256 int n=polygon.size();
257 bool inPolygon=false;
258 for(int i=0;i<n;++i){
259 Point a=polygon[i];
260 Point b=polygon[(i+1)%n];
261 if(greaterThan(a.y,b.y))swap(a,b);
262 if(lessThanOrEqual(a.y,p.y)&&lessThan(p.y,b.y)&&greaterThan((b-a).cross(p-a),0))inPolygon=!inPolygon;
263 }
264 return inPolygon;
265 }
266
267 //-----------------------------------------------------------
268
269 vector<Point>convexHull(vector<Point>&points,bool include_collinear=false){
270 int n=points.size();
271 if(n<=1)return points;
272 sort(points.begin(),points.end(),[](const Point&l,const Point&r)->bool{
274 return lessThan(l.y,r.y);
275 });
276 if(n==2)return points;
277 vector<Point>upper={points[0],points[1]},lower={points[0],points[1]};
278 for(int i=2;i<n;++i){
279 while((int)upper.size()>=2&&ccw(upper.end()[-2],upper.end()[-1],points[i])!=CLOCKWISE){
280 if(ccw(upper.end()[-2],upper.end()[-1],points[i])==ONLINE_FRONT&&include_collinear)break;
281 upper.pop_back();
282 }
283 upper.push_back(points[i]);
284 while((int)lower.size()>=2&&ccw(lower.end()[-2],lower.end()[-1],points[i])!=COUNTER_CLOCKWISE){
285 if(ccw(lower.end()[-2],lower.end()[-1],points[i])==ONLINE_FRONT&&include_collinear)break;
286 lower.pop_back();
287 }
288 lower.push_back(points[i]);
289 }
290 reverse(upper.begin(),upper.end());
291 upper.pop_back();
292 lower.pop_back();
293 lower.insert(lower.end(),upper.begin(),upper.end());
294 return lower;
295 }
296 Real convexHullDiameter(const vector<Point>&hull){
297 int n=hull.size();
298 if(n==1)return 0;
299 int k=1;
300 Real max_dist=0;
301 for(int i=0;i<n;++i){
302 while(true){
303 int j=(k+1)%n;
304 Point dist1=hull[i]-hull[j],dist2=hull[i]-hull[k];
305 max_dist=max(max_dist,dist1.abs());
306 max_dist=max(max_dist,dist2.abs());
307 if(dist1.abs()>dist2.abs()){
308 k=j;
309 }else{
310 break;
311 }
312 }
313 Point dist=hull[i]-hull[k];
314 max_dist=max(max_dist,dist.abs());
315 }
316 return max_dist;
317 }
318 vector<Point>cutPolygon(const vector<Point>&g,const Line&l){
319 auto isLeft=[](const Point&p1,const Point&p2,const Point&p)->bool{return(p2-p1).cross(p-p1)>0;};
320 vector<Point>newPolygon;
321 int n=g.size();
322 for(int i=0;i<n;++i){
323 const Point&cur=g[i];
324 const Point&next=g[(i+1)%n];
325 if(isLeft(l.a,l.b,cur))newPolygon.push_back(cur);
326 if((isLeft(l.a,l.b,cur)&&!isLeft(l.a,l.b,next))||(!isLeft(l.a,l.b,cur)&&isLeft(l.a,l.b,next))){
327 Real A1=(next-cur).cross(l.a-cur);
328 Real A2=(next-cur).cross(l.b-cur);
329 Point intersection=l.a+(l.b-l.a)*(A1/(A1-A2));
330 newPolygon.push_back(intersection);
331 }
332 }
333 return newPolygon;
334 }
335
336 //-----------------------------------------------------------
337
338 Real closestPair(vector<Point>&points,int l,int r){
339 if(r-l<=1)return numeric_limits<Real>::max();
340 int mid=(l+r)>>1;
341 Real x=points[mid].x;
342 Real d=min(closestPair(points,l,mid),closestPair(points,mid,r));
343 auto iti=points.begin(),itl=iti+l,itm=iti+mid,itr=iti+r;
344 inplace_merge(itl,itm,itr,[](const Point&lhs,const Point&rhs)->bool{
345 return lessThan(lhs.y,rhs.y);
346 });
347 vector<Point>nearLine;
348 for(int i=l;i<r;++i){
349 if(greaterThanOrEqual(fabs(points[i].x-x),d))continue;
350 int sz=nearLine.size();
351 for(int j=sz-1;j>=0;--j){
352 Point dv=points[i]-nearLine[j];
353 if(dv.y>=d)break;
354 d=min(d,dv.abs());
355 }
356 nearLine.push_back(points[i]);
357 }
358 return d;
359 }
360
361 //-----------------------------------------------------------
362
363 int countIntersections(vector<Segment>segments){
364 struct Event{
365 Real x;
366 int type;//0:horizontal start,1:vertical,2:horizontal end
367 Real y1,y2;
368 Event(Real x,int type,Real y1,Real y2):x(x),type(type),y1(y1),y2(y2){}
369 bool operator<(const Event&other)const{
370 if(x==other.x)return type<other.type;
371 return x<other.x;
372 }
373 };
374 vector<Event>events;
375 sort(segments.begin(),segments.end(),[](const Segment&lhs,const Segment&rhs)->bool{
376 return lessThan(min(lhs.a.x,lhs.b.x),min(rhs.a.x,rhs.b.x));
377 });
378 for(const auto&seg:segments){
379 if(seg.a.y==seg.b.y){
380 //Horizontal segment
381 Real y=seg.a.y;
382 Real x1=min(seg.a.x,seg.b.x);
383 Real x2=max(seg.a.x,seg.b.x);
384 events.emplace_back(x1,0,y,y);
385 events.emplace_back(x2,2,y,y);
386 }else{
387 //Vertical segment
388 Real x=seg.a.x;
389 Real y1=min(seg.a.y,seg.b.y);
390 Real y2=max(seg.a.y,seg.b.y);
391 events.emplace_back(x,1,y1,y2);
392 }
393 }
394 sort(events.begin(),events.end());
395 set<Real>activeSegments;
396 int intersectionCount=0;
397 for(const auto&event:events){
398 if(event.type==0){
399 //Add horizontal segment to active set
400 activeSegments.insert(event.y1);
401 }else if(event.type==2){
402 //Remove horizontal segment from active set
403 activeSegments.erase(event.y1);
404 }else if(event.type==1){
405 //Count intersections with vertical segment
406 auto lower=activeSegments.lower_bound(event.y1);
407 auto upper=activeSegments.upper_bound(event.y2);
408 intersectionCount+=distance(lower,upper);
409 }
410 }
411 return intersectionCount;
412 }
413
414 //-----------------------------------------------------------
415
416 int countCirclesIntersection(const Circle&c1,const Circle&c2){
417 Real d=sqrt((c1.center.x-c2.center.x)*(c1.center.x-c2.center.x)+
419 Real r1=c1.r,r2=c2.r;
420 if(greaterThan(d,r1+r2)){
421 return 4;
422 }else if(almostEqual(d,r1+r2)){
423 return 3;
424 }else if(greaterThan(d,fabs(r1-r2))){
425 return 2;
426 }else if(almostEqual(d,fabs(r1-r2))){
427 return 1;
428 }else{
429 return 0;
430 }
431 }
432 Circle getInCircle(const Point&A,const Point&B,const Point&C){
433 Real a=(B-C).abs();
434 Real b=(A-C).abs();
435 Real c=(A-B).abs();
436 Real s=(a+b+c)/2;
437 Real area=sqrt(s*(s-a)*(s-b)*(s-c));
438 Real r=area/s;
439 Real cx=(a*A.x+b*B.x+c*C.x)/(a+b+c);
440 Real cy=(a*A.y+b*B.y+c*C.y)/(a+b+c);
441 return Circle{Point(cx,cy),r};
442 }
443 Circle getCircumCircle(const Point&A,const Point&B,const Point&C){
444 Real D=2*(A.x*(B.y-C.y)+B.x*(C.y-A.y)+C.x*(A.y-B.y));
445 Real Ux=((A.x*A.x+A.y*A.y)*(B.y-C.y)+(B.x*B.x+B.y*B.y)*(C.y-A.y)+(C.x*C.x+C.y*C.y)*(A.y-B.y))/D;
446 Real Uy=((A.x*A.x+A.y*A.y)*(C.x-B.x)+(B.x*B.x+B.y*B.y)*(A.x-C.x)+(C.x*C.x+C.y*C.y)*(B.x-A.x))/D;
447 Point center(Ux,Uy);
448 Real radius=(center-A).abs();
449 return Circle{center,radius};
450 }
452 Real cx=c.center.x,cy=c.center.y,r=c.r;
453 Real dx=p2.x-p1.x;
454 Real dy=p2.y-p1.y;
455 Real a=dx*dx+dy*dy;
456 Real b=2*(dx*(p1.x-cx)+dy*(p1.y-cy));
457 Real c_const=(p1.x-cx)*(p1.x-cx)+(p1.y-cy)*(p1.y-cy)-r*r;
458 Real discriminant=b*b-4*a*c_const;
459 vector<Point>intersections;
460 if(almostEqual(discriminant,0)){
461 Real t=-b/(2*a);
462 Real ix=p1.x+t*dx;
463 Real iy=p1.y+t*dy;
464 intersections.emplace_back(ix,iy);
465 intersections.emplace_back(ix,iy);
466 }else if(discriminant>0){
467 Real sqrt_discriminant=sqrt(discriminant);
468 Real t1=(-b+sqrt_discriminant)/(2*a);
469 Real t2=(-b-sqrt_discriminant)/(2*a);
470 Real ix1=p1.x+t1*dx;
471 Real iy1=p1.y+t1*dy;
472 Real ix2=p1.x+t2*dx;
473 Real iy2=p1.y+t2*dy;
474 intersections.emplace_back(ix1,iy1);
475 intersections.emplace_back(ix2,iy2);
476 }
477 if(almostEqual(intersections[0].x,intersections[1].x)){
478 if(greaterThan(intersections[0].y,intersections[1].y))swap(intersections[0],intersections[1]);
479 }else if(greaterThan(intersections[0].x,intersections[1].x)){
480 swap(intersections[0],intersections[1]);
481 }
482 return intersections;
483 }
485 Real x1=c1.center.x,y1=c1.center.y,r1=c1.r;
486 Real x2=c2.center.x,y2=c2.center.y,r2=c2.r;
487 Real d=sqrt((x2-x1)*(x2-x1)+(y2-y1)*(y2-y1));
488 if(d>r1+r2||d<abs(r1-r2))return{};//No intersection
489 Real a=(r1*r1-r2*r2+d*d)/(2*d);
490 Real h=sqrt(r1*r1-a*a);
491 Real x0=x1+a*(x2-x1)/d;
492 Real y0=y1+a*(y2-y1)/d;
493 Real rx=-(y2-y1)*(h/d);
494 Real ry=(x2-x1)*(h/d);
495 Point p1(x0+rx,y0+ry);
496 Point p2(x0-rx,y0-ry);
497 vector<Point>intersections;
498 intersections.push_back(p1);
499 intersections.push_back(p2);
500 if(almostEqual(intersections[0].x,intersections[1].x)){
501 if(greaterThan(intersections[0].y,intersections[1].y))swap(intersections[0],intersections[1]);
502 }else if(greaterThan(intersections[0].x,intersections[1].x)){
503 swap(intersections[0],intersections[1]);
504 }
505 return intersections;
506 }
508 Real cx=c.center.x,cy=c.center.y,r=c.r;
509 Real px=p.x,py=p.y;
510 Real dx=px-cx;
511 Real dy=py-cy;
512 Real d=(p-c.center).abs();
513 if(lessThan(d,r)){
514 return{};//No tangents if the point is inside the circle
515 }else if(almostEqual(d,r)){
516 return{p};
517 }
518 Real a=r*r/d;
519 Real h=sqrt(r*r-a*a);
520 Real cx1=cx+a*dx/d;
521 Real cy1=cy+a*dy/d;
522 vector<Point>tangents;
523 tangents.emplace_back(cx1+h*dy/d,cy1-h*dx/d);
524 tangents.emplace_back(cx1-h*dy/d,cy1+h*dx/d);
525 if(almostEqual(tangents[0].x,tangents[1].x)){
526 if(greaterThan(tangents[0].y,tangents[1].y))swap(tangents[0],tangents[1]);
527 }else if(greaterThan(tangents[0].x,tangents[1].x)){
528 swap(tangents[0],tangents[1]);
529 }
530 return tangents;
531 }
533 Real x1=c1.center.x,y1=c1.center.y,r1=c1.r;
534 Real x2=c2.center.x,y2=c2.center.y,r2=c2.r;
535 Real dx=x2-x1;
536 Real dy=y2-y1;
537 Real d=sqrt(dx*dx+dy*dy);
538 vector<Segment>tangents;
539 //Coincident circles(infinite tangents)
540 if(almostEqual(d,0)&&almostEqual(r1,r2))return tangents;
541 //External tangents
542 if(greaterThanOrEqual(d,r1+r2)){
543 Real a=atan2(dy,dx);
544 for(int sign:{-1,1}){
545 Real theta=acos((r1+r2)/d);
546 Real cx1=x1+r1*cos(a+sign*theta);
547 Real cy1=y1+r1*sin(a+sign*theta);
548 Real cx2=x2+r2*cos(a+sign*theta);
549 Real cy2=y2+r2*sin(a+sign*theta);
550 tangents.emplace_back(Segment{Point(cx1,cy1),Point(cx2,cy2)});
551 if(almostEqual(d,r1+r2))break;
552 }
553 }
554 //Internal tangents
555 if(greaterThanOrEqual(d,fabs(r1-r2))){
556 Real a=atan2(dy,dx);
557 for(int sign:{-1,1}){
558 Real theta=acos((r1-r2)/d);
559 Real cx1=x1+r1*cos(a+sign*theta);
560 Real cy1=y1+r1*sin(a+sign*theta);
561 Real cx2=x2-r2*cos(a+sign*theta);
562 Real cy2=y2-r2*sin(a+sign*theta);
563 tangents.emplace_back(Segment{Point(cx1,cy1),Point(cx2,cy2)});
564 if(almostEqual(d,fabs(r1-r2)))
565 break;
566 }
567 }
568 sort(tangents.begin(),tangents.end(),[&](const Segment&s1,const Segment&s2){
570 return lessThan(s1.a.y,s2.a.y);
571 }else{
572 return lessThan(s1.a.x,s2.a.x);
573 }
574 });
575 return tangents;
576 }
577}
幾何ライブラリ
Definition geo.hpp:4
bool isOrthogonal(const Segment &l1, const Line &l2)
Definition geo.hpp:168
bool isParallel(const Segment &l1, const Line &l2)
Definition geo.hpp:167
int countCirclesIntersection(const Circle &c1, const Circle &c2)
Definition geo.hpp:416
bool isOrthogonal(const Line &l1, const Segment &l2)
Definition geo.hpp:166
vector< Point > cutPolygon(const vector< Point > &g, const Line &l)
Definition geo.hpp:318
bool isParallel(const Line &l1, const Segment &l2)
Definition geo.hpp:165
Real distanceSegmentToSegment(const Segment &s1, const Segment &s2)
Definition geo.hpp:212
int countIntersections(vector< Segment >segments)
Definition geo.hpp:363
Point projection(const Point &p1, const Point &p2, const Point &p)
ベクトル p の直線 p1, p2 への正射影ベクトルを返す
Definition geo.hpp:134
Point reflection(const Line &l, const Point &p)
ベクトル p の直線 l に対する鏡像ベクトルを返す
Definition geo.hpp:154
Point reflection(const Point &p1, const Point &p2, const Point &p)
ベクトル p の直線 p1, p2 に対する鏡像ベクトルを返す
Definition geo.hpp:148
bool greaterThanOrEqual(Real a, Real b)
Definition geo.hpp:12
bool isPointInsidePolygon(const vector< Point > &polygon, const Point &p)
Definition geo.hpp:255
Real distancePointToSegment(const Point &p, const Segment &s)
Definition geo.hpp:204
bool isOrthogonal(const Segment &l1, const Segment &l2)
Definition geo.hpp:164
const Real EPS
Definition geo.hpp:6
bool isParallel(const Line &l1, const Line &l2)
Definition geo.hpp:161
Real closestPair(vector< Point > &points, int l, int r)
Definition geo.hpp:338
Circle getCircumCircle(const Point &A, const Point &B, const Point &C)
Definition geo.hpp:443
vector< Segment > getCommonTangentsLine(const Circle &c1, const Circle &c2)
Definition geo.hpp:532
Point projection(const Line &l, const Point &p)
ベクトル p の直線 l への正射影ベクトルを返す
Definition geo.hpp:141
Orientation ccw(const Point &p0, const Point &p1, const Point &p2)
3点 p0, p1, p2 の進行方向を返す
Definition geo.hpp:105
Circle getInCircle(const Point &A, const Point &B, const Point &C)
Definition geo.hpp:432
Real convexHullDiameter(const vector< Point > &hull)
Definition geo.hpp:296
Point getIntersection(const Segment &s1, const Segment &s2)
Definition geo.hpp:195
bool greaterThan(Real a, Real b)
Definition geo.hpp:10
bool isPointOnLine(const Point &p, const Line &l)
Definition geo.hpp:169
bool almostEqual(Real a, Real b)
Definition geo.hpp:8
string orientationToString(Orientation o)
Definition geo.hpp:116
Real getPolygonArea(const vector< Point > &points)
Definition geo.hpp:221
bool lessThanOrEqual(Real a, Real b)
Definition geo.hpp:11
bool isParallel(const Segment &l1, const Segment &l2)
Definition geo.hpp:163
bool isConvex(const vector< Point > &points)
Definition geo.hpp:231
bool isPointOnSegment(const Point &p, const Segment &s)
Definition geo.hpp:170
bool isOrthogonal(const Line &l1, const Line &l2)
Definition geo.hpp:162
Orientation
Definition geo.hpp:96
@ ON_SEGMENT
Definition geo.hpp:101
@ COUNTER_CLOCKWISE
Definition geo.hpp:97
@ ONLINE_BACK
Definition geo.hpp:99
@ ONLINE_FRONT
Definition geo.hpp:100
@ CLOCKWISE
Definition geo.hpp:98
bool lessThan(Real a, Real b)
Definition geo.hpp:9
bool isPointOnPolygon(const vector< Point > &polygon, const Point &p)
Definition geo.hpp:245
vector< Point > getCircleLineIntersection(const Circle &c, Point p1, Point p2)
Definition geo.hpp:451
vector< Point > convexHull(vector< Point > &points, bool include_collinear=false)
Definition geo.hpp:269
vector< Point > getCirclesIntersect(const Circle &c1, const Circle &c2)
Definition geo.hpp:484
bool isIntersecting(const Segment &s1, const Segment &s2)
Definition geo.hpp:177
vector< Point > getTangentLinesFromPoint(const Circle &c, const Point &p)
Definition geo.hpp:507
Real r
半径
Definition geo.hpp:84
Circle(Real x, Real y, Real r)
Definition geo.hpp:87
Point center
中心
Definition geo.hpp:83
bool operator==(const Circle &C) const
Definition geo.hpp:90
friend istream & operator>>(istream &is, Circle &C)
Definition geo.hpp:91
Circle(Point _center, Real r)
Definition geo.hpp:88
Circle()=default
直線
Definition geo.hpp:48
Point a
Definition geo.hpp:49
friend istream & operator>>(istream &is, Line &l)
Definition geo.hpp:72
Point b
Definition geo.hpp:49
Line(const Real &A, const Real &B, const Real &C)
直線 Ax+By=C を定義する
Definition geo.hpp:54
Line(const Point &_a, const Point &_b)
Definition geo.hpp:51
Line()=default
bool operator==(const Line &l) const
Definition geo.hpp:71
2次元平面上の位置ベクトル
Definition geo.hpp:15
Real cross(const Point &p) const
p との外積を返す
Definition geo.hpp:29
Real arg() const
偏角を返す
Definition geo.hpp:41
Point operator/(Real k) const
Definition geo.hpp:23
Point(Real x, Real y)
Definition geo.hpp:18
Point()=default
friend istream & operator>>(istream &is, Point &p)
Definition geo.hpp:44
Point operator*(Real k) const
Definition geo.hpp:22
Real norm() const
2乗ノルムを返す
Definition geo.hpp:35
Real abs() const
ユークリッドノルムを返す
Definition geo.hpp:38
Real dot(const Point &p) const
p との内積を返す
Definition geo.hpp:26
bool operator==(const Point &p) const
Definition geo.hpp:43
Point operator+(const Point &p) const
Definition geo.hpp:20
Point operator-(const Point &p) const
Definition geo.hpp:21
Real cross(const Point &p1, const Point &p2) const
p1 と p2 を端点とするベクトルとの外積を返す
Definition geo.hpp:32