Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit74514bd

Browse files
committed
geo_ops.c: Clarify comments and function arguments
These functions were not crystal clear about what their respective APIsare. Make an effort to improve that.Emre's patch was correct AFAICT, but I (Álvaro) felt the need to improvea few comments a bit more. Any resulting errors are my own.Per complaint from Coverity, Ning Yu, and Tom Lane.Author: Emre Hasegeli, Álvaro HerreraReviewed-by: Tomas Vondra, Álvaro HerreraDiscussion:https://postgr.es/m/26769.1533090136@sss.pgh.pa.us
1 parent621a8ac commit74514bd

File tree

1 file changed

+100
-72
lines changed

1 file changed

+100
-72
lines changed

‎src/backend/utils/adt/geo_ops.c

Lines changed: 100 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,16 @@
33
* geo_ops.c
44
* 2D geometric operations
55
*
6+
* This module implements the geometric functions and operators. The
7+
* geometric types are (from simple to more complicated):
8+
*
9+
* - point
10+
* - line
11+
* - line segment
12+
* - box
13+
* - circle
14+
* - polygon
15+
*
616
* Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group
717
* Portions Copyright (c) 1994, Regents of the University of California
818
*
@@ -25,6 +35,34 @@
2535
#include"utils/fmgrprotos.h"
2636
#include"utils/geo_decls.h"
2737

38+
/*
39+
* * Type constructors have this form:
40+
* void type_construct(Type *result, ...);
41+
*
42+
* * Operators commonly have signatures such as
43+
* void type1_operator_type2(Type *result, Type1 *obj1, Type2 *obj2);
44+
*
45+
* Common operators are:
46+
* * Intersection point:
47+
* bool type1_interpt_type2(Point *result, Type1 *obj1, Type2 *obj2);
48+
*Return whether the two objects intersect. If *result is not NULL,
49+
*it is set to the intersection point.
50+
*
51+
* * Containment:
52+
* bool type1_contain_type2(Type1 *obj1, Type2 *obj2);
53+
*Return whether obj1 contains obj2.
54+
* bool type1_contain_type2(Type1 *contains_obj, Type1 *contained_obj);
55+
*Return whether obj1 contains obj2 (used when types are the same)
56+
*
57+
* * Distance of closest point in or on obj1 to obj2:
58+
* float8 type1_closept_type2(Point *result, Type1 *obj1, Type2 *obj2);
59+
*Returns the shortest distance between two objects. If *result is not
60+
*NULL, it is set to the closest point in or on obj1 to obj2.
61+
*
62+
* These functions may be used to implement multiple SQL-level operators. For
63+
* example, determining whether two lines are parallel is done by checking
64+
* whether they don't intersect.
65+
*/
2866

2967
/*
3068
* Internal routines
@@ -64,7 +102,7 @@ static intlseg_crossing(float8 x, float8 y, float8 px, float8 py);
64102
staticboollseg_contain_point(LSEG*lseg,Point*point);
65103
staticfloat8lseg_closept_point(Point*result,LSEG*lseg,Point*pt);
66104
staticfloat8lseg_closept_line(Point*result,LSEG*lseg,LINE*line);
67-
staticfloat8lseg_closept_lseg(Point*result,LSEG*l1,LSEG*l2);
105+
staticfloat8lseg_closept_lseg(Point*result,LSEG*on_lseg,LSEG*to_lseg);
68106

69107
/* Routines for boxes */
70108
staticinlinevoidbox_construct(BOX*result,Point*pt1,Point*pt2);
@@ -74,7 +112,7 @@ static float8 box_ar(BOX *box);
74112
staticfloat8box_ht(BOX*box);
75113
staticfloat8box_wd(BOX*box);
76114
staticboolbox_contain_point(BOX*box,Point*point);
77-
staticboolbox_contain_box(BOX*box1,BOX*box2);
115+
staticboolbox_contain_box(BOX*contains_box,BOX*contained_box);
78116
staticboolbox_contain_lseg(BOX*box,LSEG*lseg);
79117
staticboolbox_interpt_lseg(Point*result,BOX*box,LSEG*lseg);
80118
staticfloat8box_closept_point(Point*result,BOX*box,Point*point);
@@ -87,7 +125,7 @@ static float8 circle_ar(CIRCLE *circle);
87125
staticvoidmake_bound_box(POLYGON*poly);
88126
staticvoidpoly_to_circle(CIRCLE*result,POLYGON*poly);
89127
staticboollseg_inside_poly(Point*a,Point*b,POLYGON*poly,intstart);
90-
staticboolpoly_contain_poly(POLYGON*polya,POLYGON*polyb);
128+
staticboolpoly_contain_poly(POLYGON*contains_poly,POLYGON*contained_poly);
91129
staticboolplist_same(intnpts,Point*p1,Point*p2);
92130
staticfloat8dist_ppoly_internal(Point*pt,POLYGON*poly);
93131

@@ -648,15 +686,15 @@ box_contain(PG_FUNCTION_ARGS)
648686
}
649687

650688
/*
651-
* Check whether the box is in the box or on its border
689+
* Check whether thesecondbox is in the first box or on its border
652690
*/
653691
staticbool
654-
box_contain_box(BOX*box1,BOX*box2)
692+
box_contain_box(BOX*contains_box,BOX*contained_box)
655693
{
656-
returnFPge(box1->high.x,box2->high.x)&&
657-
FPle(box1->low.x,box2->low.x)&&
658-
FPge(box1->high.y,box2->high.y)&&
659-
FPle(box1->low.y,box2->low.y);
694+
returnFPge(contains_box->high.x,contained_box->high.x)&&
695+
FPle(contains_box->low.x,contained_box->low.x)&&
696+
FPge(contains_box->high.y,contained_box->high.y)&&
697+
FPle(contains_box->low.y,contained_box->low.y);
660698
}
661699

662700

@@ -1223,9 +1261,8 @@ line_interpt(PG_FUNCTION_ARGS)
12231261
/*
12241262
* Internal version of line_interpt
12251263
*
1226-
* This returns true if two lines intersect (they do, if they are not
1227-
* parallel), false if they do not. This also sets the intersection point
1228-
* to *result, if it is not NULL.
1264+
* Return whether two lines intersect. If *result is not NULL, it is set to
1265+
* the intersection point.
12291266
*
12301267
* NOTE: If the lines are identical then we will find they are parallel
12311268
* and report "no intersection". This is a little weird, but since
@@ -2244,10 +2281,9 @@ lseg_center(PG_FUNCTION_ARGS)
22442281

22452282

22462283
/*
2247-
*Find the intersection point of two segments (if any).
2284+
* Return whether the two segments intersect. If *result is not NULL,
2285+
* it is set to the intersection point.
22482286
*
2249-
* This returns true if two line segments intersect, false if they do not.
2250-
* This also sets the intersection point to *result, if it is not NULL.
22512287
* This function is almost perfectly symmetric, even though it doesn't look
22522288
* like it. See lseg_interpt_line() for the other half of it.
22532289
*/
@@ -2507,11 +2543,8 @@ dist_ppoly_internal(Point *pt, POLYGON *poly)
25072543
*-------------------------------------------------------------------*/
25082544

25092545
/*
2510-
* Check if the line segment intersects with the line
2511-
*
2512-
* This returns true if line segment intersects with line, false if they
2513-
* do not. This also sets the intersection point to *result, if it is not
2514-
* NULL.
2546+
* Return whether the line segment intersect with the line. If *result is not
2547+
* NULL, it is set to the intersection point.
25152548
*/
25162549
staticbool
25172550
lseg_interpt_line(Point*result,LSEG*lseg,LINE*line)
@@ -2534,21 +2567,20 @@ lseg_interpt_line(Point *result, LSEG *lseg, LINE *line)
25342567
*/
25352568
if (!lseg_contain_point(lseg,&interpt))
25362569
return false;
2537-
2538-
if (result==NULL)
2539-
return true;
2540-
2541-
/*
2542-
* If there is an intersection, then check explicitly for matching
2543-
* endpoints since there may be rounding effects with annoying LSB
2544-
* residue.
2545-
*/
2546-
if (point_eq_point(&lseg->p[0],&interpt))
2547-
*result=lseg->p[0];
2548-
elseif (point_eq_point(&lseg->p[1],&interpt))
2549-
*result=lseg->p[1];
2550-
else
2551-
*result=interpt;
2570+
if (result!=NULL)
2571+
{
2572+
/*
2573+
* If there is an intersection, then check explicitly for matching
2574+
* endpoints since there may be rounding effects with annoying LSB
2575+
* residue.
2576+
*/
2577+
if (point_eq_point(&lseg->p[0],&interpt))
2578+
*result=lseg->p[0];
2579+
elseif (point_eq_point(&lseg->p[1],&interpt))
2580+
*result=lseg->p[1];
2581+
else
2582+
*result=interpt;
2583+
}
25522584

