@@ -14,7 +14,7 @@ var dot = require('./matrix').dot;
1414 * Turn an array of [x, y] pairs into a polygon object
1515 * that can test if points are inside it
1616 *
17- * @param pts Array of [x, y] pairs
17+ * @param ptsIn Array of [x, y] pairs
1818 *
1919 * @returns polygon Object {xmin, xmax, ymin, ymax, pts, contains}
2020 * (x|y)(min|max) are the bounding rect of the polygon
@@ -43,6 +43,47 @@ polygon.tester = function tester(ptsIn) {
4343 ymax = Math . max ( ymax , pts [ i ] [ 1 ] ) ;
4444 }
4545
46+ // do we have a rectangle? Handle this here, so we can use the same
47+ // tester for the rectangular case without sacrificing speed
48+
49+ var isRect = false ,
50+ rectFirstEdgeTest ;
51+
52+ function onFirstVert ( pt ) { return pt [ 0 ] === pts [ 0 ] [ 0 ] ; }
53+ function onFirstHorz ( pt ) { return pt [ 1 ] === pts [ 0 ] [ 1 ] ; }
54+
55+ if ( pts . length === 5 ) {
56+ if ( pts [ 0 ] [ 0 ] === pts [ 1 ] [ 0 ] ) { // vert, horz, vert, horz
57+ if ( pts [ 2 ] [ 0 ] === pts [ 3 ] [ 0 ] &&
58+ pts [ 0 ] [ 1 ] === pts [ 3 ] [ 1 ] &&
59+ pts [ 1 ] [ 1 ] === pts [ 2 ] [ 1 ] ) {
60+ isRect = true ;
61+ rectFirstEdgeTest = onFirstVert ;
62+ }
63+ }
64+ else if ( pts [ 0 ] [ 1 ] === pts [ 1 ] [ 1 ] ) { // horz, vert, horz, vert
65+ if ( pts [ 2 ] [ 1 ] === pts [ 3 ] [ 1 ] &&
66+ pts [ 0 ] [ 0 ] === pts [ 3 ] [ 0 ] &&
67+ pts [ 1 ] [ 0 ] === pts [ 2 ] [ 0 ] ) {
68+ isRect = true ;
69+ rectFirstEdgeTest = onFirstHorz ;
70+ }
71+ }
72+ }
73+
74+ function rectContains ( pt , omitFirstEdge ) {
75+ var x = pt [ 0 ] ,
76+ y = pt [ 1 ] ;
77+
78+ if ( x < xmin || x > xmax || y < ymin || y > ymax ) {
79+ // pt is outside the bounding box of polygon
80+ return false ;
81+ }
82+ if ( omitFirstEdge && rectFirstEdgeTest ( pt ) ) return false ;
83+
84+ return true ;
85+ }
86+
4687 function contains ( pt , omitFirstEdge ) {
4788 var x = pt [ 0 ] ,
4889 y = pt [ 1 ] ;
@@ -115,7 +156,8 @@ polygon.tester = function tester(ptsIn) {
115156 ymin : ymin ,
116157 ymax : ymax ,
117158 pts : pts ,
118- contains : contains
159+ contains : isRect ? rectContains : contains ,
160+ isRect : isRect
119161 } ;
120162} ;
121163
0 commit comments