PostGIS  2.1.10dev-r@@SVN_REVISION@@
int lw_dist3d_ptarray_poly ( POINTARRAY pa,
LWPOLY poly,
PLANE3D plane,

Computes pointarray to polygon distance.

Definition at line 840 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, rect_node::p1, DISTPTS3D::p1, rect_node::p2, 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().

841 {
844  int i,j,k;
845  double f, s1, s2;
846  VECTOR3D projp1_projp2;
847  POINT3DZ p1, p2,projp1, projp2, intersectionp;
849  getPoint3dz_p(pa, 0, &p1);
851  s1=project_point_on_plane(&p1, plane, &projp1); /*the sign of s1 tells us on which side of the plane the point is. */
852  lw_dist3d_pt_poly(&p1, poly, plane,&projp1, dl);
854  for (i=1;i<pa->npoints;i++)
855  {
856  int intersects;
857  getPoint3dz_p(pa, i, &p2);
858  s2=project_point_on_plane(&p2, plane, &projp2);
859  lw_dist3d_pt_poly(&p2, poly, plane,&projp2, dl);
861  /*If s1and s2 has different signs that means they are on different sides of the plane of the polygon.
862  That means that the edge between the points crosses the plane and might intersect with the polygon*/
863  if((s1*s2)<=0)
864  {
865  f=fabs(s1)/(fabs(s1)+fabs(s2)); /*The size of s1 and s2 is the distance from the point to the plane.*/
866  get_3dvector_from_points(&projp1, &projp2,&projp1_projp2);
868  /*get the point where the line segment crosses the plane*/
869  intersectionp.x=projp1.x+f*projp1_projp2.x;
870  intersectionp.y=projp1.y+f*projp1_projp2.y;
871  intersectionp.z=projp1.z+f*projp1_projp2.z;
873  intersects = LW_TRUE; /*We set intersects to true until the opposite is proved*/
875  if(pt_in_ring_3d(&intersectionp, poly->rings[0], plane)) /*Inside outer ring*/
876  {
877  for (k=1;k<poly->nrings; k++)
878  {
879  /* Inside a hole, so no intersection with the polygon*/
880  if ( pt_in_ring_3d(&intersectionp, poly->rings[k], plane ))
881  {
882  intersects=LW_FALSE;
883  break;
884  }
885  }
886  if(intersects)
887  {
888  dl->distance=0.0;
889  dl->p1.x=intersectionp.x;
890  dl->p1.y=intersectionp.y;
891  dl->p1.z=intersectionp.z;
893  dl->p2.x=intersectionp.x;
894  dl->p2.y=intersectionp.y;
895  dl->p2.z=intersectionp.z;
896  return LW_TRUE;
898  }
899  }
900  }
902  projp1=projp2;
903  s1=s2;
904  p1=p2;
905  }
907  /*check or pointarray against boundary and inner boundaries of the polygon*/
908  for (j=0;j<poly->nrings;j++)
909  {
910  lw_dist3d_ptarray_ptarray(pa, poly->rings[j], dl);
911  }
913 return LW_TRUE;
914 }
double z
Definition: liblwgeom.h:290
double y
Definition: liblwgeom.h:290
double distance
Definition: measures3d.h:26
double x
Definition: liblwgeom.h:290
double z
Definition: measures3d.h:36
Definition: measures3d.h:28
int npoints
Definition: liblwgeom.h:327
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:989
Definition: measures3d.h:27
double y
Definition: measures3d.h:36
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:806
int getPoint3dz_p(const POINTARRAY *pa, int n, POINT3DZ *point)
Definition: lwgeom_api.c:305
#define LW_FALSE
Definition: liblwgeom.h:52
Datum intersects(PG_FUNCTION_ARGS)
#define LW_TRUE
Return types for functions with status returns.
Definition: liblwgeom.h:51
Definition: liblwgeom.h:413
int nrings
Definition: liblwgeom.h:411
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:1027
int get_3dvector_from_points(POINT3DZ *p1, POINT3DZ *p2, VECTOR3D *v)
Definition: measures3d.h:85
double x
Definition: measures3d.h:36
int lw_dist3d_ptarray_ptarray(POINTARRAY *l1, POINTARRAY *l2, DISTPTS3D *dl)
Finds all combinationes of segments between two pointarrays.
Definition: measures3d.c:630

Here is the call graph for this function:

Here is the caller graph for this function: