/* Create by zyzx
* Created 2008-11-4
* Modified 2008-11-4
*/
在网上查了下,计算多边形面积主要有2种方法:1、在多边形内部取一点,构成三角形,再求三角形面积,此方法缺陷很多。2、矢量运算法,这里主要介绍矢量运算法。
我们都知道已知A(x1,y1)B(x2,y2)C(x3,y3)三点的面积公式为
|x1 x2 x3|
S(A,B,C) = |y1 y2 y3| * 0.5 (当三点为逆时针时为正,顺时针则为负的)
|1 1 1 |
对多边形A1A2A3、、、An(顺或逆时针都可以),设平面上有任意的一点P,则有:
S(A1,A2,A3,、、、,An)
= abs(S(P,A1,A2)+ S(P,A2,A3)+、、、+S(P,An,A1))
P是可以取任意的一点,用(0,0)就可以了。
代码实现如下:
1 double PolygonArea(const Point_F* p, int n);
2 double Matrix3Pt( Point_F pt1, Point_F pt2, Point_F pt3 );
3
4 struct Point_F
5 {
6 Point_F() {}
7 Point_F(double x, double y) : x(x), y(y) {}
8
9 double x;
10 double y;
11 };
12
13
14 /* 功能:计算多边形面积
15 * 条件:非歧义多边形
16 * 参数:
17 * Point_F* p 多边形顶点序列:顺时针,逆时针
18 * int n 多边形顶点个数
19 * 返回:面积
20 */
21 double PolygonArea( const Point_F* p, int n )
22 {
23 /*
24 多边形面积
25 S( A1, A2, A3, , An )
26 = abs( S(P, A1, A2) + S(P, A2, A3) + S(P, A3, A4) + + S(P, An, A1) )
27 P 为任意点 ( 默认 P = (0, 0) )
28 */
29
30 double area = 0;
31 int iP = 0;
32 Point_F* pPt = (Point_F*)p;
33
34 assert( pPt );
35 if( n <= 2 ) return 0.0;
36
37 do
38 {
39 iP += 1;
40 if( n > iP )
41 {
42 area = area + Matrix3Pt( Point_F(0,0), *pPt, *(pPt + 1) );
43 }else if( n == iP ){
44 area = area + Matrix3Pt( Point_F(0,0), *pPt, *p );
45 }else{
46 break;
47 }
48 pPt += 1;
49 } while ( n >= iP );
50
51 area = fabs( area );
52
53 return area;
54 }
55
56 /*
57 * 功能:3点矢量行列式,算子->求面积
58 */
59 double Matrix3Pt( Point_F pt1, Point_F pt2, Point_F pt3 )
60 {
61 /*
62 3点 行列式展开
63 | x1, x2, x3 |
64 S(A,B,C) = | y1, y2, y3 | * 0.5
65 | 1, 1, 1 |
66 = ( x1*y2 - x1*y3 - x2*y1 + x2*y3 + x3*y1 - x3*y2 ) * 0.5
67 */
68 return ( pt1.x * pt2.y -
69 pt1.x * pt3.y -
70 pt2.x * pt1.y +
71 pt2.x * pt3.y +
72 pt3.x * pt1.y -
73 pt3.x * pt2.y
74 ) * 0.5 ;
75 }
测试效果:
1 // * 测试例子
2
3 void main()
4 {
5 Point_F pt[ 4] = {
6 Point_F( 0, 0 ),
7 Point_F( 100, 0 ),
8 Point_F( 100, 100 ),
9 Point_F( 0, 100 )
10 };
11
12 double area = PolygonArea( pt, 4 );
13
14
15 }