计算几何常用函数

目录㈠点的基本运算1. 平面上两点之间距离 12. 判断两点是否重合 13. 矢量叉乘 14. 矢量点乘 25. 判断点是否在线段上 26. 求一点饶某点旋转后的坐标 27. 求矢量夹角 2㈡线段及直线的基本运算1. 点与线段的关系 32. 求点到线段所在直线垂线的垂足 43. 点到线段的最近点 44. 点到线段所在直线的距离 45. 点到折线集的最近距离 46. 判断圆是否在多边形内 57. 求矢量夹角余弦 58. 求线段之间的夹角 59. 判断线段是否相交 610.判断线段是否相交但不交在端点处 611.求线段所在直线的方程 612.求直线的斜率 713.求直线的倾斜角 714.求点关于某直线的对称点 715.判断两条直线是否相交及求直线交点 716.判断线段是否相交,如果相交返回交点 7㈢多边形常用算法模块1. 判断多边形是否简单多边形 82. 检查多边形顶点的凸凹性 93. 判断多边形是否凸多边形 94. 求多边形面积 95. 判断多边形顶点的排列方向,方法一 106. 判断多边形顶点的排列方向,方法二 107. 射线法判断点是否在多边形内 108. 判断点是否在凸多边形内 119. 寻找点集的graham算法 1210.寻找点集凸包的卷包裹法 1311.判断线段是否在多边形内 1412.求简单多边形的重心 1513.求凸多边形的重心 1714.求肯定在给定多边形内的一个点 1715.求从多边形外一点出发到该多边形的切线 1816.判断多边形的核是否存在 19㈣圆的基本运算1 .点是否在圆内 202 .求不共线的三点所确定的圆 21㈤矩形的基本运算1.已知矩形三点坐标,求第4点坐标 22㈥常用算法的描述 22㈦补充1.两圆关系: 242.判断圆是否在矩形内: 243.点到平面的距离: 254.点是否在直线同侧: 255.镜面反射线: 256.矩形包含: 267.两圆交点: 278.两圆公共面积: 289. 圆和直线关系: 2910. 内切圆: 3011. 求切点: 3112. 线段的左右旋: 3113.公式: 32代码:/* 需要包含的头文件 */#include <cmath >/* 常用的常量定义 */const double INF = 1E200const double EP = 1E-10const int MAXV = 300const double PI = 3.14159265/* 基本几何结构 */struct POINT{double x;double y; POINT(double a=0, double b=0) { x=a; y=b;} //constructor};struct LINESEG{POINT s;POINT e; LINESEG(POINT a, POINT b) { s=a; e=b;}LINESEG() { }};struct LINE // 直线的解析方程 a*x+b*y+c=0 为统一表示,约定 a >= 0{double a;double b;double c; LINE(double d1=1, double d2=-1, double d3=0) {a=d1; b=d2; c=d3;}};/********************* ** 点的基本运算 ** *********************/double dist(POINT p1,POINT p2) // 返回两点之间欧氏距离{return( sqrt( (p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y) ) ) ;}bool equal_point(POINT p1,POINT p2) // 判断两个点是否重合{return ( (abs(p1.x-p2.x)<EP)&&(abs(p1.y-p2.y)<EP) );}/**************************************************************** **************r=multiply(sp,ep,op),得到(sp-op)*(ep-op)的叉积r>0:ep在矢量opsp的逆时针方向;r=0:opspep三点共线;r<0:ep在矢量opsp的顺时针方向***************************************************************** **************/double multiply(POINT sp,POINT ep,POINT op){return((sp.x-op.x)*(ep.y-op.y)-(ep.x-op.x)*(sp.y-op.y));}/**************************************************************** ***************r=dotmultiply(p1,p2,op),得到矢量(p1-op)和(p2-op)的点积,如果两个矢量都非零矢量r<0:两矢量夹角为锐角;r=0:两矢量夹角为直角;r>0:两矢量夹角为钝角***************************************************************** **************/double dotmultiply(POINT p1,POINT p2,POINT p0){return ((p1.x-p0.x)*(p2.x-p0.x)+(p1.y-p0.y)*(p2.y-p0.y));}/* 判断点p是否在线段l上,条件:(p在线段l所在的直线上)&& (点p在以线段l 为对角线的矩形内) */bool online(LINESEG l,POINT p){return((multiply(l.e,p,l.s)==0)&&( ( (p.x-l.s.x)*(p.x-l.e.x)<=0 )&&( (p.y-l.s.y)*(p.y-l.e.y)<=0 ) ) );}// 返回点p以点o为圆心逆时针旋转alpha(单位:弧度)后所在的位置POINT rotate(POINT o,double alpha,POINT p){POINT tp;p.x-=o.x;p.y-=o.y;tp.x=p.x*cos(alpha)-p.y*sin(alpha)+o.x;tp.y=p.y*cos(alpha)+p.x*sin(alpha)+o.y;return tp;}/* 返回顶角在o点,起始边为os,终止边为oe的夹角(单位:弧度)角度小于pi,返回正值角度大于pi,返回负值可以用于求线段之间的夹角*/double angle(POINT o,POINT s,POINT e){double cosfi,fi,norm;double dsx = s.x - o.x;double dsy = s.y - o.y;double dex = e.x - o.x;double dey = e.y - o.y;cosfi=dsx*dex+dsy*dey;norm=(dsx*dsx+dey*dey)*(dex*dex+dey*dey);cosfi /= sqrt( norm );if (cosfi >= 1.0 ) return 0;if (cosfi <= -1.0 ) return -3.1415926;fi=acos(cosfi);if (dsx*dey-dsy*dex>0) return fi; // 说明矢量os 在矢量 oe的顺时针方向return -fi;}/****************************** ** 线段及直线的基本运算 ** ******************************//* 判断点与线段的关系,用途很广泛本函数是根据下面的公式写的,P是点C到线段AB所在直线的垂足AC dot ABr = ---------||AB||^2(Cx-Ax)(Bx-Ax) + (Cy-Ay)(By-Ay)= -------------------------------L^2r has the following meaning:r=0 P = Ar=1 P = Br<0 P is on the backward extension of ABr>1 P is on the forward extension of AB0<r<1 P is interior to AB*/double relation(POINT p,LINESEG l){LINESEG tl;tl.s=l.s;tl.e=p;return dotmultiply(tl.e,l.e,l.s)/(dist(l.s,l.e)*dist(l.s,l.e)); }// 求点C到线段AB所在直线的垂足 PPOINT perpendicular(POINT p,LINESEG l){double r=relation(p,l);POINT tp;tp.x=l.s.x+r*(l.e.x-l.s.x);tp.y=l.s.y+r*(l.e.y-l.s.y);return tp;}/* 求点p到线段l的最短距离,并返回线段上距该点最近的点np注意:np是线段l上到点p最近的点,不一定是垂足 */double ptolinesegdist(POINT p,LINESEG l,POINT &np){double r=relation(p,l);if(r<0){np=l.s;return dist(p,l.s);}if(r>1){np=l.e;return dist(p,l.e);}np=perpendicular(p,l);return dist(p,np);}// 求点p到线段l所在直线的距离,请注意本函数与上个函数的区别double ptoldist(POINT p,LINESEG l){return abs(multiply(p,l.e,l.s))/dist(l.s,l.e);}/* 计算点到折线集的最近距离,并返回最近点.注意:调用的是ptolineseg()函数 */double ptopointset(int vcount,POINT pointset[],POINT p,POINT &q) {int i;double cd=double(INF),td;LINESEG l;POINT tq,cq;for(i=0;i<vcount-1;i++){l.s=pointset[i];l.e=pointset[i+1];td=ptolinesegdist(p,l,tq);if(td<cd){cd=td;cq=tq;}}q=cq;return cd;}/* 判断圆是否在多边形内.ptolineseg()函数的应用2 */bool CircleInsidePolygon(int vcount,POINT center,double radius,PO INT polygon[]){POINT q;double d;q.x=0;q.y=0;d=ptopointset(vcount,polygon,center,q);if(d<radius||fabs(d-radius)<EP)return true;elsereturn false;}/* 返回两个矢量l1和l2的夹角的余弦(-1 --- 1)注意:如果想从余弦求夹角的话,注意反余弦函数的定义域是从 0到pi */double cosine(LINESEG l1,LINESEG l2){return (((l1.e.x-l1.s.x)*(l2.e.x-l2.s.x) +(l1.e.y-l1.s.y)*(l2.e.y-l2.s.y))/(dist(l1.e,l1.s)*dist(l2.e,l2.s) )) );}// 返回线段l1与l2之间的夹角单位:弧度范围(-pi,pi)double lsangle(LINESEG l1,LINESEG l2){POINT o,s,e;o.x=o.y=0;s.x=l1.e.x-l1.s.x;s.y=l1.e.y-l1.s.y;e.x=l2.e.x-l2.s.x;e.y=l2.e.y-l2.s.y;return angle(o,s,e);}// 如果线段u和v相交(包括相交在端点处)时,返回truebool intersect(LINESEG u,LINESEG v){return( (max(u.s.x,u.e.x)>=min(v.s.x,v.e.x))&& //排斥实验(max(v.s.x,v.e.x)>=min(u.s.x,u.e.x))&&(max(u.s.y,u.e.y)>=min(v.s.y,v.e.y))&&(max(v.s.y,v.e.y)>=min(u.s.y,u.e.y))&&(multiply(v.s,u.e,u.s)*multiply(u.e,v.e,u.s)>=0)&& //跨立实验(multiply(u.s,v.e,v.s)*multiply(v.e,u.e,v.s)>=0));}// (线段u和v相交)&&(交点不是双方的端点) 时返回truebool intersect_A(LINESEG u,LINESEG v){return((intersect(u,v))&&(!online(u,v.s))&&(!online(u,v.e))&&(!online(v,u.e))&&(!online(v,u.s)));}// 线段v所在直线与线段u相交时返回true;方法:判断线段u是否跨立线段v bool intersect_l(LINESEG u,LINESEG v){return multiply(u.s,v.e,v.s)*multiply(v.e,u.e,v.s)>=0;}// 根据已知两点坐标,求过这两点的直线解析方程: a*x+b*y+c = 0 (a >= 0) LINE makeline(POINT p1,POINT p2){LINE tl;int sign = 1;tl.a=p2.y-p1.y;if(tl.a<0){sign = -1;tl.a=sign*tl.a;}tl.b=sign*(p1.x-p2.x);tl.c=sign*(p1.y*p2.x-p1.x*p2.y);return tl;}// 根据直线解析方程返回直线的斜率k,水平线返回 0,竖直线返回 1e200double slope(LINE l){if(abs(l.a) < 1e-20)return 0;if(abs(l.b) < 1e-20)return INF;return -(l.a/l.b);}// 返回直线的倾斜角alpha ( 0 - pi)double alpha(LINE l){if(abs(l.a)< EP)return 0;if(abs(l.b)< EP)return PI/2;double k=slope(l);if(k>0)return atan(k);elsereturn PI+atan(k);}// 求点p关于直线l的对称点POINT symmetry(LINE l,POINT p){POINT tp;tp.x=((l.b*l.b-l.a*l.a)*p.x-2*l.a*l.b*p.y-2*l.a*l.c)/(l.a*l.a+ l.b*l.b);tp.y=((l.a*l.a-l.b*l.b)*p.y-2*l.a*l.b*p.x-2*l.b*l.c)/(l.a*l.a+ l.b*l.b);return tp;}// 如果两条直线 l1(a1*x+b1*y+c1 = 0), l2(a2*x+b2*y+c2 = 0)相交,返回true,且返回交点pbool lineintersect(LINE l1,LINE l2,POINT &p) // 是 L1,L2{double d=l1.a*l2.b-l2.a*l1.b;if(abs(d)<EP) // 不相交return false;p.x = (l2.c*l1.b-l1.c*l2.b)/d;p.y = (l2.a*l1.c-l1.a*l2.c)/d;return true;}// 如果线段l1和l2相交,返回true且交点由(inter)返回,否则返回false bool intersection(LINESEG l1,LINESEG l2,POINT &inter){LINE ll1,ll2;ll1=makeline(l1.s,l1.e);ll2=makeline(l2.s,l2.e);if(lineintersect(ll1,ll2,inter)){return online(l1,inter);}elsereturn false;}/******************************* ** 多边形常用算法模块 ** *******************************/// 如果无特别说明,输入多边形顶点要求按逆时针排列/*返回值:输入的多边形是简单多边形,返回true要求:输入顶点序列按逆时针排序说明:简单多边形定义:1:循环排序中相邻线段对的交是他们之间共有的单个点2:不相邻的线段不相交本程序默认第一个条件已经满足*/bool issimple(int vcount,POINT polygon[]){int i,cn;LINESEG l1,l2;for(i=0;i<vcount;i++){l1.s=polygon[i];l1.e=polygon[(i+1)%vcount];cn=vcount-3;while(cn){l2.s=polygon[(i+2)%vcount];l2.e=polygon[(i+3)%vcount];if(intersect(l1,l2))break;cn--;}if(cn)return false;}return true;}// 返回值:按输入顺序返回多边形顶点的凸凹性判断,bc[i]=1,iff:第i个顶点是凸顶点void checkconvex(int vcount,POINT polygon[],bool bc[]){int i,index=0;POINT tp=polygon[0];for(i=1;i<vcount;i++) // 寻找第一个凸顶点{if(polygon[i].y<tp.y||(polygon[i].y == tp.y&&polygon[i].x<tp.x)) {tp=polygon[i];index=i;}}int count=vcount-1;bc[index]=1;while(count) // 判断凸凹性{if(multiply(polygon[(index+1)%vcount],polygon[(index+2)%vcount],p olygon[index])>=0 )bc[(index+1)%vcount]=1;elsebc[(index+1)%vcount]=0;index++;count--;}}// 返回值:多边形polygon是凸多边形时,返回truebool isconvex(int vcount,POINT polygon[]){bool bc[MAXV];checkconvex(vcount,polygon,bc);for(int i=0;i<vcount;i++) // 逐一检查顶点,是否全部是凸顶点if(!bc[i])return false;return true;}// 返回多边形面积(signed);输入顶点按逆时针排列时,返回正值;否则返回负值double area_of_polygon(int vcount,POINT polygon[]){int i;double s;if (vcount<3) return 0;s=polygon[0].y*(polygon[vcount-1].x-polygon[1].x);for (i=1;i<vcount;i++)s+=polygon[i].y*(polygon[(i-1)].x-polygon[(i+1)%vcount].x); return s/2;}// 如果输入顶点按逆时针排列,返回truebool isconterclock(int vcount,POINT polygon[]){return area_of_polygon(vcount,polygon)>0;}// 另一种判断多边形顶点排列方向的方法bool isccwize(int vcount,POINT polygon[]){int i,index;POINT a,b,v;v=polygon[0];index=0;for(i=1;i<vcount;i++) // 找到最低且最左顶点,肯定是凸顶点{if(polygon[i].y<v.y||polygon[i].y == v.y && polygon[i].x<v.x) {index=i;}}a=polygon[(index-1+vcount)%vcount]; // 顶点v的前一顶点b=polygon[(index+1)%vcount]; // 顶点v的后一顶点return multiply(v,b,a)>0;}/* 射线法判断点q与多边形polygon的位置关系,要求polygon为简单多边形,顶点逆时针排列如果点在多边形内:返回0如果点在多边形边上:返回1如果点在多边形外:返回2*/int insidepolygon(int vcount,POINT Polygon[],POINT q){int c=0,i,n;LINESEG l1,l2;bool bintersect_a,bonline1,bonline2,bonline3;double r1,r2;l1.s=q;l1.e=q;l1.e.x=double(INF);n=vcount;for (i=0;i<vcount;i++){l2.s=Polygon[i];l2.e=Polygon[(i+1)%n];if(online(l2,q))return 1; // 如果点在边上,返回1if ( (bintersect_a=intersect_A(l1,l2))|| // 相交且不在端点((bonline1=online(l1,Polygon[(i+1)%n]))&& // 第二个端点在射线上((!(bonline2=online(l1,Polygon[(i+2)%n])))&& /* 前一个端点和后一个端点在射线两侧 */((r1=multiply(Polygon[i],Polygon[(i+1)%n],l1.s)*multiply(Polygon[ (i+1)%n],Polygon[(i+2)%n],l1.s))>0) ||(bonline3=online(l1,Polygon[(i+2)%n]))&& /* 下一条边是水平线,前一个端点和后一个端点在射线两侧 */((r2=multiply(Polygon[i],Polygon[(i+2)%n],l1.s)*multiply(Po lygon[(i+2)%n],Polygon[(i+3)%n],l1.s))>0)))) c++;}if(c%2 == 1)return 0;elsereturn 2;}// 点q是凸多边形polygon内时,返回true;注意:多边形polygon一定要是凸多边形bool InsideConvexPolygon(int vcount,POINT polygon[],POINT q) // 可用于三角形!{POINT p;LINESEG l;int i;p.x=0;p.y=0;for(i=0;i<vcount;i++) // 寻找一个肯定在多边形polygon内的点p:多边形顶点平均值{p.x+=polygon[i].x;p.y+=polygon[i].y;}p.x /= vcount;p.y /= vcount;for(i=0;i<vcount;i++){l.s=polygon[i];l.e=polygon[(i+1)%vcount];if(multiply(p,l.e,l.s)*multiply(q,l.e,l.s)<0) /* 点p和点q在边l的两侧,说明点q肯定在多边形外 */break;}return (i==vcount);}/**********************************************寻找凸包的graham 扫描法PointSet为输入的点集;ch为输出的凸包上的点集,按照逆时针方向排列;n为PointSet中的点的数目len为输出的凸包上的点的个数**********************************************/void Graham_scan(POINT PointSet[],POINT ch[],int n,int &len){int i,j,k=0,top=2;POINT tmp;// 选取PointSet中y坐标最小的点PointSet[k],如果这样的点有多个,则取最左边的一个for(i=1;i<n;i++)if ( PointSet[i].y<PointSet[k].y ||(PointSet[i].y==PointSet[k].y) && (PointSet[i].x<PointSet[k].x) )k=i;tmp=PointSet[0];PointSet[0]=PointSet[k];PointSet[k]=tmp; // 现在PointSet中y坐标最小的点在PointSet[0]for (i=1;i<n-1;i++) /* 对顶点按照相对PointSet[0]的极角从小到大进行排序,极角相同的按照距离PointSet[0]从近到远进行排序 */{k=i;for (j=i+1;j<n;j++)if ( multiply(PointSet[j],PointSet[k],PointSet[0])>0 || // 极角更小(multiply(PointSet[j],PointSet[k],PointSet[0])==0) && /* 极角相等,距离更短 */ dist(PointSet[0],PointSet[j])<dist(PointSet[0],Poin tSet[k]) )k=j;tmp=PointSet[i];PointSet[i]=PointSet[k];PointSet[k]=tmp;}ch[0]=PointSet[0];ch[1]=PointSet[1];ch[2]=PointSet[2];for (i=3;i<n;i++){while (multiply(PointSet[i],ch[top],ch[top-1])>=0) top--;ch[++top]=PointSet[i];}len=top+1;}// 卷包裹法求点集凸壳,参数说明同graham算法void ConvexClosure(POINT PointSet[],POINT ch[],int n,int &len) {int top=0,i,index,first;double curmax,curcos,curdis;POINT tmp;LINESEG l1,l2;bool use[MAXV];tmp=PointSet[0];index=0;// 选取y最小点,如果多于一个,则选取最左点for(i=1;i<n;i++){if(PointSet[i].y<tmp.y||PointSet[i].y == tmp.y&&PointSet[i].x<tmp .x){index=i;}use[i]=false;}tmp=PointSet[index];first=index;use[index]=true;index=-1;ch[top++]=tmp;tmp.x-=100;l1.s=tmp;l1.e=ch[0];l2.s=ch[0];while(index!=first){curmax=-100;curdis=0;// 选取与最后一条确定边夹角最小的点,即余弦值最大者for(i=0;i<n;i++){if(use[i])continue;l2.e=PointSet[i];curcos=cosine(l1,l2); // 根据cos值求夹角余弦,范围在(-1 -- 1 )if(curcos>curmax || fabs(curcos-curmax)<1e-6 && dist(l2.s,l2.e)>c urdis){curmax=curcos;index=i;curdis=dist(l2.s,l2.e);}}use[first]=false; //清空第first个顶点标志,使最后能形成封闭的hulluse[index]=true;ch[top++]=PointSet[index];l1.s=ch[top-2];l1.e=ch[top-1];l2.s=ch[top-1];}len=top-1;}代码:/* 判断线段是否在简单多边形内(注意:如果多边形是凸多边形,下面的算法可以化简) 原理:必要条件一:线段的两个端点都在多边形内;必要条件二:线段和多边形的所有边都不内交;用途:1. 判断折线是否在简单多边形内2. 判断简单多边形是否在另一个简单多边形内*/bool LinesegInsidePolygon(int vcount,POINT polygon[],LINESEG l) {// 判断线端l的端点是否不都在多边形内if(!insidepolygon(vcount,polygon,l.s)||!insidepolygon(vcount,poly gon,l.e))return false;int top=0,i,j;POINT PointSet[MAXV],tmp;LINESEG s;for(i=0;i<vcount;i++)s.s=polygon[i];s.e=polygon[(i+1)%vcount];if(online(s,l.s)) //线段l的起始端点在线段s上PointSet[top++]=l.s;else if(online(s,l.e)) //线段l的终止端点在线段s上PointSet[top++]=l.e;else{if(online(l,s.s)) //线段s的起始端点在线段l上PointSet[top++]=s.s;else if(online(l,s.e)) // 线段s的终止端点在线段l上PointSet[top++]=s.e;else{if(intersect(l,s)) // 这个时候如果相交,肯定是内交,返回falsereturn false;}}}for(i=0;i<top-1;i++) /* 冒泡排序,x坐标小的排在前面;x坐标相同者,y坐标小的排在前面 */{for(j=i+1;j<top;j++){if( PointSet[i].x>PointSet[j].x || fabs(PointSet[i].x-PointSet[j] .x)<EP && PointSet[i].y>PointSet[j].y ){tmp=PointSet[i];PointSet[i]=PointSet[j];PointSet[j]=tmp;}}}for(i=0;i<top-1;i++){tmp.x=(PointSet[i].x+PointSet[i+1].x)/2; //得到两个相邻交点的中点tmp.y=(PointSet[i].y+PointSet[i+1].y)/2;if(!insidepolygon(vcount,polygon,tmp))return false;}return true;/* 求任意简单多边形polygon的重心需要调用下面几个函数:void AddPosPart(); 增加右边区域的面积void AddNegPart(); 增加左边区域的面积void AddRegion(); 增加区域面积在使用该程序时,如果把xtr,ytr,wtr,xtl,ytl,wtl设成全局变量就可以使这些函数的形式得到化简,但要注意函数的声明和调用要做相应变化*/void AddPosPart(double x, double y, double w, double &xtr, double &ytr, double &wtr){if (abs(wtr + w)<1e-10 ) return; // detect zero regionsxtr = ( wtr*xtr + w*x ) / ( wtr + w );ytr = ( wtr*ytr + w*y ) / ( wtr + w );wtr = w + wtr;return;}void AddNegPart(double x, ouble y, double w, double &xtl, double &ytl, double &wtl){if ( abs(wtl + w)<1e-10 )return; // detect zero regionsxtl = ( wtl*xtl + w*x ) / ( wtl + w );ytl = ( wtl*ytl + w*y ) / ( wtl + w );wtl = w + wtl;return;}void AddRegion ( double x1, double y1, double x2, double y2, doub le &xtr, double &ytr,double &wtr, double &xtl, double &ytl, double &wtl ){if ( abs (x1 - x2)< 1e-10 )return;if ( x2 > x1 ){AddPosPart ((x2+x1)/2, y1/2, (x2-x1) * y1,xtr,ytr,wtr); /* rectan gle 全局变量变化处 */AddPosPart ((x1+x2+x2)/3, (y1+y1+y2)/3, (x2-x1)*(y2-y1)/2,xtr,ytr,wtr);// triangle 全局变量变化处}else{AddNegPart ((x2+x1)/2, y1/2, (x2-x1) * y1,xtl,ytl,wtl);// rectangle 全局变量变化处AddNegPart ((x1+x2+x2)/3, (y1+y1+y2)/3, (x2-x1)*(y2-y1)/2,xtl,ytl ,wtl);// triangle 全局变量变化处}}POINT cg_simple(int vcount,POINT polygon[]){double xtr,ytr,wtr,xtl,ytl,wtl;//注意:如果把xtr,ytr,wtr,xtl,ytl,wtl改成全局变量后这里要删去POINT p1,p2,tp;xtr = ytr = wtr = 0.0;xtl = ytl = wtl = 0.0;for(int i=0;i<vcount;i++){p1=polygon[i];p2=polygon[(i+1)%vcount];AddRegion(p1.x,p1.y,p2.x,p2.y,xtr,ytr,wtr,xtl,ytl,wtl); //全局变量变化处}tp.x = (wtr*xtr + wtl*xtl) / (wtr + wtl);tp.y = (wtr*ytr + wtl*ytl) / (wtr + wtl);return tp;}// 求凸多边形的重心,要求输入多边形按逆时针排序POINT gravitycenter(int vcount,POINT polygon[]){POINT tp;double x,y,s,x0,y0,cs,k;x=0;y=0;s=0;for(int i=1;i<vcount-1;i++){x0=(polygon[0].x+polygon[i].x+polygon[i+1].x)/3;y0=(polygon[0].y+polygon[i].y+polygon[i+1].y)/3; //求当前三角形的重心cs=multiply(polygon[i],polygon[i+1],polygon[0])/2;//三角形面积可以直接利用该公式求解if(abs(s)<1e-20){x=x0;y=y0;s+=cs;continue;}k=cs/s; //求面积比例x=(x+k*x0)/(1+k);y=(y+k*y0)/(1+k);s += cs;}tp.x=x;tp.y=y;return tp;}/* 给定一简单多边形,找出一个肯定在该多边形内的点定理1:每个多边形至少有一个凸顶点定理2:顶点数>=4的简单多边形至少有一条对角线结论: x坐标最大,最小的点肯定是凸顶点y坐标最大,最小的点肯定是凸顶点*/POINT a_point_insidepoly(int vcount,POINT polygon[]){POINT v,a,b,r;int i,index;v=polygon[0];index=0;for(i=1;i<vcount;i++) //寻找一个凸顶点{if(polygon[i].y<v.y){v=polygon[i];index=i;}}a=polygon[(index-1+vcount)%vcount]; //得到v的前一个顶点b=polygon[(index+1)%vcount]; //得到v的后一个顶点POINT tri[3],q;tri[0]=a;tri[1]=v;tri[2]=b;double md=INF;int in1=index;bool bin=false;for(i=0;i<vcount;i++) //寻找在三角形avb内且离顶点v最近的顶点q {if(i == index)continue;if(i == (index-1+vcount)%vcount)continue;if(i == (index+1)%vcount)continue;if(!InsideConvexPolygon(3,tri,polygon[i]))continue;bin=true;if(dist(v,polygon[i])<md){q=polygon[i];md=dist(v,q);}}if(!bin) //没有顶点在三角形avb内,返回线段ab中点{r.x=(a.x+b.x)/2;r.y=(a.y+b.y)/2;return r;}r.x=(v.x+q.x)/2; //返回线段vq的中点r.y=(v.y+q.y)/2;return r;}/* 求从多边形外一点p出发到一个简单多边形的切线,如果存在返回切点,其中rp点是右切点,lp是左切点注意:p点一定要在多边形外输入顶点序列是逆时针排列原理:如果点在多边形内肯定无切线;凸多边形有唯一的两个切点,凹多边形就可能有多于两个的切点;如果polygon是凸多边形,切点只有两个只要找到就可以,可以化简此算法如果是凹多边形还有一种算法可以求解:先求凹多边形的凸包,然后求凸包的切线*/void pointtangentpoly(int vcount,POINT polygon[],POINT p,POINT &r p,POINT &lp){LINESEG ep,en;bool blp,bln;rp=polygon[0];lp=polygon[0];for(int i=1;i<vcount;i++){ep.s=polygon[(i+vcount-1)%vcount];ep.e=polygon[i];en.s=polygon[i];en.e=polygon[(i+1)%vcount];blp=multiply(ep.e,p,ep.s)>=0; // p is to the left of pre edgebln=multiply(en.e,p,en.s)>=0; // p is to the left of next edgeif(!blp&&bln){if(multiply(polygon[i],rp,p)>0) // polygon[i] is above rprp=polygon[i];}if(blp&&!bln){if(multiply(lp,polygon[i],p)>0) // polygon[i] is below lplp=polygon[i];}}return ;}// 如果多边形polygon的核存在,返回true,返回核上的一点p.顶点按逆时针方向输入bool core_exist(int vcount,POINT polygon[],POINT &p){int i,j,k;LINESEG l;LINE lineset[MAXV];for(i=0;i<vcount;i++){lineset[i]=makeline(polygon[i],polygon[(i+1)%vcount]);}for(i=0;i<vcount;i++){for(j=0;j<vcount;j++){if(i == j)continue;if(lineintersect(lineset[i],lineset[j],p)){for(k=0;k<vcount;k++){l.s=polygon[k];l.e=polygon[(k+1)%vcount];if(multiply(p,l.e,l.s)>0)//多边形顶点按逆时针方向排列,核肯定在每条边的左侧或边上break;}if(k == vcount) //找到了一个核上的点break;}}if(j<vcount)break;}if(i<vcount)return true;elsereturn false;}/************************** ** 圆的基本运算 ** **************************//* 返回值:点p在圆内(包括边界)时,返回true用途:因为圆为凸集,所以判断点集,折线,多边形是否在圆内时,只需要逐一判断点是否在圆内即可。

