// Copyright (C) Common Computational Geometry Algorithms e.U, ZutterHao
//
// This file is implementation of Common Common Computational Geometry Algorithms.
//
// Please please pay attention to input according to the specified data type.
//
// Author: ZutterHao .Nanjing University ,VISG
// Github: https://github.com/fanghao6666
// <20> <> <EFBFBD> <EFBFBD> ʵ<EFBFBD> ֵ<EFBFBD> һ Щ<D2BB> <D0A9> <EFBFBD> 㼸<EFBFBD> <E3BCB8> <EFBFBD> г <EFBFBD> <D0B3> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> 㷨<EFBFBD> <E3B7A8> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> 㣬<EFBFBD> ߣ<EFBFBD> <DFA3> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ε<EFBFBD>
// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> 㷨ֻ<E3B7A8> <D6BB> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> C++<2B> <> <EFBFBD> ⣬<EFBFBD> <E2A3AC> <EFBFBD> ð<EFBFBD> <C3B0> <EFBFBD> <EFBFBD> κ<EFBFBD> <CEBA> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
// ʹ <> <CAB9> ʱ<EFBFBD> <CAB1> ע<EFBFBD> ⰴ<EFBFBD> չ涨<D5B9> <E6B6A8> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ͽ<EFBFBD> <CDBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
// Ŀǰֻʹ <D6BB> <CAB9> C++<2B> <> ʵ<EFBFBD> <CAB5> <EFBFBD> 㷨<EFBFBD> <E3B7A8> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> 㷨ԭ<E3B7A8> <D4AD> <EFBFBD> <EFBFBD> ½<EFBFBD> <C2BD> <EFBFBD> <EFBFBD> Github<75> ϸ<EFBFBD> <CFB8> <EFBFBD>
// Github: https://github.com/fanghao6666
/*** <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ͷ<EFBFBD> ļ<EFBFBD> ***/
# include <iostream>
# include <vector>
# include <map>
# include <stack>
# include <algorithm>
# include <random>
# include <ctime>
using namespace std ;
namespace Compute_Geometry {
/*** <20> <> <EFBFBD> ó<EFBFBD> <C3B3> <EFBFBD> ***/
const double PI = 3.14159265 ;
/******************************* <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> *******************************/
// <20> <> ,<2C> <> ά<EFBFBD> <CEAC> <EFBFBD> <EFBFBD> ά,ͬʱ<CDAC> <CAB1> Ҳ<EFBFBD> <D2B2> <EFBFBD> Ա<EFBFBD> ʾ һ <CABE> <D2BB> ʸ<EFBFBD> <CAB8>
struct Point
{
double x ; // x<> <78> <EFBFBD> <EFBFBD>
double y ; // y<> <79> <EFBFBD> <EFBFBD>
double z ; // z<> <7A> <EFBFBD> ꣨Ĭ<EAA3A8> <C4AC> Ϊ0<CEAA> <30> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ҫ<EFBFBD> <D2AA> ά<EFBFBD> <CEAC> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> z<EFBFBD> <7A> ֵ<EFBFBD> <D6B5>
Point ( double a = 0 , double b = 0 , double c = 0 ) { x = a ; y = b ; z = c ; } // <20> <> <EFBFBD> 캯<EFBFBD> <ECBAAF>
} ;
// <20> <> <EFBFBD> ļӷ<C4BC>
Point add ( const Point & lhs , const Point & rhs )
{
Point res ;
res . x = lhs . x + rhs . x ;
res . y = lhs . y + rhs . y ;
res . z = lhs . z + rhs . z ;
return res ;
}
// <20> <> <EFBFBD> ļ<EFBFBD> <C4BC> <EFBFBD>
Point sub ( const Point & lhs , const Point & rhs )
{
Point res ;
res . x = lhs . x - rhs . x ;
res . y = lhs . y - rhs . y ;
res . z = lhs . z - rhs . z ;
return res ;
}
// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ij˷<C4B3>
Point mul ( const Point & p , double ratio )
{
Point res ;
res . x = p . x * ratio ;
res . y = p . y * ratio ;
res . z = p . z * ratio ;
return res ;
}
// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ij<EFBFBD> <C4B3> <EFBFBD>
Point div ( const Point & p , double ratio )
{
Point res ;
res . x = p . x / ratio ;
res . y = p . y / ratio ;
res . z = p . z / ratio ;
return res ;
}
// <20> <> <EFBFBD> ж<EFBFBD> <D0B6> <EFBFBD> <EFBFBD> <EFBFBD>
bool equal ( const Point & lhs , const Point & rhs )
{
return ( lhs . x = = rhs . x & & lhs . y = = rhs . y & & lhs . z = = rhs . z ) ;
}
// <20> <> ,<2C> <> <EFBFBD> <EFBFBD> <EFBFBD> ߶κ<DFB6> ֱ<EFBFBD> <D6B1>
struct Line
{
Point s ; // <20> <> <EFBFBD> <EFBFBD>
Point e ; // <20> յ<EFBFBD>
bool is_seg ; // <20> Ƿ<EFBFBD> <C7B7> <EFBFBD> <EFBFBD> ߶<EFBFBD>
Line ( ) { } ; // Ĭ<> Ϲ <EFBFBD> <CFB9> 캯<EFBFBD> <ECBAAF>
Line ( Point a , Point b , bool _is_seg = true ) { s = a ; e = b ; is_seg = _is_seg ; } // <20> <> <EFBFBD> 캯<EFBFBD> <ECBAAF> (Ĭ<> <C4AC> <EFBFBD> <EFBFBD> <EFBFBD> ߶<EFBFBD> )
} ;
// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ƽ <EFBFBD> <C6BD>
struct Triangle
{
Point v0 ;
Point v1 ;
Point v2 ;
bool is_plane ;
Triangle ( ) { } ; // Ĭ<> Ϲ <EFBFBD> <CFB9> 캯<EFBFBD> <ECBAAF>
Triangle ( Point a , Point b , Point c , bool _is_plane = false ) { v0 = a ; v1 = b ; v2 = c ; is_plane = _is_plane ; } // <20> <> <EFBFBD> 캯<EFBFBD> <ECBAAF> <EFBFBD> <EFBFBD> Ĭ<EFBFBD> <C4AC> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Σ<EFBFBD>
} ;
/******************************* <20> <> <EFBFBD> 㼸<EFBFBD> <E3BCB8> <EFBFBD> 㷨Ŀ¼ *******************************/
// һ <> <D2BB> <EFBFBD> <EFBFBD>
// 1.1<EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ֮<EFBFBD> <EFBFBD> <EFBFBD> ľ<EFBFBD> <EFBFBD> <EFBFBD>
double distance ( const Point & p1 , const Point & p2 ) ;
// 1.2<EFBFBD> <EFBFBD> ʸ<EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
double length ( const Point & vec ) ;
// 1.3<EFBFBD> <EFBFBD> ʸ<EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
Point normalize ( const Point & vec ) ;
// 1.4<EFBFBD> <EFBFBD> ʸ<EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
double dotMultiply ( const Point & op , const Point & p1 , const Point & p2 ) ;
double dotMultiply ( const Point & vec1 , const Point & vec2 ) ;
// 1.5<EFBFBD> <EFBFBD> ʸ<EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
Point multiply ( const Point & op , const Point & p1 , const Point & p2 ) ;
Point multiply ( const Point & vec1 , const Point & vec2 ) ;
// 1.6<EFBFBD> <EFBFBD> <EFBFBD> 㵽<EFBFBD> ߵ ľ<EFBFBD> <EFBFBD> <EFBFBD>
double ptolDistance ( const Point & p , const Line & l ) ;
// 1.7<EFBFBD> <EFBFBD> <EFBFBD> 㵽<EFBFBD> ߵ <EFBFBD> ͶӰ<EFBFBD> <EFBFBD>
Point ptolProjection ( const Point & p , const Line & l ) ;
// 1.8<EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ߵ ĶԳƵ<EFBFBD>
Point ptolSymmetry ( const Point & p , const Line & l ) ;
// 1.9<EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ƿ<EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
bool isponl ( const Point & p , const Line & l ) ;
// 1.10<EFBFBD> <EFBFBD> ʸ<EFBFBD> <EFBFBD> <EFBFBD> н<EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
double Sin ( const Point & op , const Point & p1 , const Point & p2 ) ;
double Sin ( const Point & vec1 , const Point & vec2 ) ;
// 1.11<EFBFBD> <EFBFBD> ʸ<EFBFBD> <EFBFBD> <EFBFBD> н<EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
double Cos ( const Point & op , const Point & p1 , const Point & p2 ) ;
double Cos ( const Point & vec1 , const Point & vec2 ) ;
// 1.12<EFBFBD> <EFBFBD> ʸ<EFBFBD> <EFBFBD> <EFBFBD> н<EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
double Tan ( const Point & op , const Point & p1 , const Point & p2 ) ;
double Tan ( const Point & vec1 , const Point & vec2 ) ;
// 1.13<EFBFBD> <EFBFBD> ʸ<EFBFBD> <EFBFBD> <EFBFBD> нǽǶ<EFBFBD>
double Angle ( const Point & op , const Point & p1 , const Point & p2 , bool is_radian = true ) ;
double Angle ( const Point & vec1 , const Point & vec , bool is_radian = true ) ;
// 1.14<EFBFBD> <EFBFBD> <EFBFBD> ж<EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ƿ<EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
bool isPointsCollinear ( const Point & p1 , const Point & p2 , const Point & p3 ) ;
// 1.15<EFBFBD> <EFBFBD> <EFBFBD> ڣ<EFBFBD> -1<> <31> -1<> <31> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> 1<EFBFBD> <31> 1<EFBFBD> <31> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> n<EFBFBD> <6E> <EFBFBD> <EFBFBD>
vector < Point > randomGenPoints ( int num ) ;
// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
// 2.1<EFBFBD> <EFBFBD> <EFBFBD> ߶<EFBFBD> <EFBFBD> Ƿ<EFBFBD> <EFBFBD> ཻ
bool isSegIntersect ( const Line & l1 , const Line & l2 , Point & inter_p ) ;
// 2.2<EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ֱ<EFBFBD> ߵ ļн<EFBFBD>
double angleOfLines ( const Line & l1 , const Line & l2 , bool is_radian = true ) ;
// 2.3<EFBFBD> <EFBFBD> һ <EFBFBD> ױ<EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ߲<EFBFBD> ֵ
vector < Point > firstOrderBezier ( const Point & s , const Point & e , int inter_num ) ;
// 2.4<EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ױ<EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ߲<EFBFBD> ֵ
vector < Point > secondOrderBezier ( const Point & s , const Point & e , const Point & p , int inter_num ) ;
// 2.5<EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ױ<EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ߲<EFBFBD> ֵ
vector < Point > thirdOrderBezier ( const Point & s , const Point & e , const Point & p1 , const Point & p2 , int inter_num ) ;
// 2.6<EFBFBD> <EFBFBD> <EFBFBD> ڣ<EFBFBD> -1<> <31> -1<> <31> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> 1<EFBFBD> <31> 1<EFBFBD> <31> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> n<EFBFBD> <6E> <EFBFBD> <EFBFBD>
vector < Line > randomGenLines ( int num ) ;
// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
// 3.1<EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ƿ<EFBFBD> <EFBFBD> ܹ<EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
bool isTriangle ( const Triangle & t ) ;
// 3.2<EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ƿ<EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ڲ<EFBFBD>
bool isPointInTriangle ( const Triangle & t , const Point & p , double & u , double & v ) ;
// 3.3<EFBFBD> <EFBFBD> <EFBFBD> 㵽ƽ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ͶӰ<EFBFBD> 㣨<EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ĵ㣩
Point ptotProjection ( const Triangle & t , const Point & p ) ;
// 3.4<EFBFBD> <EFBFBD> <EFBFBD> 㵽ƽ <EFBFBD> <EFBFBD> <EFBFBD> ľ<EFBFBD> <EFBFBD> <EFBFBD>
double ptotDistance ( const Triangle & t , const Point & p ) ;
// 3.5<EFBFBD> <EFBFBD> <EFBFBD> ߶κ<EFBFBD> ƽ <EFBFBD> <EFBFBD> <EFBFBD> Ľ<EFBFBD> <EFBFBD> <EFBFBD>
Point ltotInterPoint ( const Triangle & t , const Line & l ) ;
// 3.6<EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ƽ <EFBFBD> <EFBFBD> <EFBFBD> ĵ<EFBFBD> λ<EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
Point getUnitNormal ( const Triangle & t ) ;
// 3.7<EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ε<EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
double areaOfTriangle ( const Triangle & t ) ;
// <20> ġ<EFBFBD> <C4A1> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
// 4.1<EFBFBD> <EFBFBD> <EFBFBD> ж϶<EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ζ<EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> İ<EFBFBD> <EFBFBD> <EFBFBD>
void checkConvex ( const vector < Point > & polygon , vector < bool > & flags ) ;
// 4.2<EFBFBD> <EFBFBD> <EFBFBD> ж϶<EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ƿ<EFBFBD> Ϊ<EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
bool isConvex ( const vector < Point > & polygon ) ;
// 4.3<EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Χ <EFBFBD> ɵ<EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
double areaOfPolygon ( const vector < Point > & polygon ) ;
// 4.4<EFBFBD> <EFBFBD> <EFBFBD> ж϶<EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ƿ<EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ʱ<EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
bool isConterClock ( const vector < Point > & polygon ) ;
// 4.5<EFBFBD> <EFBFBD> <EFBFBD> жϵ<EFBFBD> <EFBFBD> Ƿ<EFBFBD> <EFBFBD> ڶ<EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ڲ<EFBFBD>
bool isPointInPolygon ( const vector < Point > & polygon , const Point & p ) ;
// 4.6<EFBFBD> <EFBFBD> <EFBFBD> ж<EFBFBD> <EFBFBD> ߶<EFBFBD> <EFBFBD> Ƿ<EFBFBD> <EFBFBD> ڶ<EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ڲ<EFBFBD>
bool isSegInPolygon ( const vector < Point > & polygon , const Line & l ) ;
// 4.7<EFBFBD> <EFBFBD> <EFBFBD> ж<EFBFBD> Բ<EFBFBD> Ƿ<EFBFBD> <EFBFBD> ڶ<EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ڲ<EFBFBD>
bool isCircleInPolygon ( const vector < Point > & polygon , const Point & p , double radius ) ;
// 4.8<EFBFBD> <EFBFBD> Ѱ<EFBFBD> ҵ㼯<EFBFBD> <EFBFBD> <EFBFBD> 㷨<EFBFBD> <EFBFBD> graham<EFBFBD> 㷨<EFBFBD> <EFBFBD>
vector < Point > findConvexGraham ( const vector < Point > & points ) ;
// 4.9<EFBFBD> <EFBFBD> Ѱ<EFBFBD> ҵ㼯<EFBFBD> <EFBFBD> <EFBFBD> 㷨<EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ʱ<EFBFBD> 临<EFBFBD> Ӷ<EFBFBD> O(nlogn)
vector < Point > findConvex ( const vector < Point > & points ) ;
// 4.10<EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
Point centerOfPolygon ( const vector < Point > & polygon ) ;
// 4.11<EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ϶<EFBFBD> <EFBFBD> ڶ<EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ڲ<EFBFBD> <EFBFBD> <EFBFBD> һ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
Point pointInPolygon ( const vector < Point > & polygon ) ;
// 4.12<EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> εķ<EFBFBD> Χ
void boxOfPolygon ( const vector < Point > & polygon , Point & down_left , Point & up_right ) ;
// <20> 塢Բ
// 5.1<EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Բ<EFBFBD> Ĺ<EFBFBD> ϵ
int pointToCircle ( const Point & c , double radius , const Point & p ) ;
// 5.2<EFBFBD> <EFBFBD> ֱ<EFBFBD> ߺ <EFBFBD> Բ<EFBFBD> Ĺ<EFBFBD> ϵ
int lineToCircle ( const Point & c , double radius , const Line & l ) ;
// 5.3<EFBFBD> <EFBFBD> <EFBFBD> ߶κ<EFBFBD> Բ<EFBFBD> Ĺ<EFBFBD> ϵ
int segToCircle ( const Point & c , double radius , const Line & l ) ;
// 5.4<EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Բ֮<EFBFBD> <EFBFBD> <EFBFBD> Ĺ<EFBFBD> ϵ
int circleToCircle ( const Point & c1 , double raduis1 , const Point & c2 , double radius2 ) ;
/******************************* <20> <> <EFBFBD> 㼸<EFBFBD> <E3BCB8> <EFBFBD> 㷨ʵ<E3B7A8> <CAB5> *******************************/
//һ <> <D2BB> <EFBFBD> <EFBFBD>
// 1.1<EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ֮<EFBFBD> <EFBFBD> <EFBFBD> ľ<EFBFBD> <EFBFBD> <EFBFBD>
//
// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> p1 : <20> <> һ <EFBFBD> <D2BB> <EFBFBD> <EFBFBD> p2: <20> ڶ<EFBFBD> <DAB6> <EFBFBD> <EFBFBD> <EFBFBD>
//
double distance ( const Point & p1 , const Point & p2 )
{
return ( sqrt ( pow ( p1 . x - p2 . x , 2 ) + pow ( p1 . y - p2 . y , 2 ) + pow ( p1 . z - p2 . z , 2 ) ) ) ;
}
// 1.2<EFBFBD> <EFBFBD> ʸ<EFBFBD> <EFBFBD> <EFBFBD> ij<EFBFBD> <EFBFBD> <EFBFBD>
//
// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> vec ʸ<> <CAB8>
//
double length ( const Point & vec )
{
return ( sqrt ( pow ( vec . x , 2 ) + pow ( vec . y , 2 ) + pow ( vec . z , 2 ) ) ) ;
}
// 1.3<EFBFBD> <EFBFBD> ʸ<EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ʸ<EFBFBD> <EFBFBD> <EFBFBD> ij<EFBFBD> <EFBFBD> ȹ<EFBFBD> Լ<EFBFBD> <EFBFBD> 1<EFBFBD> <EFBFBD>
//
// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> vec <20> <> ʸ<> <CAB8>
//
Point normalize ( const Point & vec )
{
Point res ;
res = div ( vec , length ( vec ) ) ;
return res ;
}
// 1.4<EFBFBD> <EFBFBD> ʸ<EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
//
// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> (p1-op)Ϊʸ<CEAA> <CAB8> 1<EFBFBD> <31> <EFBFBD> <EFBFBD> p2-op<6F> <70> Ϊʸ<CEAA> <CAB8> 2
//
double dotMultiply ( const Point & op , const Point & p1 , const Point & p2 )
{
return ( ( p1 . x - op . x ) * ( p2 . x - op . x ) + ( p1 . y - op . y ) * ( p2 . y - op . y ) + ( p1 . z - op . z ) * ( p2 . z - op . z ) ) ;
}
// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> vec1Ϊʸ<CEAA> <CAB8> 1<EFBFBD> <31> vec2Ϊʸ<CEAA> <CAB8> 2
//
double dotMultiply ( const Point & vec1 , const Point & vec2 )
{
return ( vec1 . x * vec2 . x + vec1 . y * vec2 . y + vec1 . z * vec2 . z ) ;
}
// 1.5<EFBFBD> <EFBFBD> ʸ<EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
//
// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> (p1-op)Ϊʸ<CEAA> <CAB8> 1<EFBFBD> <31> <EFBFBD> <EFBFBD> p2-op<6F> <70> Ϊʸ<CEAA> <CAB8> 2
//
Point multiply ( const Point & op , const Point & p1 , const Point & p2 )
{
Point result ;
result . x = ( p1 . y - op . y ) * ( p2 . z - op . z ) - ( p2 . y - op . y ) * ( p1 . z - op . z ) ;
result . y = ( p1 . z - op . z ) * ( p2 . x - op . x ) - ( p2 . z - op . z ) * ( p1 . x - op . x ) ;
result . z = ( p1 . x - op . x ) * ( p2 . y - op . y ) - ( p2 . x - op . x ) * ( p1 . y - op . y ) ;
return result ;
}
// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> vec1Ϊʸ<CEAA> <CAB8> 1<EFBFBD> <31> vec2Ϊʸ<CEAA> <CAB8> 2
//
Point multiply ( const Point & vec1 , const Point & vec2 )
{
Point result ;
result . x = vec1 . y * vec2 . z - vec2 . y * vec1 . z ;
result . y = vec1 . z * vec2 . x - vec2 . z * vec1 . x ;
result . z = vec1 . x * vec2 . y - vec2 . x * vec1 . y ;
return result ;
}
// 1.6<EFBFBD> <EFBFBD> <EFBFBD> 㵽<EFBFBD> ߵ ľ<EFBFBD> <EFBFBD> <EFBFBD>
//
// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> p : <20> <> l<> <6C> ֱ<EFBFBD> <D6B1>
//
double ptolDistance ( const Point & p , const Line & l )
{
Point line_vec = sub ( l . e , l . s ) ;
Point point_vec = sub ( p , l . s ) ;
// <20> <> <EFBFBD> ȼ<EFBFBD> <C8BC> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ߶<EFBFBD> ͶӰ<CDB6> <D3B0> <EFBFBD> <EFBFBD>
double project_len = dotMultiply ( line_vec , point_vec ) / length ( line_vec ) ;
// <20> <> <EFBFBD> ݹ<EFBFBD> <DDB9> ɶ<EFBFBD> <C9B6> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ľ<EFBFBD> <C4BE> <EFBFBD>
double distance = sqrt ( pow ( length ( line_vec ) , 2 ) - pow ( project_len , 2 ) ) ;
return distance ;
}
// 1.7<EFBFBD> <EFBFBD> <EFBFBD> 㵽<EFBFBD> ߵ <EFBFBD> ͶӰ<EFBFBD> <EFBFBD>
//
// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> p : <20> <> l : <20> <>
//
Point ptolProjection ( const Point & p , const Line & l )
{
Point line_vec = sub ( l . e , l . s ) ;
Point point_vec = sub ( p , l . s ) ;
Point unit_line_vec = normalize ( line_vec ) ;
// <20> <> <EFBFBD> <EFBFBD> ͶӰ<CDB6> <D3B0> <EFBFBD> <EFBFBD>
double project_len = dotMultiply ( point_vec , unit_line_vec ) ;
// ͶӰ<CDB6> <D3B0>
Point project_p = add ( l . s , mul ( unit_line_vec , project_len ) ) ;
return project_p ;
}
// 1.8<EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ߵ ĶԳƵ<EFBFBD>
//
// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> p : <20> <> l : <20> Գ<EFBFBD> <D4B3> <EFBFBD>
//
Point ptolSymmetry ( const Point & p , const Line & l )
{
// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ֱ<EFBFBD> <D6B1> <EFBFBD> ϵ<EFBFBD> ͶӰ<CDB6> <D3B0>
Point project_p = ptolProjection ( p , l ) ;
// <20> 㵽ͶӰ<CDB6> <D3B0> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
Point project_vec = sub ( project_p , p ) ;
// <20> ԳƵ<D4B3>
Point symmetry_p = add ( p , mul ( project_vec , 2 ) ) ;
return symmetry_p ;
}
// 1.9<EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ƿ<EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
// <20> ߷<EFBFBD> Ϊֱ<CEAA> ߺ <EFBFBD> <DFBA> ߶Σ<DFB6> ֱ<EFBFBD> ߱<EFBFBD> ʾ <EFBFBD> <CABE> <EFBFBD> <EFBFBD> ֱ<EFBFBD> <D6B1> <EFBFBD> Ƿ<C7B7> <F1BEADB9> <EFBFBD>
//
// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> p : <20> <> l : <20> ߶λ<DFB6> <CEBB> <EFBFBD> <EFBFBD> <EFBFBD>
//
bool isponl ( const Point & p , const Line & l )
{
Point line_vec = sub ( l . e , l . s ) ;
Point point_vec1 = sub ( p , l . s ) ;
Point point_vec2 = sub ( p , l . e ) ;
Point mul_vec = multiply ( line_vec , point_vec1 ) ;
double dot = dotMultiply ( point_vec1 , point_vec2 ) ;
// <20> <> <EFBFBD> Ƿ<EFBFBD> <C7B7> <EFBFBD> <EFBFBD> ߶<EFBFBD> <DFB6> <EFBFBD>
if ( l . is_seg )
{
if ( equal ( p , l . s ) | | equal ( p , l . e ) )
return true ;
return ( 0.0 = = length ( mul_vec ) & & dot < 0.0 ) ;
}
// <20> <> <EFBFBD> Ƿ<EFBFBD> <C7B7> <EFBFBD> ֱ<EFBFBD> <D6B1> <EFBFBD> <EFBFBD>
else
{
return ( 0.0 = = length ( mul_vec ) ) ;
}
}
// 1.10<EFBFBD> <EFBFBD> ʸ<EFBFBD> <EFBFBD> <EFBFBD> н<EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
//
// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> op : ʸ<> <CAB8> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> p1 : ʸ<> <CAB8> 1<EFBFBD> ˵<EFBFBD> p2 : ʸ<> <CAB8> 2<EFBFBD> ˵<EFBFBD>
//
double Sin ( const Point & op , const Point & p1 , const Point & p2 )
{
Point vec1 = sub ( p1 , op ) ;
Point vec2 = sub ( p2 , op ) ;
return Sin ( vec1 , vec2 ) ;
}
// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> vec1 ʸ<> <CAB8> 1 vec2 ʸ<> <CAB8> 2
//
double Sin ( const Point & vec1 , const Point & vec2 )
{
return sqrt ( 1.0 - pow ( Cos ( vec1 , vec2 ) , 2 ) ) ;
}
// 1.11<EFBFBD> <EFBFBD> ʸ<EFBFBD> <EFBFBD> <EFBFBD> н<EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
//
// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> op : ʸ<> <CAB8> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> p1 : ʸ<> <CAB8> 1<EFBFBD> ˵<EFBFBD> p2 : ʸ<> <CAB8> 2<EFBFBD> ˵<EFBFBD>
//
double Cos ( const Point & op , const Point & p1 , const Point & p2 )
{
Point vec1 = sub ( p1 , op ) ;
Point vec2 = sub ( p2 , op ) ;
return Cos ( vec1 , vec2 ) ;
}
// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> vec1 ʸ<> <CAB8> 1 vec2 ʸ<> <CAB8> 2
//
double Cos ( const Point & vec1 , const Point & vec2 )
{
Point unit_vec1 = normalize ( vec1 ) ;
Point unit_vec2 = normalize ( vec2 ) ;
return dotMultiply ( unit_vec1 , unit_vec2 ) ;
}
// 1.12<EFBFBD> <EFBFBD> ʸ<EFBFBD> <EFBFBD> <EFBFBD> н<EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
//
// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> op : ʸ<> <CAB8> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> p1 : ʸ<> <CAB8> 1<EFBFBD> ˵<EFBFBD> p2 : ʸ<> <CAB8> 2<EFBFBD> ˵<EFBFBD>
//
double Tan ( const Point & op , const Point & p1 , const Point & p2 )
{
Point vec1 = sub ( p1 , op ) ;
Point vec2 = sub ( p2 , op ) ;
return Tan ( vec1 , vec2 ) ;
}
// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> vec1 ʸ<> <CAB8> 1 vec2 ʸ<> <CAB8> 2
//
double Tan ( const Point & vec1 , const Point & vec2 )
{
double cos = Cos ( vec1 , vec2 ) ;
double sin = Sin ( vec1 , vec2 ) ;
// <20> <> ĸ<EFBFBD> <C4B8> Ϊ<EFBFBD> <CEAA>
if ( 0.0 = = cos )
return - 1 ;
else
return ( sin / cos ) ;
}
// 1.13<EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ļнǽǶ<EFBFBD>
// <20> <> <EFBFBD> <EFBFBD> : op : ʸ<> <CAB8> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> p1 : ʸ<> <CAB8> 1<EFBFBD> ˵<EFBFBD> p2 : ʸ<> <CAB8> 2<EFBFBD> ˵<EFBFBD> is_radian : Ĭ<> <C4AC> Ϊ<EFBFBD> <CEAA> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
//
double Angle ( const Point & op , const Point & p1 , const Point & p2 , bool is_radian )
{
double cos_value = Cos ( op , p1 , p2 ) ;
if ( is_radian )
{
return acos ( cos_value ) ;
}
else
{
return ( acos ( cos_value ) / PI * 180.0 ) ;
}
}
// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> vec1 : ʸ<> <CAB8> 1 vec2 : ʸ<> <CAB8> 2
//
double Angle ( const Point & vec1 , const Point & vec2 , bool is_radian )
{
double cos_value = Cos ( vec1 , vec2 ) ;
if ( is_radian )
{
return acos ( cos_value ) ;
}
else
{
return ( acos ( cos_value ) / PI * 180.0 ) ;
}
}
// 1.14<EFBFBD> <EFBFBD> <EFBFBD> ж<EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ƿ<EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
bool isPointsCollinear ( const Point & p1 , const Point & p2 , const Point & p3 )
{
Line line ( p1 , p2 , false ) ;
// <20> жϵ<D0B6> <CFB5> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ƿ<EFBFBD> <C7B7> <EFBFBD> ǰ<EFBFBD> <C7B0> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ߶<EFBFBD> <DFB6> <EFBFBD>
return isponl ( p3 , line ) ;
}
// 1.15<EFBFBD> <EFBFBD> <EFBFBD> ڣ<EFBFBD> -1<> <31> -1<> <31> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> 1<EFBFBD> <31> 1<EFBFBD> <31> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> n<EFBFBD> <6E> <EFBFBD> <EFBFBD>
//
// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> down_left : <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ½<EFBFBD> up_right: <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ͻ<EFBFBD> num : <20> <> <EFBFBD> ɵ<EFBFBD> <C9B5> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
//
vector < Point > randomGenPoints ( int num )
{
vector < Point > result ;
std : : uniform_real_distribution < double > dist ( - 0.9 , 0.9 ) ;
std : : mt19937 rng ;
rng . seed ( std : : random_device { } ( ) ) ;
for ( int i = 0 ; i < num ; + + i )
{
double rand_x = dist ( rng ) ;
double rand_y = dist ( rng ) ;
result . push_back ( Point ( rand_x , rand_y ) ) ;
}
return result ;
}
// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
// 2.1<EFBFBD> <EFBFBD> <EFBFBD> ߶<EFBFBD> <EFBFBD> Ƿ<EFBFBD> <EFBFBD> ཻ
// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ߶εĶ˵<C4B6> <CBB5> غϻ<D8BA> <CFBB> <EFBFBD> ij<EFBFBD> <C4B3> <EFBFBD> ߶ζ˵<CEB6> <CBB5> <EFBFBD> <EFBFBD> <EFBFBD> һ <EFBFBD> <D2BB> <EFBFBD> ߶<EFBFBD> <DFB6> <EFBFBD> Ҳ<EFBFBD> <D2B2> <EFBFBD> ཻ
// <20> ߶<EFBFBD> <DFB6> ж<EFBFBD> <D0B6> Ƿ<EFBFBD> <C7B7> ཻ<EFBFBD> <E0BDBB> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ֱ<EFBFBD> <D6B1> <EFBFBD> <EFBFBD> <EFBFBD> ൱<EFBFBD> <E0B5B1> <EFBFBD> ж<EFBFBD> <D0B6> Ƿ<EFBFBD> ƽ <EFBFBD> <C6BD>
//
// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> l1 : <20> ߶<EFBFBD> 1 l2 : <20> ߶<EFBFBD> 2 inter_p : <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ཻ<EFBFBD> <E0BDBB> <EFBFBD> ؽ<EFBFBD> <D8BD> <EFBFBD>
//
bool isSegIntersect ( const Line & l1 , const Line & l2 , Point & inter_p )
{
Point line1 = sub ( l1 . e , l1 . s ) ;
Point line2 = sub ( l2 . e , l2 . s ) ;
Point norm1 = normalize ( line1 ) ;
Point norm2 = normalize ( line2 ) ;
// <20> ߶<EFBFBD> <DFB6> ཻ
if ( l1 . is_seg )
{
// <20> ˵<EFBFBD> <CBB5> <EFBFBD> <EFBFBD> ߶<EFBFBD> <DFB6> <EFBFBD>
if ( isponl ( l1 . s , l2 ) )
{
inter_p = l1 . s ;
return true ;
}
if ( isponl ( l1 . e , l2 ) )
{
inter_p = l1 . e ;
return true ;
}
if ( isponl ( l2 . s , l1 ) )
{
inter_p = l2 . s ;
return true ;
}
if ( isponl ( l2 . e , l1 ) )
{
inter_p = l2 . e ;
return true ;
}
// <20> ж<EFBFBD> <D0B6> ߶<EFBFBD> <DFB6> Ƿ<EFBFBD> <C7B7> <EFBFBD> <E0BBA5> <EFBFBD> <EFBFBD>
double dot1 = dotMultiply ( multiply ( sub ( l2 . s , l1 . s ) , line1 ) , multiply ( sub ( l2 . e , l1 . s ) , line1 ) ) ;
double dot2 = dotMultiply ( multiply ( sub ( l1 . s , l2 . s ) , line2 ) , multiply ( sub ( l1 . e , l2 . s ) , line2 ) ) ;
if ( dot1 < 0.0 & & dot2 < 0.0 )
{
double t1 = length ( multiply ( sub ( l1 . s , l2 . s ) , norm2 ) ) / length ( multiply ( norm2 , norm1 ) ) ;
double t2 = length ( multiply ( sub ( l2 . s , l1 . s ) , norm1 ) ) / length ( multiply ( norm1 , norm2 ) ) ;
inter_p = add ( l1 . s , mul ( norm1 , t1 ) ) ;
return true ;
}
else
{
return false ;
}
}
// ֱ<> <D6B1> <EFBFBD> ཻ
else
{
if ( Cos ( line1 , line2 ) = = 1.0 )
return false ;
double t1 = length ( multiply ( sub ( l1 . s , l2 . s ) , norm2 ) ) / length ( multiply ( norm2 , norm1 ) ) ;
double t2 = length ( multiply ( sub ( l2 . s , l1 . s ) , norm1 ) ) / length ( multiply ( norm1 , norm2 ) ) ;
inter_p = add ( l1 . s , mul ( norm1 , t1 ) ) ;
return true ;
}
}
// 2.2<EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ֱ<EFBFBD> ߵ ļн<EFBFBD>
//
//
// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> l1 : <20> ߶<EFBFBD> 1 l2 : <20> ߶<EFBFBD> 2
//
double angleOfLines ( const Line & l1 , const Line & l2 , bool is_radian )
{
Point line1 = sub ( l1 . e , l1 . s ) ;
Point line2 = sub ( l2 . e , l2 . s ) ;
return Angle ( line1 , line2 , is_radian ) ;
}
// 2.3<EFBFBD> <EFBFBD> һ <EFBFBD> ױ<EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ߲<EFBFBD> ֵ
//
// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> s<> <73> <20> <> <EFBFBD> <EFBFBD> e : <20> յ<EFBFBD> inter_num<75> <6D> <EFBFBD> <EFBFBD> ֵ<EFBFBD> <D6B5> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ʼ <EFBFBD> 㣩
// <20> <> <EFBFBD> <EFBFBD> ֵ<EFBFBD> <D6B5> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ʼ <EFBFBD> <CABC>
//
vector < Point > firstOrderBezier ( const Point & s , const Point & e , int inter_num )
{
vector < Point > res ;
res . push_back ( s ) ;
for ( int i = 1 ; i < = inter_num ; + + i )
{
double a1 = double ( i ) / double ( inter_num + 1 ) ;
double a2 = 1.0 - a1 ;
res . push_back ( add ( mul ( s , a2 ) , mul ( e , a1 ) ) ) ;
}
res . push_back ( e ) ;
return res ;
}
// 2.4<EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ױ<EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ߲<EFBFBD> ֵ
//
// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> s<> <73> <20> <> <EFBFBD> <EFBFBD> e : <20> յ<EFBFBD> p : <20> <> <EFBFBD> Ƶ<EFBFBD> inter_num<75> <6D> <EFBFBD> <EFBFBD> ֵ<EFBFBD> <D6B5> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ʼ <EFBFBD> 㣩
// <20> <> <EFBFBD> <EFBFBD> ֵ<EFBFBD> <D6B5> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ʼ <EFBFBD> <CABC>
//
vector < Point > secondOrderBezier ( const Point & s , const Point & e , const Point & p , int inter_num )
{
vector < Point > res ;
res . push_back ( s ) ;
for ( int i = 1 ; i < = inter_num ; + + i )
{
double a = double ( i ) / double ( inter_num + 1 ) ;
double a1 = pow ( a , 2 ) ;
double a2 = 2 * a * ( 1.0 - a ) ;
double a3 = pow ( 1.0 - a , 2 ) ;
res . push_back ( add ( add ( mul ( s , a3 ) , mul ( p , a2 ) ) , mul ( e , a1 ) ) ) ;
}
res . push_back ( e ) ;
return res ;
}
// 2.5<EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ױ<EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ߲<EFBFBD> ֵ
//
// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> s<> <73> <20> <> <EFBFBD> <EFBFBD> e : <20> յ<EFBFBD> p1<70> <31> p2 : <20> <> <EFBFBD> Ƶ<EFBFBD> inter_num<75> <6D> <EFBFBD> <EFBFBD> ֵ<EFBFBD> <D6B5> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ʼ <EFBFBD> 㣩
// <20> <> <EFBFBD> <EFBFBD> ֵ<EFBFBD> <D6B5> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ʼ <EFBFBD> <CABC>
//
vector < Point > thirdOrderBezier ( const Point & s , const Point & e , const Point & p1 , const Point & p2 , int inter_num )
{
vector < Point > res ;
res . push_back ( s ) ;
for ( int i = 1 ; i < = inter_num ; + + i )
{
double a = double ( i ) / double ( inter_num + 1 ) ;
double a1 = pow ( a , 3 ) ;
double a2 = 3 * pow ( a , 2 ) * ( 1.0 - a ) ;
double a3 = 3 * pow ( 1.0 - a , 2 ) * a ;
double a4 = pow ( 1.0 - a , 3 ) ;
res . push_back ( add ( add ( add ( mul ( s , a4 ) , mul ( p1 , a3 ) ) , mul ( p2 , a2 ) ) , mul ( e , a1 ) ) ) ;
}
res . push_back ( e ) ;
return res ;
}
// 2.6<EFBFBD> <EFBFBD> <EFBFBD> ڣ<EFBFBD> -1<> <31> -1<> <31> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> 1<EFBFBD> <31> 1<EFBFBD> <31> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> n<EFBFBD> <6E> <EFBFBD> <EFBFBD>
//
// <20> <> <EFBFBD> <EFBFBD> num : <20> <> Ҫ<EFBFBD> <D2AA> <EFBFBD> ɵ<EFBFBD> <C9B5> ߶ε<DFB6> <CEB5> <EFBFBD> <EFBFBD> <EFBFBD>
//
vector < Line > randomGenLines ( int num )
{
vector < Line > result ;
std : : uniform_real_distribution < double > dist ( - 0.9 , 0.9 ) ;
std : : mt19937 rng ;
rng . seed ( std : : random_device { } ( ) ) ;
for ( int i = 0 ; i < num ; + + i )
{
double rand_sx = dist ( rng ) ;
double rand_sy = dist ( rng ) ;
Point p1 ( rand_sx , rand_sy ) ;
double rand_ex = dist ( rng ) ;
double rand_ey = dist ( rng ) ;
Point p2 ( rand_ex , rand_ey ) ;
result . push_back ( Line ( p1 , p2 , true ) ) ;
}
return result ;
}
// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
// 3.1<EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ƿ<EFBFBD> <EFBFBD> ܹ<EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ߵ <EFBFBD> <DFB5> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> һ <EFBFBD> <D2BB> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
//
// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> t : <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
//
bool isTriangle ( const Triangle & t )
{
return isPointsCollinear ( t . v0 , t . v1 , t . v2 ) ;
}
// 3.2<EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ƿ<EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ڲ<EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ķ<EFBFBD> <EFBFBD> <EFBFBD>
// <20> 㷨<EFBFBD> <E3B7A8> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ӣ<EFBFBD> https://www.cnblogs.com/graphics/archive/2010/08/05/1793393.html
//
// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> t : <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> p : <20> <> Ҫ<EFBFBD> жϵĵ<CFB5> u,v<> ֱ<EFBFBD> Ϊ<EFBFBD> <CEAA> <EFBFBD> ڱ<EFBFBD> ʾ <EFBFBD> <CABE> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ͶӰϵ<D3B0> <CFB5>
//
bool isPointInTriangle ( const Triangle & t , const Point & p , double & u , double & v )
{
Point vec1 = sub ( t . v1 , t . v0 ) ;
Point vec2 = sub ( t . v2 , t . v0 ) ;
Point vec_p = sub ( p , t . v0 ) ;
double dot00 = dotMultiply ( vec1 , vec1 ) ;
double dot01 = dotMultiply ( vec1 , vec2 ) ;
double dot02 = dotMultiply ( vec1 , vec_p ) ;
double dot11 = dotMultiply ( vec2 , vec2 ) ;
double dot12 = dotMultiply ( vec2 , vec_p ) ;
double inverDeno = 1 / ( dot00 * dot11 - dot01 * dot01 ) ;
u = ( dot11 * dot02 - dot01 * dot12 ) * inverDeno ;
v = ( dot00 * dot12 - dot01 * dot02 ) * inverDeno ;
if ( u < 0 | | u > 1 ) return false ;
if ( v < 0 | | v > 1 ) return false ;
if ( u + v < 1 ) return true ;
else return false ;
}
// 3.3<EFBFBD> <EFBFBD> <EFBFBD> 㵽ƽ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ĵ㣬<EFBFBD> <EFBFBD> <EFBFBD> 㵽ƽ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ͶӰ
//
// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> t : <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> p : <20> <>
//
Point ptotProjection ( const Triangle & t , const Point & p )
{
Point vec_p = sub ( p , t . v0 ) ;
Point unit_normal = getUnitNormal ( t ) ;
double ratio = dotMultiply ( vec_p , unit_normal ) ;
return sub ( p , mul ( unit_normal , ratio ) ) ;
}
// 3.4<EFBFBD> <EFBFBD> <EFBFBD> 㵽ƽ <EFBFBD> <EFBFBD> <EFBFBD> ľ<EFBFBD> <EFBFBD> <EFBFBD>
//
// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> t : <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ڵ<EFBFBD> ƽ <EFBFBD> <C6BD> p : <20> <> Ҫ<EFBFBD> жϵĵ<CFB5>
//
double ptotDistance ( const Triangle & t , const Point & p )
{
Point project_p = ptotProjection ( t , p ) ;
return distance ( p , project_p ) ;
}
// 3.5<EFBFBD> <EFBFBD> <EFBFBD> ߶κ<EFBFBD> ƽ <EFBFBD> <EFBFBD> <EFBFBD> Ľ<EFBFBD> <EFBFBD> <EFBFBD>
//
// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> t : <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ƽ <EFBFBD> <C6BD> l : ֱ<> <D6B1>
//
Point ltotInterPoint ( const Triangle & t , const Line & l )
{
Point line_vec = sub ( l . e , l . s ) ;
Point point_vec = sub ( t . v0 , l . s ) ;
Point unit_plane_normal = getUnitNormal ( t ) ;
double ratio = dotMultiply ( point_vec , unit_plane_normal ) / dotMultiply ( unit_plane_normal , line_vec ) ;
return add ( l . s , mul ( line_vec , ratio ) ) ;
}
// 3.6<EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ƽ <EFBFBD> <EFBFBD> <EFBFBD> ĵ<EFBFBD> λ<EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
//
// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> t : <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ƽ <EFBFBD> <C6BD>
//
Point getUnitNormal ( const Triangle & t )
{
Point vec1 = sub ( t . v1 , t . v0 ) ;
Point vec2 = sub ( t . v2 , t . v0 ) ;
return normalize ( multiply ( vec1 , vec2 ) ) ;
}
// 3.7<EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ε<EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
//
// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> t : <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ƽ <EFBFBD> <C6BD>
//
double areaOfTriangle ( const Triangle & t )
{
return ( 0.5 * length ( multiply ( sub ( t . v1 , t . v0 ) , sub ( t . v2 , t . v0 ) ) ) ) ;
}
// <20> ġ<EFBFBD> <C4A1> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
// <20> <> <EFBFBD> <EFBFBD> û<EFBFBD> <C3BB> <EFBFBD> ر<EFBFBD> ˵<EFBFBD> <CBB5> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ĭ<EFBFBD> <C4AC> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ζ<EFBFBD> <CEB6> 㰴<EFBFBD> <E3B0B4> <EFBFBD> <EFBFBD> ʱ<EFBFBD> <CAB1> <EFBFBD> <EFBFBD> <EFBFBD> У <EFBFBD> <D0A3> <EFBFBD> Ϊ<EFBFBD> <CEAA> ά<EFBFBD> 㼴z=0
// 4.1<EFBFBD> <EFBFBD> <EFBFBD> ж϶<EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ζ<EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> İ<EFBFBD> <EFBFBD> <EFBFBD>
//
// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> polygon : <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ε㼯<CEB5> <E3BCAF> flags : <20> <> ־ÿ<D6BE> <C3BF> <EFBFBD> <EFBFBD> <EFBFBD> Ƿ<EFBFBD> <C7B7> <EFBFBD> <EFBFBD> <CDB9>
//
void checkConvex ( const vector < Point > & polygon , vector < bool > & flags )
{
flags . resize ( polygon . size ( ) ) ;
// <20> ҵ<EFBFBD> <D2B5> <EFBFBD> һ <EFBFBD> <D2BB> <EFBFBD> Ķ<EFBFBD> <C4B6> <EFBFBD>
int index = 0 ;
for ( int i = 1 ; i < polygon . size ( ) ; + + i )
{
if ( polygon [ i ] . y < polygon [ index ] . y | |
( polygon [ i ] . y = = polygon [ index ] . y & & polygon [ i ] . x < polygon [ index ] . x ) )
{
index = i ;
}
}
/* <20> ж<EFBFBD> ÿ<EFBFBD> <C3BF> <EFBFBD> <EFBFBD> <EFBFBD> İ<EFBFBD> <EFBFBD> <CDB9>
* ͨ <EFBFBD> <EFBFBD> <EFBFBD> ж <EFBFBD> ǰ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ж <EFBFBD> <EFBFBD> Ƿ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ʱ <EFBFBD> <EFBFBD>
*/
int size = polygon . size ( ) - 1 ;
flags [ index ] = true ;
while ( size )
{
if ( multiply ( polygon [ index ] , polygon [ ( index + 1 ) % size ] , polygon [ ( index + 2 ) % size ] ) . z > = 0 )
{
flags [ ( index + 1 ) % size ] = true ;
}
else
{
flags [ ( index + 1 ) % size ] = false ;
}
index + + ;
size - - ;
}
}
// 4.2<EFBFBD> <EFBFBD> <EFBFBD> ж϶<EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ƿ<EFBFBD> Ϊ<EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
//
// <20> <> <EFBFBD> <EFBFBD> <20> <> polygon : <20> <> <EFBFBD> <EFBFBD> <EFBFBD> Ķ<EFBFBD> <C4B6> <EFBFBD> <EFBFBD> ζ<EFBFBD> <CEB6> <EFBFBD>
//
bool isConvex ( const vector < Point > & polygon )
{
vector < bool > flags ;
// <20> ж<EFBFBD> ÿ<EFBFBD> <C3BF> <EFBFBD> <EFBFBD> <EFBFBD> İ<EFBFBD> <EFBFBD> <CDB9>
checkConvex ( polygon , flags ) ;
// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> һ <EFBFBD> <D2BB> <EFBFBD> 㲻<EFBFBD> <E3B2BB> <EFBFBD> ģ<EFBFBD> <C4A3> <EFBFBD> <EFBFBD> ˶<EFBFBD> <CBB6> <EFBFBD> <EFBFBD> <EFBFBD> Ϊ<EFBFBD> <CEAA>
for ( auto c : flags )
if ( ! c )
return false ;
return true ;
}
// 4.3<EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Χ <EFBFBD> ɵ<EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
//
// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> polygon : <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
//
double areaOfPolygon ( const vector < Point > & polygon )
{
// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ε<EFBFBD> <CEB5> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ƿ<EFBFBD>
int size = polygon . size ( ) ;
if ( size < 3 ) return 0 ;
double area ( 0.0 ) ;
for ( int i = 0 ; i < size ; + + i )
{
area + = polygon [ i ] . y * ( polygon [ ( i - 1 + size ) % size ] . x - polygon [ ( i + 1 ) % size ] . x ) ;
}
return ( area / 2 ) ;
}
// 4.4<EFBFBD> <EFBFBD> <EFBFBD> ж϶<EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ƿ<EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ʱ<EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
//
// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> polygon : <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
//
bool isConterClock ( const vector < Point > & polygon )
{
return areaOfPolygon ( polygon ) > 0 ;
}
// 4.5<EFBFBD> <EFBFBD> <EFBFBD> жϵ<EFBFBD> <EFBFBD> Ƿ<EFBFBD> <EFBFBD> ڶ<EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ڲ<EFBFBD>
// <20> жϴӵ<CFB4> <D3B5> <EFBFBD> <EFBFBD> <EFBFBD> һ <EFBFBD> <D2BB> <EFBFBD> ߶<EFBFBD> <DFB6> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> εĽ<CEB5> <C4BD> <EFBFBD> <EFBFBD> ĸ<EFBFBD> <C4B8> <EFBFBD>
// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ཻ<EFBFBD> <E0BDBB> ż<EFBFBD> <C5BC> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ཻ
//
// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> polygon : <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> p : <20> <> Ҫ<EFBFBD> жϵĵ<CFB5>
//
bool isPointInPolygon ( const vector < Point > & polygon , const Point & p )
{
Point down_left , up_right ;
boxOfPolygon ( polygon , down_left , up_right ) ;
// λ<> ڶ<EFBFBD> <DAB6> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ⲿһ <E2B2BF> <D2BB>
Point out_p = sub ( down_left , Point ( 10.0 , 0.0 ) ) ;
int cnt ( 0 ) ;
Line p_line ( p , out_p , true ) ;
for ( int i = 0 ; i < polygon . size ( ) ; + + i )
{
Point s = polygon [ i ] ;
Point e = polygon [ ( i + 1 ) % polygon . size ( ) ] ;
Line seg ( s , e , true ) ;
Point inter_p ;
if ( isSegIntersect ( p_line , seg , inter_p ) )
{
cnt + + ;
}
}
return ( cnt % 2 = = 1 ) ;
}
// 4.6<EFBFBD> <EFBFBD> <EFBFBD> ж<EFBFBD> <EFBFBD> ߶<EFBFBD> <EFBFBD> Ƿ<EFBFBD> <EFBFBD> ڶ<EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ڲ<EFBFBD>
// <20> ߶<EFBFBD> <DFB6> ڶ<EFBFBD> <DAB6> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ڲ<EFBFBD> <DAB2> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ˵㶼<CBB5> ڶ<EFBFBD> <DAB6> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ҳ<EFBFBD> <D2B2> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ཻ
//
// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> polygon : <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> l <20> <> <20> ߶<EFBFBD>
bool isSegInPolygon ( const vector < Point > & polygon , const Line & l )
{
// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ж<EFBFBD> <D0B6> ߶ζ˵<CEB6> <CBB5> Ƿ<EFBFBD> <C7B7> <EFBFBD> <EFBFBD> ڶ<EFBFBD> <DAB6> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ڲ<EFBFBD>
bool is_s_in = isPointInPolygon ( polygon , l . s ) ;
bool is_e_in = isPointInPolygon ( polygon , l . e ) ;
// Ȼ<> <C8BB> <EFBFBD> ж<EFBFBD> <D0B6> ߶<EFBFBD> <DFB6> Ƿ<EFBFBD> <C7B7> ཻ
if ( is_s_in & & is_e_in )
{
for ( int i = 0 ; i < polygon . size ( ) ; + + i )
{
Point s = polygon [ i ] ;
Point e = polygon [ ( i + 1 ) % polygon . size ( ) ] ;
Line seg ( s , e , true ) ;
Point inter_p ;
if ( isSegIntersect ( l , seg , inter_p ) )
{
return false ;
}
}
return true ;
}
else
{
return false ;
}
}
// 4.7<EFBFBD> <EFBFBD> <EFBFBD> ж<EFBFBD> Բ<EFBFBD> Ƿ<EFBFBD> <EFBFBD> ڶ<EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ڲ<EFBFBD>
// ֻ<> ж<EFBFBD> <D0B6> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> е ı ߶<C4B1> <DFB6> <EFBFBD> Բ<EFBFBD> <D4B2> <EFBFBD> ⲿ<EFBFBD> <E2B2BF> Բ<EFBFBD> Ŵ<EFBFBD> <C5B4> ڶ<EFBFBD> <DAB6> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ڲ<EFBFBD>
//
// <09> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> polygon : <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> c : Բ<> <D4B2> radius <20> <> <20> 뾶
//
bool isCircleInPolygon ( const vector < Point > & polygon , const Point & c , double radius )
{
for ( int i = 0 ; i < polygon . size ( ) ; + + i )
{
const Point & p1 = polygon [ i ] ;
const Point & p2 = polygon [ ( i + 1 ) % polygon . size ( ) ] ;
Line line ( p1 , p2 , true ) ;
if ( segToCircle ( c , radius , line ) ! = 2 )
return false ;
}
return true ;
}
// 4.8<EFBFBD> <EFBFBD> Ѱ<EFBFBD> ҵ㼯<EFBFBD> <EFBFBD> <EFBFBD> 㷨<EFBFBD> <EFBFBD> graham<EFBFBD> 㷨<EFBFBD> <EFBFBD>
// <20> 㷨<EFBFBD> <E3B7A8> <EFBFBD> ӣ<EFBFBD> https://blog.csdn.net/acm_zl/article/details/9342631
//
// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> points <20> <> ƽ <> <C6BD> <EFBFBD> 㼯
//Ŀǰʵ<C7B0> ֵİ汾<C4B0> <E6B1BE> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
vector < Point > findConvexGraham ( const vector < Point > & points )
{
vector < Point > result ;
// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
if ( points . size ( ) < 3 )
return result ;
// Ѱ<> <D1B0> <EFBFBD> <EFBFBD> <EFBFBD> ײ<EFBFBD> <D7B2> ĵ<EFBFBD>
int index = 0 ;
for ( int i = 0 ; i < points . size ( ) ; + + i )
{
if ( points [ i ] . y < points [ index ] . y )
{
index = i ;
}
}
Point convex_p = points [ index ] ;
// <20> <> <EFBFBD> <EFBFBD> ÿ<EFBFBD> <C3BF> <EFBFBD> <EFBFBD> <EFBFBD> ļ<EFBFBD> <C4BC> <EFBFBD>
map < double , int > cos_map ;
Point x_vec ( 1.0 , 0.0 ) ;
for ( int i = 0 ; i < points . size ( ) ; + + i )
{
if ( i ! = index )
{
double cos_value = Cos ( sub ( points [ i ] , convex_p ) , x_vec ) ;
// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ж<EFBFBD> <D0B6> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ͬ<EFBFBD> ļ<EFBFBD> <C4BC> ǣ<EFBFBD> <C7A3> <EFBFBD> ȡ<EFBFBD> <C8A1> Զ<EFBFBD> ĵ<EFBFBD>
if ( cos_map . count ( - cos_value ) ! = 0 )
{
if ( length ( points [ i ] ) > length ( points [ cos_map [ - cos_value ] ] ) )
cos_map [ - cos_value ] = i ;
}
else
cos_map [ - cos_value ] = i ;
}
}
// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ջ
stack < int > result_stack ;
// <20> <> <EFBFBD> 뿪ʼ <EBBFAA> <CABC> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
result_stack . push ( index ) ;
result_stack . push ( cos_map . begin ( ) - > second ) ;
for ( auto iter = ( + + cos_map . begin ( ) ) ; iter ! = cos_map . end ( ) ; + + iter )
{
int first = result_stack . top ( ) ;
result_stack . pop ( ) ;
int second = result_stack . top ( ) ;
Point vec1 = sub ( points [ first ] , points [ second ] ) ;
Point vec2 = sub ( points [ iter - > second ] , points [ first ] ) ;
if ( multiply ( vec1 , vec2 ) . z > = 0 )
result_stack . push ( first ) ;
result_stack . push ( iter - > second ) ;
}
// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ݴ<EFBFBD> ջ<EFBFBD> ж<EFBFBD> ȡ
while ( ! result_stack . empty ( ) )
{
result . push_back ( points [ result_stack . top ( ) ] ) ;
result_stack . pop ( ) ;
}
std : : reverse ( result . begin ( ) , result . end ( ) ) ;
return result ;
}
//// 4.9<EFBFBD> <EFBFBD> Ѱ<EFBFBD> ҵ㼯<EFBFBD> <EFBFBD> <EFBFBD> 㷨<EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ʱ<EFBFBD> 临<EFBFBD> Ӷ<EFBFBD> O(nlogn)
////
//// <09> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> points : ƽ <> <C6BD> <EFBFBD> 㼯
////
//// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ֵ<EFBFBD> <D6B5> <EFBFBD> <EFBFBD> ı ȽϺ <C8BD> <CFBA> <EFBFBD>
//bool cmp(Point a, Point b)
//{
// if (a.x == b.x)
// return a.y < b.y;
// return a.x < b.x;
//}
//vector<Point> findConvex(const vector<Point>& points)
//{
// vector<Point> result;
// if (points.size() < 3)
// return result;
//
// vector<Point> tmp_points = points;
// // <20> <> <EFBFBD> Ƚ<EFBFBD> <C8BD> <EFBFBD> <EFBFBD> е 㰴<D0B5> <E3B0B4> <EFBFBD> ֵ<EFBFBD> <D6B5> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
// sort(tmp_points.begin(), tmp_points.end(), cmp);
//
// // <20> <> <EFBFBD> <CDB9>
// vector<Point> upper_hull;
// // <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> һ <EFBFBD> <D2BB> <EFBFBD> ͵ڶ<CDB5> <DAB6> <EFBFBD> <EFBFBD> <EFBFBD>
// upper_hull.push_back(tmp_points[0]);
// upper_hull.push_back(tmp_points[1]);
// for (int i = 2; i < tmp_points.size(); ++i)
// {
// upper_hull.push_back(tmp_points[i]);
// while (upper_hull.size() > 2 && multiply(sub(upper_hull[upper_hull.size() - 2], upper_hull[upper_hull.size() - 3]), sub(upper_hull[upper_hull.size() - 1], upper_hull[upper_hull.size() - 3])).z >= 0)
// {
// upper_hull.erase(upper_hull.end() - 2);
// }
// }
// // <20> <> <EFBFBD> <CDB9>
// vector<Point> lower_hull;
// // <20> <> <EFBFBD> 뵹<EFBFBD> <EBB5B9> <EFBFBD> <EFBFBD> һ <EFBFBD> ڶ<EFBFBD> <DAB6> <EFBFBD> <EFBFBD> <EFBFBD>
// lower_hull.push_back(tmp_points[tmp_points.size() - 1]);
// lower_hull.push_back(tmp_points[tmp_points.size() - 2]);
// for (int i = tmp_points.size() - 3; i >= 0; --i)
// {
// lower_hull.push_back(tmp_points[i]);
// while (lower_hull.size() > 2 && multiply(sub(lower_hull[lower_hull.size() - 2], lower_hull[lower_hull.size() - 3]), sub(lower_hull[lower_hull.size() - 1], lower_hull[lower_hull.size() - 3])).z >= 0)
// {
// lower_hull.erase(lower_hull.end() - 1);
// }
// }
// // ɾ<> <C9BE> <EFBFBD> ظ<EFBFBD> <D8B8> <EFBFBD>
// lower_hull.erase(lower_hull.begin());
// lower_hull.erase(lower_hull.end() - 1);
//
// // <20> ϲ <EFBFBD> <CFB2> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <CDB9>
// upper_hull.insert(upper_hull.end(), lower_hull.begin(), lower_hull.end());
//
// result = upper_hull;
//
// return result;
//}
// 4.10<EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
// <20> 㷨ԭ<E3B7A8> <D4AD> <EFBFBD> <EFBFBD> <EFBFBD> ӣ<EFBFBD>
//
// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> polygon <20> <> <20> <EFBFBD> <F2B5A5B6> <EFBFBD> <EFBFBD> <EFBFBD>
//
Point centerOfPolygon ( const vector < Point > & polygon )
{
double polygon_area ( 0.0 ) ;
Point center ;
Point origin ;
for ( int i = 0 ; i < polygon . size ( ) ; + + i )
{
Point curr_p = polygon [ i ] ;
Point next_p = polygon [ ( i + 1 ) % polygon . size ( ) ] ;
Triangle t ( origin , curr_p , next_p ) ;
double curr_area = areaOfTriangle ( t ) ;
polygon_area + = curr_area ;
center = add ( center , mul ( div ( add ( curr_p , next_p ) , 3 ) , curr_area ) ) ;
}
center = div ( center , polygon_area ) ;
return center ;
}
// 4.11<EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ϶<EFBFBD> <EFBFBD> ڶ<EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ڲ<EFBFBD> <EFBFBD> <EFBFBD> һ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
// <20> <> <EFBFBD> <EFBFBD> 1: ÿ<> <C3BF> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> һ <EFBFBD> <D2BB> <EFBFBD> <CDB9> <EFBFBD> 㣬
// x<> <78> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> С <EFBFBD> ĵ<EFBFBD> <C4B5> ϶<EFBFBD> <CFB6> <EFBFBD> <EFBFBD> <CDB9> <EFBFBD> 㣬y<E3A3AC> <79> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> С <EFBFBD> ĵ<EFBFBD> <C4B5> ϶<EFBFBD> <CFB6> <EFBFBD> <EFBFBD> <CDB9> <EFBFBD> <EFBFBD>
// <20> <> <EFBFBD> <EFBFBD> 2<EFBFBD> <32> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> >= 4<> ļ<C4BC> <F2B5A5B6> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> һ <EFBFBD> <D2BB> <EFBFBD> Խ<EFBFBD> <D4BD> <EFBFBD>
//
// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> polygon <20> <> <20> <EFBFBD> <F2B5A5B6> <EFBFBD> <EFBFBD> <EFBFBD>
//
Point pointInPolygon ( const vector < Point > & polygon )
{
// <> <CDB9> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
int index = 0 ;
Point convex_p = polygon [ 0 ] ;
// Ѱ<> <D1B0> һ <EFBFBD> <D2BB> <EFBFBD> <CDB9> <EFBFBD> <EFBFBD>
for ( int i = 0 ; i < polygon . size ( ) ; + + i )
{
if ( polygon [ i ] . y < convex_p . y )
{
index = i ;
convex_p = polygon [ i ] ;
}
}
// <20> <> ȡ<C8A1> <CDB9> <EFBFBD> <EFBFBD> ǰ<EFBFBD> <C7B0> һ <EFBFBD> <D2BB> <EFBFBD> <EFBFBD>
int size = polygon . size ( ) ;
Point pre_p = polygon [ ( index - 1 + size ) % size ] ;
Point next_p = polygon [ ( index + 1 ) % size ] ;
Triangle t ( convex_p , pre_p , next_p ) ;
double min_d = double ( INT_MAX ) ;
bool flag = false ;
Point min_p ;
for ( int i = 0 ; i < polygon . size ( ) ; + + i )
{
if ( i = = index | | i = = ( ( index - 1 + size ) % size ) | | i = = ( ( index + 1 ) % size ) )
continue ;
flag = true ;
if ( distance ( convex_p , polygon [ i ] ) < min_d )
{
min_p = polygon [ i ] ;
min_d = distance ( convex_p , polygon [ i ] ) ;
}
}
// <20> <> <EFBFBD> <EFBFBD> û<EFBFBD> ж<EFBFBD> <D0B6> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ڲ<EFBFBD> <DAB2> <EFBFBD> <EFBFBD> <EFBFBD> ǰ<EFBFBD> <C7B0> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> е <EFBFBD>
if ( ! flag )
{
return div ( add ( pre_p , next_p ) , 2 ) ;
}
// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <CDB9> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> е <EFBFBD>
return div ( add ( convex_p , min_p ) , 2 ) ;
}
// 4.12<EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ȡ<EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> εİ<EFBFBD> Χ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ε<EFBFBD> <CEB5> <EFBFBD> С <EFBFBD> <D0A1> Χ <EFBFBD> У <EFBFBD> <D0A3> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> º<EFBFBD> <C2BA> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ʾ
//
// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> polygon : <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> down_left : <20> <> <EFBFBD> µ<EFBFBD> up_right : <20> <> <EFBFBD> ϵ<EFBFBD>
//
void boxOfPolygon ( const vector < Point > & polygon , Point & down_left , Point & up_right )
{
double max_x = double ( INT_MIN ) , min_x = double ( INT_MAX ) ;
double max_y = double ( INT_MIN ) , min_y = double ( INT_MAX ) ;
for ( auto c : polygon )
{
max_x = ( c . x > max_x ) ? c . x : max_x ;
min_x = ( c . x < min_x ) ? c . x : min_x ;
max_y = ( c . y > max_y ) ? c . y : max_y ;
min_y = ( c . y < min_y ) ? c . y : min_y ;
}
down_left = Point ( min_x , min_y ) ;
up_right = Point ( max_x , max_y ) ;
}
// <20> 塢Բ
// 5.1<EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Բ<EFBFBD> Ĺ<EFBFBD> ϵ
//
// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> c: Բ<> <D4B2> radiuns <20> <> Բ<> İ뾶 p : <20> жϵĵ<CFB5>
// <20> <> <EFBFBD> <EFBFBD> ֵ <20> <> 0 <20> <> Բ<> <D4B2> 1 <20> <> Բ<> <D4B2> 2<> <32> Բ<> <D4B2>
//
int pointToCircle ( const Point & c , double radius , const Point & p )
{
double ptoc_d = distance ( c , p ) ;
if ( ptoc_d < radius )
return 0 ;
else if ( ptoc_d = = radius )
return 1 ;
else
return 2 ;
}
// 5.2<EFBFBD> <EFBFBD> ֱ<EFBFBD> ߺ <EFBFBD> Բ<EFBFBD> Ĺ<EFBFBD> ϵ
//
// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> c: Բ<> <D4B2> radiuns <20> <> Բ<> İ뾶 l : <20> жϵ<D0B6> ֱ<EFBFBD> <D6B1>
// <20> <> <EFBFBD> <EFBFBD> ֵ <20> <> 0 <20> <> <20> ཻ 1 <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> 2<> <32> <20> <> <EFBFBD> <EFBFBD>
//
int lineToCircle ( const Point & c , double radius , const Line & l )
{
double ctol_d = ptolDistance ( c , l ) ;
if ( ctol_d < radius )
return 0 ;
else if ( ctol_d = = radius )
return 1 ;
else
return 2 ;
}
// 5.3<EFBFBD> <EFBFBD> <EFBFBD> ߶κ<EFBFBD> Բ<EFBFBD> Ĺ<EFBFBD> ϵ
//
// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> c: Բ<> <D4B2> radiuns <20> <> Բ<> İ뾶 l : <20> жϵ<D0B6> <CFB5> ߶<EFBFBD>
// <20> <> <EFBFBD> <EFBFBD> ֵ <20> <> 0 <20> <> Բ<> <D4B2> 1 <20> <> <20> <> Բ<EFBFBD> ཻ 2<> <32> Բ<> <D4B2>
//
int segToCircle ( const Point & c , double radius , const Line & l )
{
double ctol_d = ptolDistance ( c , l ) ;
if ( ctol_d > radius )
return 2 ;
else if ( ctol_d = = radius )
return 1 ;
else
{
Point project_p = ptolProjection ( c , l ) ;
if ( isponl ( project_p , l ) )
return 1 ;
else
return 2 ;
}
}
// 5.4<EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Բ֮<EFBFBD> <EFBFBD> <EFBFBD> Ĺ<EFBFBD> ϵ
//
// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> c1 : Բ1Բ<31> ģ<EFBFBD> r1 Բ1<D4B2> 뾶 c2 : Բ2Բ<32> ģ<EFBFBD> r2 Բ2<D4B2> 뾶
// <20> <> <EFBFBD> <EFBFBD> ֵ<EFBFBD> <D6B5> 0 <20> <> <EFBFBD> ں<EFBFBD> 1<> <31> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> 2<> <32> <EFBFBD> ཻ 3<> <33> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> 4<> <34> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
//
int circleToCircle ( const Point & c1 , double r1 , const Point & c2 , double r2 )
{
double ctoc_d = distance ( c1 , c2 ) ;
if ( ctoc_d < abs ( r1 - r2 ) )
return 0 ;
else if ( ctoc_d = = abs ( r1 - r2 ) )
return 1 ;
else if ( ctoc_d > abs ( r1 - r2 ) & & ctoc_d < ( r1 + r2 ) )
return 2 ;
else if ( ctoc_d = = ( r1 + r2 ) )
return 3 ;
else if ( ctoc_d > ( r1 + r2 ) )
return 4 ;
}
}