-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathpolyarea.c
More file actions
104 lines (83 loc) · 2.29 KB
/
polyarea.c
File metadata and controls
104 lines (83 loc) · 2.29 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
/*
* A mex function to compute the area of a polygon
*
* [ar] = polyarea(pa);
*
* pa : cell array of polygons (nx2 matrices)
* ar : array of polygon areas with same shape as 'pa'
*
* This software is in the Public Domain
* Ulf Griesmann, NIST, November 2016
*/
#include <math.h>
#include <string.h>
#include <mex.h>
#ifdef __GNUC__
#define RESTRICT __restrict
#define INLINE __inline__
#else
#define RESTRICT
#define INLINE
#endif
/*-- local prototypes -----------------------------------------*/
INLINE double
polygon_area(double * RESTRICT p, int M, int m);
/*-------------------------------------------------------------*/
void
mexFunction(int nlhs, mxArray *plhs[],
int nrhs, const mxArray *prhs[])
{
mxArray *par; /* pointer to array structure */
double *pda; /* polygon data */
double *pout; /* pointer to output data */
int m, M;
int k, Na;
/* check argument pa */
if ( !mxIsCell(prhs[0]) ) {
mexErrMsgTxt("argument must be a cell array.");
}
Na = mxGetNumberOfElements(prhs[0]);
if (!Na) {
mexErrMsgTxt("no input polygons pa.");
}
/* create output array */
plhs[0] = mxCreateDoubleMatrix(mxGetM(prhs[0]), mxGetN(prhs[0]), mxREAL);
pout = (double *)mxGetData(plhs[0]);
/* calculate polygon areas */
for (k=0; k<Na; k++) {
/* get the next polygon from the cell array */
par = mxGetCell(prhs[0], k); /* ptr to mxArray */
pda = mxGetData(par); /* ptr to a data */
M = m = mxGetM(par); /* rows = vertex number */
/* check if last vertex is duplicate of first */
if ( (pda[0] == pda[m-1]) && (pda[m] == pda[2*m-1]) ) {
m--;
}
/* check if enough vertices */
if (m <= 2) {
mexErrMsgTxt("polygons must have at least 3 vertices.");
}
/* calculate area */
pout[k] = polygon_area(pda, M, m);
}
}
/*
* calculate the area of a simple polygon
* Note: polygons are in row-major order
*/
INLINE double
polygon_area(double * RESTRICT p, int M, int m)
{
int k;
double A;
A = 0.0;
for (k=0; k<m-1; k++) {
A += p[k]*p[M+k+1] - p[k+1]*p[M+k];
}
A += p[k]*p[M] - p[0]*p[M+k];
A *= 0.5;
/* make area independent of polygon orientation */
if (A < 0.0)
A = -A;
return A;
}