合集下载

常用函数公式运用

常用函数公式运用

常用函数公式运用介绍常用函数公式及其运用是一个很广泛的话题。

由于篇幅有限,我将介绍一些常见的函数公式及其在数学、物理、工程和经济等领域的应用。

1.三角函数公式:- sin²x + cos²x = 1:这个简单的三角恒等式是很多三角函数相关公式的基础。

它在几何学、物理学和工程学中经常被用来证明三角形的恒等关系,以及计算角度间的关系。

- 三角函数的和差化积公式:例如sin(x+x) = sin x cos x +cos x sin x,这个公式在解决角度和方向问题时非常有用。

2.指数函数公式:-指数函数的性质e^(x+x)=e^x*e^x:这个公式在解决复利问题和连续增长模型时非常有用。

它被广泛应用于经济学中的复利计算和人口增长模型中。

- 牛顿冷却定律:温度变化率与温度差成正比,即dT/dt = -k(T-T_a),其中k为比例常数,T为物体温度,T_a为环境温度。

这个公式描述了物体的温度随时间的变化,从而可以用来研究随时间变化的物理系统。

3.对数函数公式:- 对数函数的性质log(x * x) = log x + log x:这个公式在解决乘法问题时非常有用。

它在经济学、物理学和计算机科学中的各种模型中经常被应用。

-高斯分布公式:x=x^−((x−x)^2/2x^2)/(x√(2x)),其中x 为均值,x为标准差。

这个公式描述了一种常见的概率分布模型,广泛应用于统计学、金融学和工程学中。

4.多项式函数公式:-迪利克雷公式:x(x)=∑(x,x)x(x)=x,其中x(x)表示正整数x的因数个数,x(x)表示小于或等于x且与x互质的数的个数。

这个公式在数论中有重要的应用。

-贝塞尔函数公式:贝塞尔函数是一类特殊函数,用来解决边界值问题。

它们在物理学和工程学中广泛应用于波动现象、傅里叶分析和信号处理等领域。

5.微积分公式:-牛顿-莱布尼茨公式:∫(x,x)x'(x)xx=x(x)−x(x),其中x'(x)表示函数x(x)的导数。

九个三角函数值

九个三角函数值

九个三角函数值
1 三角函数基本概念
三角函数是数学中最常见的函数之一,它主要是以正弦、余弦及正切形式表示的。

它常用来计算几何图形特性,也用来解决物理中常见问题。

2 基本三角函数值
正弦函数sin(x):
45°时,sin(45°)=√2/2
90°时,sin(90°)=1
180°时,sin(180°)=0
余弦函数cos(x):
45°时,cos(45°)=√2/2
90°时,cos(90°)=0
180°时,cos(180°)=-1
正切函数tan(x):
45°时,tan(45°)=1
90°时,tan(90°)=无穷
180°时,tan(180°)=0
3 应用
三角函数广泛用于几何和物理中,其中最主要的是几何学研究的线性几何学和曲线几何学。

