@@ -82,69 +82,12 @@ polygon.tester = function tester(ptsIn) {
8282 }
8383
8484 function contains ( pt , omitFirstEdge ) {
85- var x = pt [ 0 ] ;
86- var y = pt [ 1 ] ;
87-
88- if ( x === BADNUM || x < xmin || x > xmax || y === BADNUM || y < ymin || y > ymax ) {
89- // pt is outside the bounding box of polygon
90- return false ;
91- }
92-
93- var imax = pts . length ;
94- var x1 = pts [ 0 ] [ 0 ] ;
95- var y1 = pts [ 0 ] [ 1 ] ;
96- var crossings = 0 ;
97- var i ;
98- var x0 ;
99- var y0 ;
100- var xmini ;
101- var ycross ;
102-
103- for ( i = 1 ; i < imax ; i ++ ) {
104- // find all crossings of a vertical line upward from pt with
105- // polygon segments
106- // crossings exactly at xmax don't count, unless the point is
107- // exactly on the segment, then it counts as inside.
108- x0 = x1 ;
109- y0 = y1 ;
110- x1 = pts [ i ] [ 0 ] ;
111- y1 = pts [ i ] [ 1 ] ;
112- xmini = Math . min ( x0 , x1 ) ;
113-
114- if ( x < xmini || x > Math . max ( x0 , x1 ) || y > Math . max ( y0 , y1 ) ) {
115- // outside the bounding box of this segment, it's only a crossing
116- // if it's below the box.
117-
118- continue ;
119- } else if ( y < Math . min ( y0 , y1 ) ) {
120- // don't count the left-most point of the segment as a crossing
121- // because we don't want to double-count adjacent crossings
122- // UNLESS the polygon turns past vertical at exactly this x
123- // Note that this is repeated below, but we can't factor it out
124- // because
125- if ( x !== xmini ) crossings ++ ;
126- } else {
127- // inside the bounding box, check the actual line intercept
128-
129- // vertical segment - we know already that the point is exactly
130- // on the segment, so mark the crossing as exactly at the point.
131- if ( x1 === x0 ) ycross = y ;
132- // any other angle
133- else ycross = y0 + ( x - x0 ) * ( y1 - y0 ) / ( x1 - x0 ) ;
134-
135- // exactly on the edge: counts as inside the polygon, unless it's the
136- // first edge and we're omitting it.
137- if ( y === ycross ) {
138- if ( i === 1 && omitFirstEdge ) return false ;
139- return true ;
140- }
141-
142- if ( y <= ycross && x !== xmini ) crossings ++ ;
143- }
144- }
145-
146- // if we've gotten this far, odd crossings means inside, even is outside
147- return crossings % 2 === 1 ;
85+ return polygon . contains ( pts , pt , omitFirstEdge , {
86+ xmin : xmin ,
87+ xmax : xmax ,
88+ ymin : ymin ,
89+ ymax : ymax
90+ } ) ;
14891 }
14992
15093 // detect if poly is degenerate
@@ -169,6 +112,79 @@ polygon.tester = function tester(ptsIn) {
169112 } ;
170113} ;
171114
115+ polygon . contains = function ( pts , pt , omitFirstEdge , opts ) {
116+ var x = pt [ 0 ] ;
117+ var y = pt [ 1 ] ;
118+
119+ if ( opts ) {
120+ var xmin = opts . xmin ;
121+ var xmax = opts . xmax ;
122+ var ymin = opts . ymin ;
123+ var ymax = opts . ymax ;
124+
125+ if ( x === BADNUM || x < xmin || x > xmax || y === BADNUM || y < ymin || y > ymax ) {
126+ // pt is outside the bounding box of polygon
127+ return false ;
128+ }
129+ }
130+
131+ var imax = pts . length ;
132+ var x1 = pts [ 0 ] [ 0 ] ;
133+ var y1 = pts [ 0 ] [ 1 ] ;
134+ var crossings = 0 ;
135+ var i ;
136+ var x0 ;
137+ var y0 ;
138+ var xmini ;
139+ var ycross ;
140+
141+ for ( i = 1 ; i < imax ; i ++ ) {
142+ // find all crossings of a vertical line upward from pt with
143+ // polygon segments
144+ // crossings exactly at xmax don't count, unless the point is
145+ // exactly on the segment, then it counts as inside.
146+ x0 = x1 ;
147+ y0 = y1 ;
148+ x1 = pts [ i ] [ 0 ] ;
149+ y1 = pts [ i ] [ 1 ] ;
150+ xmini = Math . min ( x0 , x1 ) ;
151+
152+ if ( x < xmini || x > Math . max ( x0 , x1 ) || y > Math . max ( y0 , y1 ) ) {
153+ // outside the bounding box of this segment, it's only a crossing
154+ // if it's below the box.
155+
156+ continue ;
157+ } else if ( y < Math . min ( y0 , y1 ) ) {
158+ // don't count the left-most point of the segment as a crossing
159+ // because we don't want to double-count adjacent crossings
160+ // UNLESS the polygon turns past vertical at exactly this x
161+ // Note that this is repeated below, but we can't factor it out
162+ // because
163+ if ( x !== xmini ) crossings ++ ;
164+ } else {
165+ // inside the bounding box, check the actual line intercept
166+
167+ // vertical segment - we know already that the point is exactly
168+ // on the segment, so mark the crossing as exactly at the point.
169+ if ( x1 === x0 ) ycross = y ;
170+ // any other angle
171+ else ycross = y0 + ( x - x0 ) * ( y1 - y0 ) / ( x1 - x0 ) ;
172+
173+ // exactly on the edge: counts as inside the polygon, unless it's the
174+ // first edge and we're omitting it.
175+ if ( y === ycross ) {
176+ if ( i === 1 && omitFirstEdge ) return false ;
177+ return true ;
178+ }
179+
180+ if ( y <= ycross && x !== xmini ) crossings ++ ;
181+ }
182+ }
183+
184+ // if we've gotten this far, odd crossings means inside, even is outside
185+ return crossings % 2 === 1 ;
186+ } ;
187+
172188/**
173189 * Test if a segment of a points array is bent or straight
174190 *
0 commit comments