PostGIS  2.5.0dev-r@@SVN_REVISION@@

◆ lw_dist3d_ptarray_poly()

int lw_dist3d_ptarray_poly ( POINTARRAY pa,
LWPOLY poly,
PLANE3D plane,

Computes pointarray to polygon distance.

Definition at line 1051 of file measures3d.c.

References DISTPTS3D::distance, get_3dvector_from_points(), getPoint3dz_p(), intersects(), lw_dist3d_pt_poly(), lw_dist3d_ptarray_ptarray(), LW_FALSE, LW_TRUE, POINTARRAY::npoints, LWPOLY::nrings, DISTPTS3D::p1, DISTPTS3D::p2, project_point_on_plane(), pt_in_ring_3d(), LWPOLY::rings, VECTOR3D::x, POINT3DZ::x, VECTOR3D::y, POINT3DZ::y, VECTOR3D::z, and POINT3DZ::z.

Referenced by lw_dist3d_line_poly(), and lw_dist3d_poly_poly().

1052 {
1055  uint32_t i,j,k;
1056  double f, s1, s2;
1057  VECTOR3D projp1_projp2;
1058  POINT3DZ p1, p2,projp1, projp2, intersectionp;
1060  getPoint3dz_p(pa, 0, &p1);
1062  s1=project_point_on_plane(&p1, plane, &projp1); /*the sign of s1 tells us on which side of the plane the point is. */
1063  lw_dist3d_pt_poly(&p1, poly, plane,&projp1, dl);
1065  for (i=1;i<pa->npoints;i++)
1066  {
1067  int intersects;
1068  getPoint3dz_p(pa, i, &p2);
1069  s2=project_point_on_plane(&p2, plane, &projp2);
1070  lw_dist3d_pt_poly(&p2, poly, plane,&projp2, dl);
1072  /*If s1and s2 has different signs that means they are on different sides of the plane of the polygon.
1073  That means that the edge between the points crosses the plane and might intersect with the polygon*/
1074  if((s1*s2)<=0)
1075  {
1076  f=fabs(s1)/(fabs(s1)+fabs(s2)); /*The size of s1 and s2 is the distance from the point to the plane.*/
1077  get_3dvector_from_points(&projp1, &projp2,&projp1_projp2);
1079  /*get the point where the line segment crosses the plane*/
1080  intersectionp.x=projp1.x+f*projp1_projp2.x;
1081  intersectionp.y=projp1.y+f*projp1_projp2.y;
1082  intersectionp.z=projp1.z+f*projp1_projp2.z;
1084  intersects = LW_TRUE; /*We set intersects to true until the opposite is proved*/
1086  if(pt_in_ring_3d(&intersectionp, poly->rings[0], plane)) /*Inside outer ring*/
1087  {
1088  for (k=1;k<poly->nrings; k++)
1089  {
1090  /* Inside a hole, so no intersection with the polygon*/
1091  if ( pt_in_ring_3d(&intersectionp, poly->rings[k], plane ))
1092  {
1093  intersects=LW_FALSE;
1094  break;
1095  }
1096  }
1097  if(intersects)
1098  {
1099  dl->distance=0.0;
1100  dl->p1.x=intersectionp.x;
1101  dl->p1.y=intersectionp.y;
1102  dl->p1.z=intersectionp.z;
1104  dl->p2.x=intersectionp.x;
1105  dl->p2.y=intersectionp.y;
1106  dl->p2.z=intersectionp.z;
1107  return LW_TRUE;
1109  }
1110  }
1111  }
1113  projp1=projp2;
1114  s1=s2;
1115  p1=p2;
1116  }
1118  /*check or pointarray against boundary and inner boundaries of the polygon*/
1119  for (j=0;j<poly->nrings;j++)
1120  {
1121  lw_dist3d_ptarray_ptarray(pa, poly->rings[j], dl);
1122  }
1124 return LW_TRUE;
1125 }
double z
Definition: liblwgeom.h:336
double y
Definition: liblwgeom.h:336
double distance
Definition: measures3d.h:41
double x
Definition: liblwgeom.h:336
double z
Definition: measures3d.h:51
Definition: measures3d.h:43
double project_point_on_plane(POINT3DZ *p, PLANE3D *pl, POINT3DZ *p0)
Finds a point on a plane from where the original point is perpendicular to the plane.
Definition: measures3d.c:1200
Definition: measures3d.h:42
double y
Definition: measures3d.h:51
uint32_t nrings
Definition: liblwgeom.h:457
unsigned int uint32_t
Definition: uthash.h:78
int lw_dist3d_pt_poly(POINT3DZ *p, LWPOLY *poly, PLANE3D *plane, POINT3DZ *projp, DISTPTS3D *dl)
Checking if the point projected on the plane of the polygon actually is inside that polygon...
Definition: measures3d.c:1017
#define LW_FALSE
Definition: liblwgeom.h:76
Datum intersects(PG_FUNCTION_ARGS)
#define LW_TRUE
Return types for functions with status returns.
Definition: liblwgeom.h:75
Definition: liblwgeom.h:459
static int get_3dvector_from_points(POINT3DZ *p1, POINT3DZ *p2, VECTOR3D *v)
Definition: measures3d.c:45
int getPoint3dz_p(const POINTARRAY *pa, uint32_t n, POINT3DZ *point)
Definition: lwgeom_api.c:205
int pt_in_ring_3d(const POINT3DZ *p, const POINTARRAY *ring, PLANE3D *plane)
pt_in_ring_3d(): crossing number test for a point in a polygon input: p = a point, pa = vertex points of a ring V[n+1] with V[n]=V[0] plane=the plane that the vertex points are lying on returns: 0 = outside, 1 = inside
Definition: measures3d.c:1238
double x
Definition: measures3d.h:51
int lw_dist3d_ptarray_ptarray(POINTARRAY *l1, POINTARRAY *l2, DISTPTS3D *dl)
Finds all combinations of segments between two pointarrays.
Definition: measures3d.c:841
uint32_t npoints
Definition: liblwgeom.h:373
Here is the call graph for this function:
Here is the caller graph for this function: