计算几何.docx

上传人:b****3 文档编号:5054884 上传时间:2022-12-12 格式:DOCX 页数:50 大小:26.24KB
下载 相关 举报
计算几何.docx_第1页
第1页 / 共50页
计算几何.docx_第2页
第2页 / 共50页
计算几何.docx_第3页
第3页 / 共50页
计算几何.docx_第4页
第4页 / 共50页
计算几何.docx_第5页
第5页 / 共50页
点击查看更多>>
下载资源
资源描述

计算几何.docx

《计算几何.docx》由会员分享,可在线阅读,更多相关《计算几何.docx(50页珍藏版)》请在冰豆网上搜索。

计算几何.docx

计算几何

//计算几何(二维)

#include

#include

#include

#include

usingnamespacestd;

constdoubleEPSILON=1e-8;

constdoubleINFINITY=1e10;

constdoublePI=3.14159265358979323846;

inlinedoubleDegToRad(doubledeg){return(deg*PI/180.0);}

inlinedoubleRadToDeg(doublerad){return(rad*180.0/PI);}

inlinedoubleSin(doubledeg){returnsin(DegToRad(deg));}

inlinedoubleCos(doubledeg){returncos(DegToRad(deg));}

inlinedoubleTan(doubledeg){returntan(DegToRad(deg));}

inlinedoubleArcSin(doubleval){returnRadToDeg(asin(val));}

inlinedoubleArcCos(doubleval){returnRadToDeg(acos(val));}

inlinedoubleArcTan(doubleval){returnRadToDeg(atan(val));}

structPOINT

{

doublex,y;

POINT(){};

POINT(double_x,double_y)

{

x=_x;

y=_y;

}

booloperator==(constPOINT&_P)const

{

returnfabs(x-_P.x)<=EPSILON&&fabs(y-_P.y)<=EPSILON;

}

booloperator!

=(constPOINT&_P)const

{

return!

(fabs(x-_P.x)<=EPSILON&&fabs(y-_P.y)<=EPSILON);

}

booloperator<(constPOINT&_P)const

{

if(y!

=_P.y)returny<_P.y;

elsereturnx<_P.x;

};

POINToperator+(constPOINT&_P)const

{

returnPOINT(x+_P.x,y+_P.y);

}

POINToperator-(constPOINT&_P)const

{

returnPOINT(x-_P.x,y-_P.y);

}

doubleAngle(constPOINT&O)//返回点关于O点的极坐标

{

doublex1=x-O.x;

doubley1=y-O.y;

if(fabs(x1)<=EPSILON)

{

if(y1>0.0)return90.0;

elsereturn270.0;

}

if(fabs(y1)<=EPSILON)

{

if(x1>0.0)return0.0;

elsereturn180.0;

}

doubleangle=ArcTan(fabs(y1/x1));

if(x1>0)

{

returny1>0?

angle:

360.0-angle;

}

else

{

returny1>0?

180.0-angle:

180.0+angle;

}

}

doubleAngle()//默认O点为(0,0)

{

returnAngle(POINT(0,0));

}

};

inlinedoubleDistance(constPOINT&a,constPOINT&b)

{

returnsqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));

}

structSEGMENT

{

POINTa,b;

SEGMENT(){};

SEGMENT(POINT_a,POINT_b)

{

a=_a;

b=_b;

};

booloperator==(constSEGMENT&_SEGMENT)const

{

returna==_SEGMENT.a&&b==_SEGMENT.b;

};

};

//Ax+By+C=0

structLINE

{

POINTa,b;

doubleA,B,C;

LINE(POINT_a,POINT_b)

{

a=_a;

b=_b;

A=b.y-a.y;

B=a.x-b.x;

C=b.x*a.y-a.x*b.y;

};

LINE(double_A,double_B,double_C)

{

A=_A;

B=_B;

C=_C;

};

booloperator==(constLINE&_L)const

{

returnfabs(A*_L.B-_L.A*B)<=EPSILON&&

fabs(A*_L.C-_L.A*C)<=EPSILON&&

fabs(B*_L.C-_L.B*C)<=EPSILON;

};

};

//叉乘,右手螺旋向上为正

doubleCross(constSEGMENT&p,constSEGMENT&q)

{

return(p.b.x-p.a.x)*(q.b.y-q.a.y)-(q.b.x-q.a.x)*(p.b.y-p.a.y);

}

doubleCross(constPOINT&a,constPOINT&b,constPOINT&o)

{

return(a.x-o.x)*(b.y-o.y)-(b.x-o.x)*(a.y-o.y);

}

intSign_Cross(constSEGMENT&p,constSEGMENT&q)//返回叉乘的符号

{

doublet=Cross(p,q);

if(t>EPSILON)return1;

elseif(t<-EPSILON)return-1;

elsereturn0;

}

intSign_Cross(constPOINT&a,constPOINT&b,constPOINT&o)//返回叉乘的符号

{

doublet=Cross(a,b,o);

if(t>EPSILON)return1;

elseif(t<-EPSILON)return-1;

elsereturn0;

}

//点到直线的垂足

POINTPedal_Point(constPOINT&P,constLINE&L)

{

if(fabs(L.B)<=EPSILON)//如果直线平行Y轴

{

returnPOINT(-L.C/L.A,P.y);

}

elseif(fabs(L.A)<=EPSILON)//如果直线平行X轴

{

returnPOINT(P.x,-L.C/L.B);

}

else

{

doublek1=-L.A/L.B;

doublek2=-1/k1;

doubleb1=-L.C/L.B;

doubleb2=P.y-k2*P.x;

doublex=(b2-b1)/(k1-k2);

doubley=k2*x+b2;

returnPOINT(x,y);

}

}

//p点关于直线L的对称点

POINTSymmetrical_Point_Of_Line(POINTP,LINEL)

{

POINT_P;

doubled;

d=L.A*L.A+L.B*L.B;

_P.x=(L.B*L.B*P.x-L.A*L.A*P.x-

2.0*L.A*L.B*P.y-2.0*L.A*L.C)/d;

_P.y=(L.A*L.A*P.y-L.B*L.B*P.y-

2.0*L.A*L.B*P.x-2.0*L.B*L.C)/d;

return_P;

}

boolIs_On_Segment(constPOINT&P,constSEGMENT&S)

{

if(P==S.a||P==S.b)returntrue;

else

{

if(P.x

P.x>min(S.a.x,S.b.x)-EPSILON&&

P.y

P.y>min(S.a.y,S.b.y)-EPSILON&&

fabs(Cross(S.b,P,S.a))<=EPSILON)

{

returntrue;

}

}

returnfalse;

}

//点到线段的最近点

POINTNearest_Point_To_Segment(constPOINT&P,constSEGMENT&S)

{

LINEL(S.a,S.b);

POINTI=Pedal_Point(P,L);

if(Is_On_Segment(I,S))

{

returnI;

}

else

{

doublet1=Distance(P,S.a);

doublet2=Distance(P,S.b);

returnt1

S.a:

S.b;

}

}

//直线相交的交点

POINTIntersection_Point(constLINE&L1,constLINE&L2)

{

POINTI;

I.x=-(L2.B*L1.C-L1.B*L2.C)/(L1.A*L2.B-L2.A*L1.B);

I.y=(L2.A*L1.C-L1.A*L2.C)/(L1.A*L2.B-L2.A*L1.B);

returnI;

}

POINTIntersection_Point(constSEGMENT&s1,constSEGMENT&s2)

{

LINEl1(s1.a,s1.b);

LINEl2(s2.a,s2.b);

returnIntersection_Point(l1,l2);

}

boolIs_Intersect(constSEGMENT&u,constSEGMENT&v)

{

if((max(u.a.x,u.b.x)>min(v.a.x,v.b.x)-EPSILON)&&

(max(v.a.x,v.b.x)>min(u.a.x,u.b.x)-EPSILON)&&

(max(u.a.y,u.b.y)>min(v.a.y,v.b.y)-EPSILON)&&

(max(v.a.y,v.b.y)>min(u.a.y,u.b.y)-EPSILON))

{

intt1=Sign_Cross(v.a,u.b,u.a);

intt2=Sign_Cross(u.b,v.b,u.a);

intt3=Sign_Cross(u.a,v.b,v.a);

intt4=Sign_Cross(v.b,u.b,v.a);

return(t1*t2>0)&&(t3*t4>0);

}

returnfalse;

}

boolIs_Touch(constSEGMENT&u,constSEGMENT&v)

{

if((max(u.a.x,u.b.x)>=min(v.a.x,v.b.x)-EPSILON)&&

(max(v.a.x,v.b.x)>=min(u.a.x,u.b.x)-EPSILON)&&

(max(u.a.y,u.b.y)>=min(v.a.y,v.b.y)-EPSILON)&&

(max(v.a.y,v.b.y)>=min(u.a.y,u.b.y)-EPSILON))

{

intt1=Sign_Cross(v.a,u.b,u.a);

intt2=Sign_Cross(u.b,v.b,u.a);

intt3=Sign_Cross(u.a,v.b,v.a);

intt4=Sign_Cross(v.b,u.b,v.a);

if(t1*t2==0)

{

return(t3*t4>=0);

}

elsereturn(t1*t2>0&&t3*t4==0);

}

returnfalse;

}

//判断线断P和直线Q是否相交,端点重合算相交

boolIs_Intersect(constSEGMENT&p,constLINE&q)

{

SEGMENTp1,p2,q0;

p1.a=q.a;p1.b=p.a;

p2.a=q.a;p2.b=p.b;

q0.a=q.a;q0.b=q.b;

intt1=Sign_Cross(p1,q0);

intt2=Sign_Cross(q0,p2);

return(t1*t2>=0);

}

//判断两条直线是否平行

boolIs_Parallel(constLINE&L1,constLINE&L2)