它可以用来描述形状大小的变化,用来解决界内所有几何计算问题。

此外,三角函数还可以用来计算物理学中各种实际情况下物体运动期间的加速度、力和功等参数,以及描述电磁学和光学运动等电磁学和光学现象。

excel 几何均值 几何标准偏差计算公式

excel 几何均值 几何标准偏差计算公式

excel 几何均值几何标准偏差计算公式
几何均值和几何标准偏差是统计学中常用的两个概念,可以用于测量一组数据的集中趋势和离散程度。

在Excel中,可以使用以下公式计算几何均值和几何标准偏差:
1. 几何均值的计算公式:
几何均值 = (数值1 * 数值2 * ... * 数值n) ^ (1 / n)
其中,数值1、数值2、...、数值n代表要计算几何均值的数据集中的各个数值。

2. 几何标准偏差的计算公式:
几何标准偏差 = ((ln(数值1) - ln(几何均值))^2 + (ln(数值2) - ln(几何均值))^2 + ... + (ln(数值n) - ln(几何均值))^2 / n) ^ 0.5 其中,数值1、数值2、...、数值n代表要计算几何标准偏差的数据集中的各个数值,ln代表自然对数。

需要注意的是,以上公式中的^表示乘方运算,ln表示自然对数运算。

在Excel中,可以使用以下函数来计算几何均值和几何标准偏差:
1. 计算几何均值:
使用GEOMEAN函数,语法为:GEOMEAN(数值1,数值2,...,数值n)
2. 计算几何标准偏差:
使用GEOSTDDEV函数,语法为:GEOSTDDEV(数值1,数值2,...,数值n)
以上就是在Excel中计算几何均值和几何标准偏差的公式和相应的函数。

geometry函数

geometry函数

geometry函数一、介绍geometry函数是一个用于处理几何图形的函数,它可以实现一系列几何图形的计算和操作。

几何图形是指二维或三维空间中的点、线、面等物体,是数学和物理学中重要的研究对象。

geometry函数可以帮助我们在程序中轻松地处理各种几何图形,包括计算它们的面积、周长、体积等。

二、基本概念在使用geometry函数之前,我们需要了解一些基本概念:1. 点:在二维平面上表示为(x,y),在三维空间中表示为(x,y,z)。

2. 直线:由两个点确定,在二维平面上通常用斜率截距式表示为y=kx+b,在三维空间中通常用参数方程表示为x=x0+t*a,y=y0+t*b,z=z0+t*c。

3. 圆:由一个圆心和半径确定,在二维平面上通常用标准式表示为(x-a)^2+(y-b)^2=r^2,在三维空间中通常用参数方程表示为x=a+r*cos(t), y=b+r*sin(t), z=c。

4. 矩形:由四个顶点确定,在二维平面上通常用左下角坐标和右上角坐标表示为(x1,y1,x2,y2),在三维空间中通常用六个面的坐标表示为(x1,y1,z1,x2,y2,z2)。

5. 三角形:由三个点确定,在二维平面上通常用三个顶点坐标表示为(x1,y1,x2,y2,x3,y3),在三维空间中通常用三个顶点坐标表示为(x1,y1,z1,x2,y2,z2,x3,y3,z3)。

