理论:http://mindlee.net/2011/11/27/computational-geometry/
http://blog.chinaunix.net/uid-12127321-id-2957853.html
三角形的内心公式:
两直线交点:
//hdu 1392 凸包
#include <cstdio>
#include <algorithm>
#include <cmath>
const double esp=1e-8;
const long N=1100;
struct Point{
double x,y;
}point[N],stack[N];
long n,top;
double Det(const Point &p1,const Point &p2,const Point &p3){
return (p2.x-p1.x)*(p3.y-p1.y)-(p3.x-p1.x)*(p2.y-p1.y);
}
double Dis(const Point &p1,const Point &p2){
return sqrt((p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y));
}
int cmp(Point &a,Point &b){
double k=Det(point[0],a,b);
if (k>0 ||(k==0 && Dis(point[0],a)<Dis(point[0],b)))
return 1;
return 0;
}
void Convert(){
for (long i=1;i<n;++i)
if (point[i].y<point[0].y || (point[i].y==point[0].y && point[i].x<point[0].x)){
Point temp=point[0]; point[0]=point[i]; point[i]=temp;
}
std::sort(point+1,point+n,cmp);
stack[0]=point[0]; stack[1]=point[1]; stack[2]=point[2]; top=2;
for (long i=3;i<n;++i){
while (Det(stack[top-1],stack[top],point[i])<=0 && top>=2)
top--;
stack[++top]=point[i];
}
}
int main(){
while (~scanf("%d",&n)&&n){
for (long i=0;i<n;++i)
scanf("%lf%lf",&point[i].x,&point[i].y);
if (n==1){
printf("0.00\n");
continue;
}
if (n==2){
printf("%.2lf\n",Dis(point[0],point[1]));
continue;
}
Convert();
double ans=0;
for (long i=1;i<=top;++i) ans+=Dis(stack[i-1],stack[i]);
ans+=Dis(stack[top],stack[0]);
printf("%.2f\n",ans);
}
return 0;
}
//poj 1279 半平面交
#include <cstdio>
#include <cmath>
#define Exp 1e-8
const long N=1600;
struct Point{
Point(double x=0.0,double y=0.0):x(x),y(y){}
double x,y;
}point[N],p[N],q[N];
long n,pcnt,qcnt;
void init(){
for (long i=1;i<=n;++i) p[i]=point[i];
p[n+1]=point[1]; p[0]=point[n];
pcnt=n; point[n+1]=point[1];
}
inline double Det(Point p1,Point p2,Point p3){
return (p2.x-p1.x)*(p3.y-p1.y)-(p3.x-p1.x)*(p2.y-p1.y);
}
inline Point Intersect(Point p1,Point p2,Point p3,Point p4){
double s1,s2;
Point temp;
s1=Det(p1,p2,p3); s2=Det(p1,p2,p4);
temp.x=(s1*p4.x-s2*p3.x)/(s1-s2);
temp.y=(s1*p4.y-s2*p3.y)/(s1-s2);
return temp;
}
void cut(Point p1,Point p2){
qcnt=0;
for (long i=1;i<=pcnt;++i)
if (Det(p1,p2,p[i])<=Exp) q[++qcnt]=p[i];
else{
if (Det(p1,p2,p[i-1])<Exp) q[++qcnt]=Intersect(p1,p2,p[i],p[i-1]);
if (Det(p1,p2,p[i+1])<Exp) q[++qcnt]=Intersect(p1,p2,p[i],p[i+1]);
}
for (long i=1;i<=qcnt;++i) p[i]=q[i];
p[qcnt+1]=q[1]; p[0]=q[qcnt];
pcnt=qcnt;
}
void solve(){
init();
for (long i=1;i<=n;++i)
cut(point[i],point[i+1]);
}
inline double getArea(){
//if (pcnt<=2) return 0.0;
double ans=0.0;
for (long i=1;i<=pcnt;++i)
ans+=Det(Point(0.0,0.0),p[i],p[i+1])/2.0;
return ans;
}
int main(){
long t;
scanf("%d",&t);
while (t--){
scanf("%d",&n);
for (long i=1;i<=n;++i) scanf("%lf%lf",&point[i].x,&point[i].y);
solve();
/*if (pcnt==0) printf("NO\n");
else printf("YES\n");*/
printf("%.2f\n",fabs(getArea()));
}
return 0;
}
//poj 3714 分治法求最近点对
#include <cstdio>
#include <cmath>
#include <algorithm>
#define Exp 1e-8;
const double inf=1e100;
using namespace std;
const long N=620000;
struct Point{
double x,y;
bool flag;
}point[N];
long n,pt[N];
double Dis(Point p1,Point p2){
if (p1.flag!=p2.flag)
return sqrt((p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y));
else return inf;
}
double solve(long l,long r){
if (r==l+1) return Dis(point[l],point[r]);
if (r==l+2) return min(min(Dis(point[l],point[l+1]),Dis(point[l],point[r])),
Dis(point[l+1],point[r]));
long m=(l+r)>>1,cnt=0,cnt_mid;
double temp=min(solve(l,m),solve(m+1,r));
if (temp==0) return 0;
for (long i=m;point[m].x-point[i].x<temp && i>=l;--i)
pt[++cnt]=i;
cnt_mid=cnt;
for (long i=m+1;point[i].x-point[m].x<temp && i<=r;++i)
pt[++cnt]=i;
for (long i=1;i<=cnt_mid;++i)
for (long j=cnt_mid+1;j<=cnt;++j)
temp=min(temp,Dis(point[pt[i]],point[pt[j]]));
return temp;
}
long fuck(Point a,Point b){
return a.x<b.x;
}
int main(){
//freopen("data.in","r",stdin);
//freopen("data.out","w",stdout);
long t; scanf("%d",&t);
while (t--){
scanf("%d",&n);
for (long i=1;i<=n;++i){
scanf("%lf%lf",&point[i].x,&point[i].y);
point[i].flag=1;
}
for (long i=n+1;i<=2*n;++i){
scanf("%lf%lf",&point[i].x,&point[i].y);
point[i].flag=0;
}
n*=2;
sort(point+1,point+1+n,fuck);
printf("%.3f\n",solve(1,n));
}
return 0;
}
//poj3714 暴力法 最近点对
#include <cstdio>
#include <cmath>
#include <algorithm>
#define Exp 1e-8;
using namespace std;
const double inf=1e100;
const long N=610000;
struct Point{
double x,y;
int flag;
}point[N];
long n;
inline double Dis(Point p1,Point p2){
if (p1.flag!=p2.flag)
return sqrt((p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y));
else
return inf;
}
long cmp(Point a,Point b){
if (a.x==b.x && a.y<b.y) return 1;
return a.x<b.x;
}
int main(){
long t;
scanf("%d",&t);
while (t--){
scanf("%d",&n);
for (long i=1;i<=n;++i){
scanf("%lf%lf",&point[i].x,&point[i].y);
point[i].flag=1;
}
for (long i=n+1;i<=2*n;++i){
scanf("%lf%lf",&point[i].x,&point[i].y);
point[i].flag=0;
}
n*=2;
sort(point+1,point+1+n,cmp);
double ans=inf;
for (long i=1;i<n;++i)
for (long j=i+1;j<=n;++j){
ans=min(ans,Dis(point[i],point[j]));
if (point[j].x-point[i].x>ans)
break;
}
printf("%.3f\n",ans);
}
return 0;
}
hdu4720 三角形的外心
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const double eps=1e-8;
struct Point{
double x,y;
Point(double x=0.0,double y=0.0):x(x),y(y){};
};
Point get_center(Point p1,Point p2,Point p3){
Point C;
double t1,t2,t3;
t1=p1.x*p1.x+p1.y*p1.y-p2.x*p2.x-p2.y*p2.y;
t2=p1.x*p1.x+p1.y*p1.y-p3.x*p3.x-p3.y*p3.y;
t3=2*(p1.x-p2.x)*(p1.y-p3.y)-2*(p1.x-p3.x)*(p1.y-p2.y);
C.x=((p1.y-p3.y)*t1-(p1.y-p2.y)*t2)/t3;
C.y=-((p1.x-p3.x)*t1-(p1.x-p2.x)*t2)/t3;
return C;
}
double dis(Point p1,Point p2){
return (p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y);
}
int sgn(double x){
return (x>eps)-(x<-eps);
}
Point p[10];
int t;
int main(){
scanf("%d",&t);
for (int k=1;k<=t;++k){
for (int i=1;i<=4;++i) scanf("%lf%lf",&p[i].x,&p[i].y);
Point C=get_center(p[1],p[2],p[3]);
double R=dis(C,p[1]);
for (int i=1;i<3;++i)
for (int j=i+1;j<4;++j){
Point tmp=Point((p[i].x+p[j].x)/2.0,(p[i].y+p[j].y)/2.0);
double tmp_r=max(dis(tmp,p[6-i-j]),dis(p[i],p[j])/4);
if (sgn(R-tmp_r)==1){
C=tmp; R=tmp_r;
}
}
double Dis=dis(p[4],C);
if (sgn(Dis-R)==1) printf("Case #%d: Safe\n",k);
else printf("Case #%d: Danger\n",k);
}
return 0;
}