{

//共线不算平行

//return(L1.A*L2.B==L2.A*L1.B)&&

//((L1.A*L2.C!

=L2.A*L1.C)||(L1.B*L2.C!

=L2.B*L1.C));

//共线算平行

return(fabs(L1.A*L2.B-L2.A*L1.B)<=EPSILON);

}

//判断两条直线是否相交

boolIs_Intersect(constLINE&L1,constLINE&L2)

{

return!

(L1==L2)&&!

(Is_Parallel(L1,L2));

}

//角(AOB)的平分线

LINEAngle_Bisector(POINTA,constPOINT&O,POINTB)

{

doubleangle1=A.Angle(O);

doubleangle2=B.Angle(O);

doubleangle3=(angle2-angle1)/2.0+angle1;

if(fabs(angle3-90.0)<=EPSILON||fabs(angle3-270.0)<=EPSILON)

{

POINTP1(O.x,O.y+1.0);

returnLINE(P1,O);

}

doublek=Tan(angle3);

POINTP2(O.x+1.0,O.y+k);

returnLINE(P2,O);

}

//线段的垂直平分线

LINESEGMENT_Bisector(constSEGMENT&S)

{

POINTO((S.a.x+S.b.x)/2.0,(S.a.y+S.b.y)/2.0);

returnAngle_Bisector(S.a,O,S.b);

}

//从X轴旋转到S的角度

doubleAngle(constSEGMENT&S)

{

doublex1=S.b.x-S.a.x;

doubley1=S.b.y-S.a.y;

if(fabs(x1)<=EPSILON)

{

if(y1>0.0)return0.5*PI;

elsereturn1.5*PI;

}

if(fabs(y1)<=EPSILON)

{

if(x1>0.0)return0.0;

elsereturnPI;

}

doubleangle=atan(fabs(y1/x1));

if(x1>0)

{

returny1>0?

angle:

2.0*PI-angle;

}

else

{

returny1>0?

PI-angle:

PI+angle;

}

}

//线段s1与s2的夹角

doubleAngle_Between(constSEGMENT&s1,constSEGMENT&s2)

{

//注意误差,若太接近,就另为0

doubleangle=Angle(s2)-Angle(s1);

if(fabs(angle)

if(angle>2.0*PI)angle=0.0;

elseif(angle<0.0)angle+=2.0*PI;

returnangle;

}

//返回两线段的重合部分

vectorCoincidence_With_Segment(constSEGMENT&s1,constSEGMENT&s2)

{

vectorS;

SEGMENTs;

if(Is_Touch(s1,s2))

{

if(Is_On_Segment(s1.a,s2)&&Is_On_Segment(s1.b,s2))

{

S.push_back(s1);

}

elseif(Is_On_Segment(s2.a,s1)&&Is_On_Segment(s2.b,s1))

{

S.push_back(s2);

}

elseif(Is_On_Segment(s2.b,s1)&&Is_On_Segment(s1.b,s2)&&s2.b!

=s1.b)

{

s.a=s2.b;

s.b=s1.b;

S.push_back(s);

}

elseif(Is_On_Segment(s2.a,s1)&&Is_On_Segment(s1.a,s2)&&s2.a!

=s1.a)

{

s.a=s2.a;

s.b=s1.a;

S.push_back(s);

}

elseif(Is_On_Segment(s1.a,s2))

{

s.a=s1.a;

s.b=s1.a;

S.push_back(s);

}

elseif(Is_On_Segment(s2.a,s1))

{

s.a=s2.a;

s.b=s2.a;

S.push_back(s);

}

}

returnS;

}

//////////////////////////////////////////////////////////////////////////////

//圆

//////////////////////////////////////////////////////////////////////////////

structCIRCLE

{

POINTC;

doubleR;

CIRCLE(){}

CIRCLE(POINT_P,double_R)

{

C=_P;

R=_R;

}

booloperator==(constCIRCLE&_C)const

{

returnfabs(R-_C.R)<=EPSILON&&C==_C.C;

}

doubleArea()

{

returnPI*R*R;

}

};

//两个圆的公共面积

doubleTwo_Circle_Common_Area(constCIRCLE&A,constCIRCLE&B)

{

doublearea=0.0;

CIRCLEM=(A.R>B.R)?

A:

B;

CIRCLEN=(A.R>B.R)?

B:

A;

doubleD=Distance(M.C,N.C);

if((DM.R-N.R))

{

doublecosM=(M.R*M.R+D*D-N.R*N.R)/(2.0*M.R*D);

doublecosN=(N.R*N.R+D*D-M.R*M.R)/(2.0*N.R*D);

doublealpha=2.0*ArcCos(cosM);

doublebeta=2.0*ArcCos(cosN);

doubleTM=0.5*M.R*M.R*Sin(alpha);

doubleTN=0.5*N.R*N.R*Sin(beta);

doubleFM=(alpha/360.0)*M.Area();

doubleFN=(beta/360.0)*N.Area();

area=FM+FN-TM-TN;

}

elseif(D<=M.R-N.R)

{

area=N.Ar

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 法律文书 > 调解书

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1