6. 多边形:由多个点确定,在二维平面上通常用顶点坐标数组表示,每个顶点的坐标为(x[i],y[i]),在三维空间中通常用顶点坐标数组表示,每个顶点的坐标为(x[i],y[i],z[i])。

7. 立体图形:包括球体、立方体、圆柱、圆锥等,在三维空间中通常用各自的参数方程表示。

三、函数列表geometry函数包含以下几种类型的函数:1. 点相关函数:包括计算两点之间距离、计算两点之间的中点、判断一个点是否在某条直线上等。

2. 直线相关函数:包括计算两条直线之间的夹角、计算两条直线是否相交、计算一条直线与一个矩形是否相交等。

常用函数公式及函数汇总

常用函数公式及函数汇总

常用函数公式及函数汇总在数学和统计学中,常用函数公式是非常重要的工具,可以用来求解各种问题。

下面是一些常见的函数及其公式的汇总。

1.线性函数:线性函数是最简单的函数之一,其函数公式为:y = ax + b,其中a和b是常量。

线性函数的图像是一条直线。

2.幂函数:幂函数是通过变量的幂指数来定义的函数。

常见的幂函数有:y=x^n,其中n是常量。

通过改变幂指数n,可以得到不同的幂函数。

3.指数函数:指数函数是以常量为底数的函数,其函数公式为:y=a^x,其中a是常量。

