📄 geompack_ptpolg.cxx
字号:
/* ptpolg.f -- translated by f2c (version 19990311).
*/
#include <ivp_physics.hxx>
#include <geompack.hxx>
void IVP_Geompack::ptpolg_(
int dim,
int ldv,
int *nv,
int inc,
int *pgind,
double *vcl,
double *pt,
double *nrml,
double *dtol,
int *inout
) {
/* System generated locals */
int vcl_dim1, vcl_offset, i__1, i__2;
double d__1, d__2, d__3;
/* Local variables */
double area, dist;
int h__, i__, j, k, l, m, s;
double t, armax, da[3], db[3];
int la, lb;
double cp[3];
int sa;
double ta;
int sb;
double nr[4], dir[3], rhs[3];
/* Written and copyright by: */
/* Barry Joe, Dept. of Computing Science, Univ. of Alberta */
/* Edmonton, Alberta, Canada T6G 2H1 */
/* Phone: (403) 492-5757 Email: barry@cs.ualberta.ca */
/* Purpose: Determine whether a point lies inside, outside, or on */
/* boundary of a planar polygon in 2 or 3 dimensional space. */
/* It is assumed that point lies in plane of polygon. */
/* Input parameters: */
/* DIM - dimension of polygon (2 or 3) */
/* LDV - leading dimension of VCL array in calling routine */
/* NV - number of vertices in polygon */
/* INC - increment for PGIND indicating indices of polygon */
/* PGIND(0:NV*INC) - indices in VCL of polygon vertices are in */
/* PGIND(0), PGIND(INC), ..., PGIND(NV*INC) with first and */
/* last vertices identical */
/* VCL(1:DIM,1:*) - vertex coordinate list */
/* PT(1:DIM) - point for which in/out test is applied */
/* NRML(1:3) - unit normal vector of plane containing polygon, */
/* with vertices oriented CCW wrt normal (used iff DIM = 3); */
/* normal is assumed to be (0,0,1) if DIM = 2 */
/* DTOL - absolute tolerance to determine whether a point is on */
/* a line or plane */
/* Output parameters: */
/* INOUT - +1, 0, or -1 depending on whether point PT is inside */
/* polygon, on boundary of polygon, or outside polygon; */
/* or -2 if error in input parameters */
/* Parameter adjustments */
--pt;
vcl_dim1 = ldv;
vcl_offset = 1 + vcl_dim1 * 1;
vcl -= vcl_offset;
--nrml;
/* Function Body */
*inout = -2;
if (dim < 2 || dim > 3) {
return;
}
/* Find edge subtending max area with PT as third triangle vertex. */
armax = 0.;
h__ = 0;
lb = pgind[0];
i__1 = dim;
for (j = 1; j <= i__1; ++j) {
db[j - 1] = vcl[j + lb * vcl_dim1] - pt[j];
/* L10: */
}
i__1 = *nv;
for (i__ = 1; i__ <= i__1; ++i__) {
la = lb;
lb = pgind[i__ * inc];
i__2 = dim;
for (j = 1; j <= i__2; ++j) {
da[j - 1] = db[j - 1];
db[j - 1] = vcl[j + lb * vcl_dim1] - pt[j];
dir[j - 1] = vcl[j + lb * vcl_dim1] - vcl[j + la * vcl_dim1];
/* L20: */
}
if (dim == 2) {
area = (d__1 = da[0] * db[1] - db[0] * da[1], abs(d__1));
} else {
/* Computing 2nd power */
d__1 = da[1] * db[2] - db[1] * da[2];
/* Computing 2nd power */
d__2 = da[2] * db[0] - db[2] * da[0];
/* Computing 2nd power */
d__3 = da[0] * db[1] - db[0] * da[1];
area = d__1 * d__1 + d__2 * d__2 + d__3 * d__3;
}
if (area > armax) {
h__ = i__;
armax = area;
}
/* L30: */
}
if (dim == 2) {
/* Computing 2nd power */
d__1 = armax;
armax = d__1 * d__1;
}
/* Computing 2nd power */
d__1 = *dtol;
if (armax <= d__1 * d__1) {
return;
}
/* Direction of ray is from PT through midpoint of edge subtending */
/* max area. NR is unit normal of line or plane containing ray, */
/* which is also orthogonal to NRML in 3-D case. */
la = pgind[(h__ - 1) * inc];
lb = pgind[h__ * inc];
dir[0] = (vcl[la * vcl_dim1 + 1] + vcl[lb * vcl_dim1 + 1]) * .5 - pt[1];
dir[1] = (vcl[la * vcl_dim1 + 2] + vcl[lb * vcl_dim1 + 2]) * .5 - pt[2];
if (dim == 2) {
/* Computing 2nd power */
d__1 = dir[0];
/* Computing 2nd power */
d__2 = dir[1];
dist = sqrt(d__1 * d__1 + d__2 * d__2);
dir[0] /= dist;
dir[1] /= dist;
dir[2] = 0.;
nr[0] = -dir[1];
nr[1] = dir[0];
nr[3] = nr[0] * pt[1] + nr[1] * pt[2];
dist = nr[0] * vcl[lb * vcl_dim1 + 1] + nr[1] * vcl[lb * vcl_dim1 + 2]
- nr[3];
} else {
dir[2] = (vcl[la * vcl_dim1 + 3] + vcl[lb * vcl_dim1 + 3]) * .5 - pt[
3];
/* Computing 2nd power */
d__1 = dir[0];
/* Computing 2nd power */
d__2 = dir[1];
/* Computing 2nd power */
d__3 = dir[2];
dist = sqrt(d__1 * d__1 + d__2 * d__2 + d__3 * d__3);
dir[0] /= dist;
dir[1] /= dist;
dir[2] /= dist;
nr[0] = nrml[2] * dir[2] - nrml[3] * dir[1];
nr[1] = nrml[3] * dir[0] - nrml[1] * dir[2];
nr[2] = nrml[1] * dir[1] - nrml[2] * dir[0];
nr[3] = nr[0] * pt[1] + nr[1] * pt[2] + nr[2] * pt[3];
dist = nr[0] * vcl[lb * vcl_dim1 + 1] + nr[1] * vcl[lb * vcl_dim1 + 2]
+ nr[2] * vcl[lb * vcl_dim1 + 3] - nr[3];
}
if (dist > 0.) {
sb = 1;
} else {
sb = -1;
}
m = 1;
if (abs(dir[1]) > abs(dir[0])) {
m = 2;
}
if (abs(dir[2]) > (d__1 = dir[m - 1], abs(d__1))) {
m = 3;
}
k = 1;
/* For remaining edges of polygon, check whether ray intersects edge. */
/* Vertices or edges lying on ray are handled by looking at preceding */
/* and succeeding edges not lying on ray. */
k = 1;
i__ = h__ + 1;
if (i__ > *nv) {
i__ = 1;
}
L40:
la = lb;
lb = pgind[i__ * inc];
sa = sb;
if (dim == 2) {
dist = nr[0] * vcl[lb * vcl_dim1 + 1] + nr[1] * vcl[lb * vcl_dim1 + 2]
- nr[3];
} else {
dist = nr[0] * vcl[lb * vcl_dim1 + 1] + nr[1] * vcl[lb * vcl_dim1 + 2]
+ nr[2] * vcl[lb * vcl_dim1 + 3] - nr[3];
}
if (abs(dist) <= *dtol) {
sb = 0;
} else if (dist > 0.) {
sb = 1;
} else {
sb = -1;
}
s = sa * sb;
if (s < 0) {
if (dim == 2) {
da[0] = vcl[la * vcl_dim1 + 1] - vcl[lb * vcl_dim1 + 1];
da[1] = vcl[la * vcl_dim1 + 2] - vcl[lb * vcl_dim1 + 2];
rhs[0] = vcl[la * vcl_dim1 + 1] - pt[1];
rhs[1] = vcl[la * vcl_dim1 + 2] - pt[2];
t = (rhs[0] * da[1] - rhs[1] * da[0]) / (dir[0] * da[1] - dir[1] *
da[0]);
} else {
da[0] = vcl[la * vcl_dim1 + 1] - vcl[lb * vcl_dim1 + 1];
da[1] = vcl[la * vcl_dim1 + 2] - vcl[lb * vcl_dim1 + 2];
da[2] = vcl[la * vcl_dim1 + 3] - vcl[lb * vcl_dim1 + 3];
rhs[0] = vcl[la * vcl_dim1 + 1] - pt[1];
rhs[1] = vcl[la * vcl_dim1 + 2] - pt[2];
rhs[2] = vcl[la * vcl_dim1 + 3] - pt[3];
cp[0] = dir[1] * da[2] - dir[2] * da[1];
cp[1] = dir[2] * da[0] - dir[0] * da[2];
cp[2] = dir[0] * da[1] - dir[1] * da[0];
l = 1;
if (abs(cp[1]) > abs(cp[0])) {
l = 2;
}
if (abs(cp[2]) > (d__1 = cp[l - 1], abs(d__1))) {
l = 3;
}
if (l == 1) {
t = (rhs[1] * da[2] - rhs[2] * da[1]) / cp[0];
} else if (l == 2) {
t = (rhs[2] * da[0] - rhs[0] * da[2]) / cp[1];
} else {
t = (rhs[0] * da[1] - rhs[1] * da[0]) / cp[2];
}
}
if (t > *dtol) {
++k;
} else if (t >= -(*dtol)) {
*inout = 0;
return;
}
} else if (s == 0) {
l = lb;
L50:
++i__;
if (i__ > *nv) {
i__ = 1;
}
if (i__ == h__) {
return;
}
la = lb;
lb = pgind[i__ * inc];
if (dim == 2) {
dist = nr[0] * vcl[lb * vcl_dim1 + 1] + nr[1] * vcl[lb * vcl_dim1
+ 2] - nr[3];
} else {
dist = nr[0] * vcl[lb * vcl_dim1 + 1] + nr[1] * vcl[lb * vcl_dim1
+ 2] + nr[2] * vcl[lb * vcl_dim1 + 3] - nr[3];
}
if (abs(dist) <= *dtol) {
goto L50;
} else if (dist > 0.) {
sb = 1;
} else {
sb = -1;
}
t = (vcl[m + l * vcl_dim1] - pt[m]) / dir[m - 1];
if (abs(t) <= *dtol) {
*inout = 0;
return;
}
if (la != l) {
ta = (vcl[m + la * vcl_dim1] - pt[m]) / dir[m - 1];
if (abs(ta) <= *dtol || t * ta < 0.) {
*inout = 0;
return;
}
}
if (sa * sb < 0 && t > 0.) {
++k;
}
}
++i__;
if (i__ > *nv) {
i__ = 1;
}
if (i__ != h__) {
goto L40;
}
/* Point lies inside polygon if number of intersections K is odd. */
if (k % 2 == 1) {
*inout = 1;
} else {
*inout = -1;
}
return;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -