常见的计算
1、点在多边形内
1 bool PointInPolygon(List poly, Point p) 2 { 3 int polySides = poly.Count; 4 int i, j = polySides - 1; 5 bool oddNodes = false; 6 for (i = 0; i < polySides; i++) 7 { 8 if ((poly[i].Y < p.Y && poly[j].Y >= p.Y || poly[j].Y < p.Y && poly[i].Y >= p.Y) && (poly[i].X <= p.X || poly[j].X <= p.X)) 9 { 10 if (poly[i].X + (p.Y - poly[i].Y) / (poly[j].Y - poly[i].Y) * (poly[j].X - poly[i].X) < p.X) 11 { 12 oddNodes = !oddNodes; 13 } 14 } 15 j = i; 16 } 17 return oddNodes; 18 }
-----------------------------------------------------------------------------------------------------------------------
2、任意多边形的面积
public float CalculateArea(List poly) { int iCycle, iCount; iCycle = 0; float iArea = 0; iCount = poly.Count; for (iCycle = 0; iCycle < iCount; iCycle++) { iArea = iArea + (poly[iCycle].X * poly[(iCycle + 1) % iCount].Y - poly[(iCycle + 1) % iCount].X * poly[iCycle].Y); } return (float)Math.Abs(0.5 * iArea); }
-----------------------------------------------------------------------------------------------------------------------
3、不规则六面体体积
1 private JPoint3D CenterPoint() 2 { 3 //计算中心点 4 float topX = (LeftBackTop.X + LeftFrontTop.X + RightBackTop.X + RightFrontTop.X) / 4; 5 float topY = (LeftBackTop.Y + LeftFrontTop.Y + RightBackTop.Y + RightFrontTop.Y) / 4; 6 float topZ = (LeftBackTop.Z + LeftFrontTop.Z + RightBackTop.Z + RightFrontTop.Z) / 4; 7 8 float bottomX = (LeftBackBottom.X + LeftFrontBottom.X + RightBackBottom.X + RightFrontBottom.X) / 4; 9 float bottomY = (LeftBackBottom.Y + LeftFrontBottom.Y + RightBackBottom.Y + RightFrontBottom.Y) / 4; 10 float bottomZ = (LeftBackBottom.Z + LeftFrontBottom.Z + RightBackBottom.Z + RightFrontBottom.Z) / 4; 11 12 float x = (topX + bottomX) / 2; 13 float y = (topY + bottomY) / 2; 14 float z = (topZ + bottomZ) / 2; 15 16 JPoint3D pCenter = new JPoint3D(x, y, z); 17 return pCenter; 18 } 19 20 public float Volume() 21 { 22 float fVolume = 0.0f; 23 //劈分成12个不规则四面体; 24 JPoint3D pCenter = CenterPoint(); 25 //上 26 float pPA = Distance(LeftBackTop, pCenter); 27 float pPB = Distance(LeftFrontTop, pCenter); 28 float pPC = Distance(RightBackTop, pCenter); 29 float pAB = Distance(LeftBackTop, LeftFrontTop); 30 float pAC = Distance(LeftBackTop, RightBackTop); 31 float pBC = Distance(LeftFrontTop, RightBackTop); 32 float x = Cos(pPA, pPB, pAB); 33 float y = Cos(pPB, pPC, pBC); 34 float z = Cos(pPA, pPC, pAC); 35 fVolume += (float)(pPA * pPB * pPC * Math.Sqrt(1 + 2 * x * y * z - x * x - y * y - z * z))/6; 36 37 pPA = Distance(LeftFrontTop, pCenter); 38 pPB = Distance(RightFrontTop, pCenter); 39 pPC = Distance(RightBackTop, pCenter); 40 pAB = Distance(RightFrontTop, LeftFrontTop); 41 pAC = Distance(LeftFrontTop, RightBackTop); 42 pBC = Distance(RightFrontTop, RightBackTop); 43 x = Cos(pPA, pPB, pAB); 44 y = Cos(pPB, pPC, pBC); 45 z = Cos(pPA, pPC, pAC); 46 fVolume += (float)(pPA * pPB * pPC * Math.Sqrt(1 + 2 * x * y * z - x * x - y * y - z * z)) / 6; 47 48 //下 49 pPA = Distance(LeftFrontBottom, pCenter); 50 pPB = Distance(RightFrontBottom, pCenter); 51 pPC = Distance(RightBackBottom, pCenter); 52 pAB = Distance(RightFrontBottom, LeftFrontBottom); 53 pAC = Distance(LeftFrontBottom, RightBackBottom); 54 pBC = Distance(RightFrontBottom, RightBackBottom); 55 x = Cos(pPA, pPB, pAB); 56 y = Cos(pPB, pPC, pBC); 57 z = Cos(pPA, pPC, pAC); 58 fVolume += (float)(pPA * pPB * pPC * Math.Sqrt(1 + 2 * x * y * z - x * x - y * y - z * z)) / 6; 59 60 pPA = Distance(LeftFrontBottom, pCenter); 61 pPB = Distance(RightFrontBottom, pCenter); 62 pPC = Distance(RightBackBottom, pCenter); 63 pAB = Distance(RightFrontBottom, LeftFrontBottom); 64 pAC = Distance(LeftFrontBottom, RightBackBottom); 65 pBC = Distance(RightFrontBottom, RightBackBottom); 66 x = Cos(pPA, pPB, pAB); 67 y = Cos(pPB, pPC, pBC); 68 z = Cos(pPA, pPC, pAC); 69 fVolume += (float)(pPA * pPB * pPC * Math.Sqrt(1 + 2 * x * y * z - x * x - y * y - z * z)) / 6; 70 //左 71 pPA = Distance(LeftFrontTop, pCenter); 72 pPB = Distance(LeftBackTop, pCenter); 73 pPC = Distance(LeftBackBottom, pCenter); 74 pAB = Distance(LeftFrontTop, LeftBackTop); 75 pAC = Distance(LeftFrontTop, LeftBackBottom); 76 pBC = Distance(LeftBackTop, LeftBackBottom); 77 x = Cos(pPA, pPB, pAB); 78 y = Cos(pPB, pPC, pBC); 79 z = Cos(pPA, pPC, pAC); 80 fVolume += (float)(pPA * pPB * pPC * Math.Sqrt(1 + 2 * x * y * z - x * x - y * y - z * z)) / 6; 81 82 pPA = Distance(LeftFrontBottom, pCenter); 83 pPB = Distance(LeftBackBottom, pCenter); 84 pPC = Distance(LeftFrontTop, pCenter); 85 pAB = Distance(LeftFrontBottom, LeftBackBottom); 86 pAC = Distance(LeftFrontBottom, LeftFrontTop); 87 pBC = Distance(LeftBackBottom, LeftFrontTop); 88 x = Cos(pPA, pPB, pAB); 89 y = Cos(pPB, pPC, pBC); 90 z = Cos(pPA, pPC, pAC); 91 fVolume += (float)(pPA * pPB * pPC * Math.Sqrt(1 + 2 * x * y * z - x * x - y * y - z * z)) / 6; 92 //右 93 pPA = Distance(RightFrontTop, pCenter); 94 pPB = Distance(RightBackTop, pCenter); 95 pPC = Distance(RightBackBottom, pCenter); 96 pAB = Distance(RightFrontTop, RightBackTop); 97 pAC = Distance(RightFrontTop, RightBackBottom); 98 pBC = Distance(RightBackTop, RightBackBottom); 99 x = Cos(pPA, pPB, pAB); 100 y = Cos(pPB, pPC, pBC); 101 z = Cos(pPA, pPC, pAC); 102 fVolume += (float)(pPA * pPB * pPC * Math.Sqrt(1 + 2 * x * y * z - x * x - y * y - z * z)) / 6; 103 104 pPA = Distance(RightFrontBottom, pCenter); 105 pPB = Distance(RightBackBottom, pCenter); 106 pPC = Distance(RightFrontTop, pCenter); 107 pAB = Distance(RightFrontBottom, RightBackBottom); 108 pAC = Distance(RightFrontBottom, RightFrontTop); 109 pBC = Distance(RightBackBottom, RightFrontTop); 110 x = Cos(pPA, pPB, pAB); 111 y = Cos(pPB, pPC, pBC); 112 z = Cos(pPA, pPC, pAC); 113 fVolume += (float)(pPA * pPB * pPC * Math.Sqrt(1 + 2 * x * y * z - x * x - y * y - z * z)) / 6; 114 //前 115 pPA = Distance(RightFrontTop, pCenter); 116 pPB = Distance(RightFrontBottom, pCenter); 117 pPC = Distance(LeftFrontTop, pCenter); 118 pAB = Distance(RightFrontBottom, RightFrontTop); 119 pAC = Distance(RightFrontTop, LeftFrontTop); 120 pBC = Distance(RightFrontBottom, LeftFrontTop); 121 x = Cos(pPA, pPB, pAB); 122 y = Cos(pPB, pPC, pBC); 123 z = Cos(pPA, pPC, pAC); 124 fVolume += (float)(pPA * pPB * pPC * Math.Sqrt(1 + 2 * x * y * z - x * x - y * y - z * z)) / 6; 125 126 pPA = Distance(LeftFrontBottom, pCenter); 127 pPB = Distance(RightFrontBottom, pCenter); 128 pPC = Distance(LeftFrontTop, pCenter); 129 pAB = Distance(RightFrontBottom, LeftFrontBottom); 130 pAC = Distance(LeftFrontBottom, LeftFrontTop); 131 pBC = Distance(RightFrontBottom, LeftFrontTop); 132 x = Cos(pPA, pPB, pAB); 133 y = Cos(pPB, pPC, pBC); 134 z = Cos(pPA, pPC, pAC); 135 fVolume += (float)(pPA * pPB * pPC * Math.Sqrt(1 + 2 * x * y * z - x * x - y * y - z * z)) / 6; 136 //后 137 pPA = Distance(RightBackTop, pCenter); 138 pPB = Distance(RightBackBottom, pCenter); 139 pPC = Distance(LeftBackTop, pCenter); 140 pAB = Distance(RightBackBottom, RightBackTop); 141 pAC = Distance(RightBackTop, LeftBackTop); 142 pBC = Distance(RightBackBottom, LeftBackTop); 143 x = Cos(pPA, pPB, pAB); 144 y = Cos(pPB, pPC, pBC); 145 z = Cos(pPA, pPC, pAC); 146 fVolume += (float)(pPA * pPB * pPC * Math.Sqrt(1 + 2 * x * y * z - x * x - y * y - z * z)) / 6; 147 148 pPA = Distance(LeftBackBottom, pCenter); 149 pPB = Distance(RightBackBottom, pCenter); 150 pPC = Distance(LeftBackTop, pCenter); 151 pAB = Distance(RightBackBottom, LeftBackBottom); 152 pAC = Distance(LeftBackBottom, LeftBackTop); 153 pBC = Distance(RightBackBottom, LeftBackTop); 154 x = Cos(pPA, pPB, pAB); 155 y = Cos(pPB, pPC, pBC); 156 z = Cos(pPA, pPC, pAC); 157 fVolume += (float)(pPA * pPB * pPC * Math.Sqrt(1 + 2 * x * y * z - x * x - y * y - z * z)) / 6; 158 159 160 return fVolume; 161 } 162 163 public float Distance(JPoint3D p1,JPoint3D p2) 164 { 165 return (float)Math.Sqrt(Math.Pow(p1.X - p2.X, 2) + Math.Pow(p1.Y - p2.Y, 2) + Math.Pow(p1.Z - p2.Z, 2)); 166 } 167 168 public float Cos(float a,float b,float c) 169 { 170 return (float)(a * a + b * b - c * c) / (2 * a * b); 171 }
-----------------------------------------------------------------------------------------------------------------------
4、非零向量夹角
bool AngleLargeThanPi(PointF point1, Point point2) { float temp=point1.X* point2.Y - point2.X* point1.Y(); return ( temp < 0); } double AngleBetweenVectors(MyVertex pIntersectiongPoint,MyVertex pStartPoint,MyVertex pEndPoint) { double ax,ay,az,bx,by,bz,dCosValue,dResuly; ax=pIntersectionPoint.x-pStartPoint.x; ay=pIntersectionPoint.y-pStartPoint.y; az=pIntersectionPoint.z-pStartPoint.z; bx=pIntersectionPoint.x-pEndPoint.x; by=pIntersectionPoint.y-pEndPoint.y; bz=pIntersectionPoint.z-pEndPoint.z; double pisDis,pieDis; pisDis=PointToPointDistance(pIntersectionPoint,pStartPoint); pieDis=PointToPointDistance(pIntersectionPoint,pEndPoint); if(pisDis==0||pieDis==0) { dResult=0; } else { dCosValue=ax*bx+ay*by+az*bz; dCosValue=dCosValue/(pieDis*pisDis); if(AngleLargeThanPi(PointF(ax,ay),PointF(bx,by))) { dResult=acos(dCosValue)*180/Pi; } else { dResult=360-acos(dCosValue)*180/Pi; } } return dResult; }
-----------------------------------------------------------------------------------------------------------------------
5、点在线的左边还是右边?三种方法
1、
1 bool LeftOfLine(const ZCoord2D& p, const ZCoord2& p1, const ZCoord2D& p2) 2 { 3 double tmpx = (p1.x - p2.x) / (p1.y - p2.y) * (p.y - p2.y) + p2.x; 4 if (tmpx > p.x)//当tmpx>p.x的时候,说明点在线的左边,小于在右边,等于则在线上。 5 return true; 6 7 return false; 8 }
2. 另外一种方法:设直线是由其上两点(x1,y1)(x2,y2)确定的,直线方向是由(x1,y1)到(x2,y2)的方向。这时若直线方程记为Ax+By+C=0则有:A=y1-y2; B=x2-x1; C=x1*y2-x2*y1;这时可以计算D:D=A*xp+B*yp+C
若D>0,则点(xp,yp)在直线的左侧;若D<0,则点在直线的右侧;D=0点在直线上
Tmp = (y1 – y2) * x + (x2 – x1) * y + x1 * y2 – x2 * y1
Tmp > 0 在左侧
Tmp = 0 在线上
Tmp < 0 在右侧
3. 设线段端点为从 A(x1, y1)到 B(x2, y2), 线外一点 P(x0,y0),判断该点位于有向线A→B 的那一侧。
a = ( x2-x1, y2-y1)
b = (x0-x1, y0-y1)
a x b = | a | | b | sinφ (φ为两向量的夹角)
| a | | b | ≠ 0 时, a x b 决定点 P的位置
所以 a x b 的 z 方向大小决定 P位置
(x2-x1)(y0-y1) – (y2-y1)(x0-x1) > 0 左侧
(x2-x1)(y0-y1) – (y2-y1)(x0-x1) < 0 右侧
(x2-x1)(y0-y1) – (y2-y1)(x0-x1) = 0 线段上
-----------------------------------------------------------------------------------------------------------------------
6、三角形五星定理
三角形五心定理 三角形的重心,外心,垂心,内心和旁心称之为三角形的五心。
三角形五心定理是指三角形重心定理,外心定理,垂心定理,内心定理,旁心定理的总称。
一、三角形重心定理 三角形的三条边的中线交于一点。该点叫做三角形的重心。三中线交于一点可用燕尾定理证明,十分简单。(重心原是一个物理概念,对于等厚度的质量均匀的三角形薄片,其重心恰为此三角形三条中线的交点,重心因而得名)
重心的性质:
1、重心到顶点的距离与重心到对边中点的距离之比为2∶1。
2、重心和三角形3个顶点组成的3个三角形面积相等。即重心到三条边的距离与三条边的长成反比。
3、重心到三角形3个顶点距离的平方和最小。
4、在平面直角坐标系中,重心的坐标是顶点坐标的算术平均,即其重心坐标为((X1+X2+X3)/3,(Y1+Y2+Y3)/3。
二、三角形外心定理 三角形外接圆的圆心,叫做三角形的外心。
外心的性质:
1、三角形的三条边的垂直平分线交于一点,该点即为该三角形外心。
2、若O是△ABC的外心,则∠BOC=2∠A(∠A为锐角或直角)或∠BOC=360°-2∠A(∠A为钝角)。
3、当三角形为锐角三角形时,外心在三角形内部;当三角形为钝角三角形时,外心在三角形外部;当三角形为直角三角形时,外心在斜边上,与斜边的中点重合。
4、计算外心的坐标应先计算下列临时变量:d1,d2,d3分别是三角形三个顶点连向另外两个顶点向量的点乘。c1=d2d3,c2=d1d3,c3=d1d2;c=c1+c2+c3。重心坐标:( (c2+c3)/2c,(c1+c3)/2c,(c1+c2)/2c )。
5、外心到三顶点的距离相等
三、三角形垂心定理 三角形的三条高(所在直线)交于一点,该点叫做三角形的垂心。
垂心的性质:
1、三角形三个顶点,三个垂足,垂心这7个点可以得到6个四点圆。
2、三角形外心O、重心G和垂心H三点共线,且OG∶GH=1∶2。(此直线称为三角形的欧拉线(Euler line))
3、垂心到三角形一顶点距离为此三角形外心到此顶点对边距离的2倍。
4、垂心分每条高线的两部分乘积相等。
定理证明
已知:ΔABC中,AD、BE是两条高,AD、BE交于点O,连接CO并延长交AB于点F ,求证:CF⊥AB
证明:
连接DE ∵∠ADB=∠AEB=90度 ∴A、B、D、E四点共圆 ∴∠ADE=∠ABE
∵∠EAO=∠DAC ∠AEO=∠ADC ∴ΔAEO∽ΔADC
∴AE/AO=AD/AC ∴ΔEAD∽ΔOAC ∴∠ACF=∠ADE=∠ABE
又∵∠ABE+∠BAC=90度 ∴∠ACF+∠BAC=90度 ∴CF⊥AB
因此,垂心定理成立!
四、三角形内心定理 三角形内切圆的圆心,叫做三角形的内心。
内心的性质:
1、三角形的三条内角平分线交于一点。该点即为三角形的内心。
2、直角三角形的内心到边的距离等于两直角边的和减去斜边的差的二分之一。
3、P为ΔABC所在平面上任意一点,点I是ΔABC内心的充要条件是:向量PI=(a×向量PA+b×向量PB+c×向量PC)/(a+b+c).
4、O为三角形的内心,A、B、C分别为三角形的三个顶点,延长AO交BC边于N,则有AO:ON=AB:BN=AC:CN=(AB+AC):BC
五、三角形旁心定理 三角形的旁切圆(与三角形的一边和其他两边的延长线相切的圆)的圆心,叫做三角形的旁心。
旁心的性质:
1、三角形一内角平分线和另外两顶点处的外角平分线交于一点,该点即为三角形的旁心。
2、每个三角形都有三个旁心。
3、旁心到三边的距离相等。
如图,点M就是△ABC的一个旁心。三角形任意两角的外角平分线和第三个角的内角平分线的交点。一个三角形有三个旁心,而且一定在三角形外。
附:三角形的中心:只有正三角形才有中心,这时重心,内心,外心,垂心,四心合一。
有关三角形五心的诗歌
三角形五心歌(重外垂内旁)
三角形有五颗心,重外垂内和旁心, 五心性质很重要,认真掌握莫记混.
重 心
三条中线定相交,交点位置真奇巧, 交点命名为“重心”,重心性质要明了,
重心分割中线段,数段之比听分晓; 长短之比二比一,灵活运用掌握好.
外 心
三角形有六元素,三个内角有三边. 作三边的中垂线,三线相交共一点.
此点定义为外心,用它可作外接圆. 内心外心莫记混,内切外接是关键.
垂 心
三角形上作三高,三高必于垂心交. 高线分割三角形,出现直角三对整,
直角三角形有十二,构成六对相似形, 四点共圆图中有,细心分析可找清.
内 心
三角对应三顶点,角角都有平分线, 三线相交定共点,叫做“内心”有根源;
点至三边均等距,可作三角形内切圆, 此圆圆心称“内心”,如此定义理当然.
-----------------------------------------------------------------------------------------------------------------------
7、判断点在园内(四点共圆)
Algorithm InCircle(va, vb, vd, vc)
if |a^b^,c^b^,d^b^| > 0,
vd is NOT in the circumcircle of abc
//a^坐标为(ax,ay,ax*ax+ay*ay),a^b^为向量
if |a^b^,c^b^,d^b^| == 0,
vd is on the circumcircle of abc
if |a^b^,c^b^,d^b^| < 0,
vd is in the circumcircle of abc
Note: Details of InCircle():
如下图:
抛物线P (z = x*x + y*y), 现有x-y平面上a,b,c三点,现在要测试点d是否在a,b,c的外接圆内,将a,b,c,d四点lift up,与P相交于a^,b^,c^,d^,则有:
case 1:如果d正好位于外接圆上,则d^必在由a^,b^,c^三点构成的平面H上。
此刻向量a^b^,c^b^,d^b^构成的矩阵的行列式det==0;
case 2:如果d位于外接圆内,即d',则d'^必在由a^,b^,c^三点构成的平面H下面。即向量a^b^,c^b^,d^b^构成的矩阵的行列式det<0;
case 3:如果d位于外接圆外,即d'',则d''^必在由a^,b^,c^三点构成的平面H上面。即向量a^b^,c^b^,d^b^构成的矩阵的行列式det>0;
int PointInCircle(MyPoint pa,MyPoint pb,MyPoint pc,MyPoint vp) { double avx,avy,bvx,bvy,cvx,cvy; double bvxcvy,cvxbvy,cvxavy,avxcvy,avxbvy,bvxavy; double alift,blift,clift; double det; //AV向量 avx=pa.x-vp.x; avy=pa.y-vp.y; //BV向量 bvx=pb.x-vp.x; bvy=pb.y-vp.y; //CV向量 cvx=pc.x-vp.x; cvy=pc.y-vp.y; bvxcvy=bvx*cvy; cvxbvy=cvx*bvy;
... ...
... ... }
-----------------------------------------------------------------------------------------------------------------------
8、由不共线的三点确定其平面法向量
已知平面上不重合的三点o(0,0,0)a(a1,a2,a3),b(b1,b2,b3),那么此三点所确定平面的法向量n(x,y,z)中的x,y,z值分别是多少;
用定义做任取其中两点成为一条直线oa向量(a1,a2,a3) ob向量(b1,b2,b3)
(x,y,z)*(a1,a2,a3)=0
(x,y,z)*(b1,b2,b3)=0
解得:((a2b3-a3b2)/(a3b1-a1b3)y,y,(a2b1-a1b2)/(a1b3-b1a3)y)
把y消掉通分得(a2b3-a3b2,a3b1-a1b3,a1b2-a2b1)
x=a2b3-a3b2,y=a3b1-a1b3,z=a1b2-a2b1
1 GetVector(float * v1,float * v2,float * v3)//v1[0]=x,v1[1]=y.v1[2]=z 2 { 3 VECTOR vec1; 4 vec1.x = v2[0] - v1[0]; 5 vec1.y = v2[1] - v1[1]; 6 vec1.z = v2[2] - v1[2]; 7 8 VECTOR vec2; 9 vec2.x = v3[0]- v1[0]; 10 vec2.y = v3[1] - v1[1]; 11 vec2.z = v3[2] - v1[2]; 12 13 VECTOR vec; 14 vec.x = vec1.y * vec2.z - vec1.z * vec2.y; 15 vec.y = vec1.z * vec2.x - vec1.x * vec2.z; 16 vec.z = vec1.x * vec2.y - vec1.y * vec2.x; 17 18 double d = sqrt (vec.x * vec.x + vec.y * vec.y + vec.z * vec.z); 19 vec.x = vec.x/d;vec.y = vec.y/d;vec.z = vec.z/d; 20 return vec; 21 }
-----------------------------------------------------------------------------------------------------------------------

浙公网安备 33010602011771号