指数函数的图像是一个逐渐上升或下降的曲线。

4.对数函数:对数函数是指以常量为底数的对数的函数形式,其函数公式为:y = log_a(x),其中a是常量。

对数函数的反函数是指数函数。

5.三角函数:三角函数包括正弦函数、余弦函数和正切函数等。

常见的三角函数公式包括:y = sin(x),y = cos(x),y = tan(x)等。

6.反三角函数:反三角函数是三角函数的反函数。

常见的反三角函数包括:y = arcsin(x),y = arccos(x),y = arctan(x)等。

7.指数对数函数:指数对数函数是指指数函数和对数函数的组合。

常见的指数对数函数包括:y = e^x,y = ln(x)等。

8.双曲函数:双曲函数是指双曲正弦函数、双曲余弦函数和双曲正切函数等。

常见的双曲函数公式包括:y = sinh(x),y = cosh(x),y = tanh(x)等。

9.上下取整函数:上取整函数是指取不小于给定实数的最小整数。

下取整函数是指取不大于给定实数的最大整数。

常见的上下取整函数符号分别为:⌈x⌉和⌊x⌋。

10.组合函数:组合函数是指两个或多个函数的组合。

常见的组合函数公式包括:y=f(g(x)),其中f和g是两个函数。

11.超越函数:超越函数是指不能通过有限次代数运算得到的函数。

常见的超越函数有:指数函数、对数函数、三角函数等。

12.变换函数:变换函数是指通过特定的变换关系得到的新函数。

函数公式大全

函数公式大全

函数公式大全在数学中,函数是描述自变量和因变量之间关系的一种数学工具,它是数学中的一个重要概念,也是解决问题的重要工具。

函数公式则是用来表示函数关系的具体表达式,通过函数公式我们可以更加清晰地了解函数的特性和性质。

下面将介绍一些常见的函数公式,希望能对大家有所帮助。

1. 线性函数公式。

线性函数是一种最简单的函数形式,它的函数公式通常表示为,y = kx + b,其中k和b分别代表斜率和截距。

线性函数的图像是一条直线,斜率决定了直线的倾斜程度,截距则表示了直线与y轴的交点。

2. 二次函数公式。

二次函数的一般形式为,y = ax^2 + bx + c,其中a、b、c为常数且a不为0。

二次函数的图像是一个抛物线,开口的方向由a的正负决定,抛物线的顶点坐标为(-b/2a, -Δ/4a),其中Δ=b^2-4ac称为二次函数的判别式。

3. 指数函数公式。

指数函数的一般形式为,y = a^x,其中a为底数,x为指数。

指数函数的图像是一条逐渐增长或逐渐减小的曲线,底数a大于1时曲线逐渐增长,底数a在0和1之间时曲线逐渐减小。

4. 对数函数公式。

对数函数的一般形式为,y = loga(x),其中a为底数,x为真数。

对数函数的图像是一条渐近于x轴的曲线,底数a大于1时曲线在一、三象限递增,底数a在0和1之间时曲线在一、三象限递减。

5. 三角函数公式。

三角函数包括正弦函数、余弦函数、正切函数等,它们的一般形式分别为,y = sin(x)、y = cos(x)、y = tan(x)。

三角函数的图像是周期性的波动曲线,正弦函数和余弦函数的振幅为1,而正切函数的图像有无数个渐近线。

6. 绝对值函数公式。

绝对值函数的一般形式为,y = |x|,表示x的绝对值。

绝对值函数的图像是一条以原点为对称中心的V形曲线,曲线在原点处转折。

7. 指数增长函数公式。

指数增长函数的一般形式为,y = a^x + b,其中a为底数,b为常数。

指数增长函数的图像是一条逐渐增长的曲线,随着x的增大,y的增长速度越来越快。

十个常用数学函数公式

十个常用数学函数公式数学函数是描述数值之间关系的一种工具,可以帮助我们理解和解决各种数学问题。

在数学中,有许多常用的数学函数公式,下面是十个常见的数学函数公式:1.平方函数公式:f(某)=某^2,其中某是任意实数。

该函数的图像是一个平滑的开口向上的抛物线。

2.立方函数公式:f(某)=某^3,其中某是任意实数。

该函数的图像是一个平滑的开口向上的抛物线。

3.开方函数公式:f(某)=√某,其中某是非负实数。

该函数的图像是一个从原点出发的逐渐上升的曲线。

4. 正弦函数公式:f(某) = sin(某),其中某是弧度。

该函数的图像是一个周期性的波动曲线,取值范围在-1到1之间。

5. 余弦函数公式:f(某) = cos(某),其中某是弧度。

该函数的图像也是一个周期性的波动曲线,取值范围在-1到1之间,但与正弦函数相位差。

6. 正切函数公式:f(某) = tan(某),其中某是弧度。

该函数的图像是一个周期性的波动曲线,取值范围在负无穷到正无穷之间。

7.指数函数公式:f(某)=a^某,其中a是大于0且不等于1的常数,某是任意实数。

该函数的图像是一个逐渐上升或下降的曲线。

8. 对数函数公式:f(某) = log_a(某),其中a是大于0且不等于1的常数,某是大于0的实数。

该函数的图像是一个逐渐上升或下降的曲线,是指数函数的反函数。

9.绝对值函数公式:f(某)=,某,其中某是任意实数。

该函数的图像是以原点为对称轴的V形曲线,取值范围在0到正无穷之间。

10.阶乘函数公式:f(某)=某!,其中某是非负整数。

该函数表示某的阶乘,即从1到某的所有正整数的乘积。

这些常用数学函数公式在各个数学领域中都有广泛的应用,如代数、几何、微积分等。

它们的图像和性质对于建立数学模型、解决实际问题以及深入理解数学概念都起到了重要的作用。

convhull函数

convhull函数Convhull函数是一个十分重要的数学函数,它可以帮助我们在计算机中进行几何图形的计算。

本文将会介绍Convhull函数的基本概念,其作用和主要用途以及在计算机中的应用。

一、什么是Convhull函数Convhull函数是计算机科学中常用的一个函数,它的作用是将给定的点集构成的几何体进行计算,得到其三角剖分,寻找其凸包所构成的多边形的函数。

二、Convhull函数的作用和用途Convhull函数在计算机程序中,主要用于计算几何图形中的边界以及构建三维模型。

在计算机图形学中,Convhull函数可以用来帮助我们构建三维模型,从而实现虚拟现实技术、三维打印等应用。

在机器视觉以及计算机视觉领域中,Convhull函数常常用于对图像进行处理,帮助我们检测物体的轮廓,进行形状匹配等功能。

在海量数据处理中,Convhull函数可以帮助我们有效地减少数据的维度,提高数据处理的效率。

例如在计算机机器学习中,Convhull函数可以帮助我们进行特征提取和降维,帮助我们更加高效地训练我们的机器学习模型。

三、Convhull函数在计算机中的应用Convhull函数在计算机科学中的应用非常广泛。

例如在机器视觉领域中,Convhull函数主要应用于轮廓的检测,形状匹配等方面;在可视化设计中,Convhull函数可以帮助我们构建三维模型;在信号处理中,Convhull函数可以用于信号降噪、信号滤波等方面。

此外,Convhull函数还可以在计算机图形学、计算机辅助设计以及计算机机器学习等领域中起到非常重要的作用。

总之,Convhull函数是计算机科学领域中应用广泛的数学函数之一。

其作用和用途十分广泛,在海量数据处理、计算机图形学、机器学习等领域中发挥着至关重要的作用。

因此,对于Convhull函数的研究和应用,将会给我们带来更多的机会和挑战。

常见的三角函数值表格高中面积

常见的三角函数值表格高中面积三角函数是几何和代数中重要的概念,它们在解决各种数学问题时发挥着重要作用。

在高中数学教学中,学生经常会接触到三角函数,并且涉及到计算三角函数的值以及在几何图形中的应用。

其中,三角函数值表格和三角函数在计算图形面积中的应用是比较常见的内容。

三角函数值表格在学习三角函数时,了解和熟悉常见角的正弦、余弦、正切等函数值是非常重要的。

下面是一些常见角的三角函数值表格:角度正弦值余弦值正切值0°01030°1/2√3/21/√345°√2/2√2/2160°√3/21/2√390°10无穷大通过这个表格,我们可以很方便地查找常见角的三角函数值,这对于解题非常有帮助。

三角函数在高中面积计算中的应用三角函数在计算几何图形的面积时也发挥着关键作用。

例如,当我们计算三角形的面积时,可以利用正弦定理或面积公式来求解。

假设有一个三角形,已知两边长分别为a和b,夹角为θ,那么这个三角形的面积可以通过以下公式来计算:\[ S = \frac{1}{2}ab\sin\theta \]其中,S表示三角形的面积。

这个公式利用了正弦函数,将三角形的面积与三角函数联系起来,帮助我们更加便捷地计算几何图形的面积。

除了三角形,其他多边形以及圆等几何图形的面积计算中也会涉及到三角函数的应用。

因此,熟练掌握三角函数值表格以及在面积计算中的应用是高中数学学习的重要内容之一。

综上所述,三角函数值表格和三角函数在高中面积计算中的应用是高中数学中常见的话题,通过学习和掌握这些知识,有助于我们更好地理解和运用三角函数,提升数学解题能力。

420个函数公式释义以及实例

420个函数公式释义以及实例由于您提到了420个函数公式,这是一个庞大的数量,您可以在不同的学科和领域中找到许多不同类型的函数公式。

在下面,我将提供一些不同类型的函数公式的示例,并解释它们的含义。

由于数量众多,我无法提供所有420个函数公式的具体实例,但是可以给出更多领域和学科上的函数公式例子。

1.三角函数公式:a)正弦函数公式: sin(x) = opposite/hypotenuse示例:在一个直角三角形中,如果一个角的正弦值为0.5,且斜边长度为10,则对边的长度是5。

b)余弦函数公式: cos(x) = adjacent/hypotenuse示例:在一个直角三角形中,如果一个角的余弦值为0.8,且斜边长度为5,则邻边的长度是4。

c)正切函数公式: tan(x) = opposite/adjacent示例:在一个直角三角形中,如果一个角的正切值为2,且对边长度为3,则邻边的长度是1.5。

2.指数函数公式:a)指数函数公式: f(x) = a^x示例:对于指数函数f(x) = 2^x,当x取值为2时,f(x)的结果为4。

b)对数函数公式: log_a(x) = b示例:对于对数函数log_2(x) = 3,当x取值为8时,log_2(x)的结果为3。

3.代数函数公式:a)一次函数公式: f(x) = mx + b示例:对于一次函数f(x) = 2x + 1,当x取值为3时,f(x)的结果为7。

b)二次函数公式: f(x) = ax^2 + bx + c示例:对于二次函数f(x) = x^2 - 4x + 4,当x取值为2时,f(x)的结果为0。

4.概率函数公式:a)正态分布函数公式: f(x) = (1/σ√(2π)) * e^(-(x-μ)^2 / (2σ^2))示例:对于正态分布函数f(x) = (1/2π) * e^(-x^2/2),当x取值为0时,f(x)的结果为0.399。

以上只是少数几个函数公式的示例,并且没有涉及到所有学科和领域。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
相关文档
最新文档