25532585
return true;
25542586
}
@@ -2559,11 +2591,9 @@ lseg_interpt_line(Point *result, LSEG *lseg, LINE *line)
25592591
*-------------------------------------------------------------------*/
25602592

25612593
/*
2562-
*The intersection point of a perpendicular of the line
2563-
*through the point.
2564-
*
2565-
* This sets the closest point to the *result if it is not NULL and returns
2566-
* the distance to the closest point.
2594+
* If *result is not NULL, it is set to the intersection point of a
2595+
* perpendicular of the line through the point. Returns the distance
2596+
* of those two points.
25672597
*/
25682598
staticfloat8
25692599
line_closept_point(Point*result,LINE*line,Point*point)
@@ -2610,8 +2640,8 @@ close_pl(PG_FUNCTION_ARGS)
26102640
/*
26112641
* Closest point on line segment to specified point.
26122642
*
2613-
*This sets the closest pointto the*result if it is not NULL and returns
2614-
* the distanceto theclosest point.
2643+
*If *result is not NULL, set itto theclosest point on the line segment
2644+
*tothepoint. Returns thedistanceof thetwo points.
26152645
*/
26162646
staticfloat8
26172647
lseg_closept_point(Point*result,LSEG*lseg,Point*pt)
@@ -2650,27 +2680,24 @@ close_ps(PG_FUNCTION_ARGS)
26502680

26512681
/*
26522682
* Closest point on line segment to line segment
2653-
*
2654-
* This sets the closest point to the *result if it is not NULL and returns
2655-
* the distance to the closest point.
26562683
*/
26572684
staticfloat8
2658-
lseg_closept_lseg(Point*result,LSEG*l1,LSEG*l2)
2685+
lseg_closept_lseg(Point*result,LSEG*on_lseg,LSEG*to_lseg)
26592686
{
26602687
Pointpoint;
26612688
float8dist,
26622689
d;
26632690

26642691
/* First, we handle the case when the line segments are intersecting. */
2665-
if (lseg_interpt_lseg(result,l1,l2))
2692+
if (lseg_interpt_lseg(result,on_lseg,to_lseg))
26662693
return0.0;
26672694

26682695
/*
26692696
* Then, we find the closest points from the endpoints of the second
26702697
* line segment, and keep the closest one.
26712698
*/
2672-
dist=lseg_closept_point(result,l1,&l2->p[0]);
2673-
d=lseg_closept_point(&point,l1,&l2->p[1]);
2699+
dist=lseg_closept_point(result,on_lseg,&to_lseg->p[0]);
2700+
d=lseg_closept_point(&point,on_lseg,&to_lseg->p[1]);
26742701
if (float8_lt(d,dist))
26752702
{
26762703
dist=d;
@@ -2679,19 +2706,19 @@ lseg_closept_lseg(Point *result, LSEG *l1, LSEG *l2)
26792706
}
26802707

26812708
/* The closest point can still be one of the endpoints, so we test them. */
2682-
d=lseg_closept_point(NULL,l2,&l1->p[0]);
2709+
d=lseg_closept_point(NULL,to_lseg,&on_lseg->p[0]);
26832710
if (float8_lt(d,dist))
26842711
{
26852712
dist=d;
26862713
if (result!=NULL)
2687-
*result=l1->p[0];
2714+
*result=on_lseg->p[0];
26882715
}
2689-
d=lseg_closept_point(NULL,l2,&l1->p[1]);
2716+
d=lseg_closept_point(NULL,to_lseg,&on_lseg->p[1]);
26902717
if (float8_lt(d,dist))
26912718
{
26922719
dist=d;
26932720
if (result!=NULL)
2694-
*result=l1->p[1];
2721+
*result=on_lseg->p[1];
26952722
}
26962723

26972724
returndist;
@@ -2719,8 +2746,8 @@ close_lseg(PG_FUNCTION_ARGS)
27192746
/*
27202747
* Closest point on or in box to specified point.
27212748
*
2722-
*This sets the closest pointto the*result if it is not NULL and returns
2723-
* the distanceto theclosest point.
2749+
*If *result is not NULL, set itto theclosest point on the box to the
2750+
*given point, and returnthe distanceof thetwo points.
27242751
*/
27252752
staticfloat8
27262753
box_closept_point(Point*result,BOX*box,Point*pt)
@@ -2837,11 +2864,11 @@ close_sl(PG_FUNCTION_ARGS)
28372864
/*
28382865
* Closest point on line segment to line.
28392866
*
2840-
*This setstheclosest point tothe*result if it is not NULL and returns
2841-
*the distanceto theclosest point.
2867+
*Returnthedistance betweentheline and the closest point of the line
2868+
*segmentto theline. If *result is not NULL, set it to that point.
28422869
*
28432870
* NOTE: When the lines are parallel, endpoints of one of the line segment
2844-
* are FPeq(), in presence of NaN orInfinitive coordinates, or perhaps =
2871+
* are FPeq(), in presence of NaN orInfinite coordinates, or perhaps =
28452872
* even because of simple roundoff issues, there may not be a single closest
28462873
* point. We are likely to set the result to the second endpoint in these
28472874
* cases.
@@ -2896,8 +2923,8 @@ close_ls(PG_FUNCTION_ARGS)
28962923
/*
28972924
* Closest point on or in box to line segment.
28982925
*
2899-
*This setstheclosest point tothe*result if it is not NULL and returns
2900-
* thedistance to the closest point.
2926+
*Returnsthedistance betweentheclosest point on or in the box to
2927+
* theline segment. If *result is not NULL, it is set to that point.
29012928
*/
29022929
staticfloat8
29032930
box_closept_lseg(Point*result,BOX*box,LSEG*lseg)
@@ -3753,7 +3780,7 @@ touched_lseg_inside_poly(Point *a, Point *b, LSEG *s, POLYGON *poly, int start)
37533780
/*
37543781
* Returns true if segment (a,b) is in polygon, option
37553782
* start is used for optimization - function checks
3756-
* polygon's edgesstarted from start
3783+
* polygon's edgesstarting from start
37573784
*/
37583785
staticbool
37593786
lseg_inside_poly(Point*a,Point*b,POLYGON*poly,intstart)
@@ -3821,29 +3848,30 @@ lseg_inside_poly(Point *a, Point *b, POLYGON *poly, int start)
38213848
returnres;
38223849
}
38233850

3824-
/*-----------------------------------------------------------------
3825-
*Determine if polygon Acontainspolygon B.
3826-
*-----------------------------------------------------------------*/
3851+
/*
3852+
*Check whether the first polygoncontainsthe second
3853+
*/
38273854
staticbool
3828-
poly_contain_poly(POLYGON*polya,POLYGON*polyb)
3855+
poly_contain_poly(POLYGON*contains_poly,POLYGON*contained_poly)
38293856
{
38303857
inti;
38313858
LSEGs;
38323859

3833-
Assert(polya->npts>0&&polyb->npts>0);
3860+
Assert(contains_poly->npts>0&&contained_poly->npts>0);
38343861

38353862
/*
3836-
* Quick check to see if bounding box is contained.
3863+
* Quick check to see if contained's bounding box is contained in
3864+
* contains' bb.
38373865
*/
3838-
if (!box_contain_box(&polya->boundbox,&polyb->boundbox))
3866+
if (!box_contain_box(&contains_poly->boundbox,&contained_poly->boundbox))
38393867
return false;
38403868

3841-
s.p[0]=polyb->p[polyb->npts-1];
3869+
s.p[0]=contained_poly->p[contained_poly->npts-1];
38423870

3843-
for (i=0;i<polyb->npts;i++)
3871+
for (i=0;i<contained_poly->npts;i++)
38443872
{
3845-
s.p[1]=polyb->p[i];
3846-
if (!lseg_inside_poly(s.p,s.p+1,polya,0))
3873+
s.p[1]=contained_poly->p[i];
3874+
if (!lseg_inside_poly(s.p,s.p+1,contains_poly,0))
38473875
return false;
38483876
s.p[0]=s.p[1];
38493877
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp