@@ -693,59 +693,58 @@ d3.geom.delaunay = function(vertices) {
693693
694694 return triangles ;
695695} ;
696- /**
697- * Constructs a new quadtree for the specified array of points. A quadtree is a
698- * two-dimensional recursive spatial subdivision. This implementation uses
699- * square partitions, dividing each square into four equally-sized squares. Each
700- * point exists in a unique node; if multiple points are in the same position,
701- * some points may be stored on internal nodes rather than leaf nodes. Quadtrees
702- * can be used to accelerate various spatial operations, such as the Barnes-Hut
703- * approximation for computing n-body forces, or collision detection.
704- *
705- * @param points [{x: x1, y: y1}, {x: x2, y: y2}, …]
706- * @return quadtree root {left: boolean, nodes: […], point: {x: x, y: y}}
707- */
708- d3 . geom . quadtree = function ( points ) {
696+ // Constructs a new quadtree for the specified array of points. A quadtree is a
697+ // two-dimensional recursive spatial subdivision. This implementation uses
698+ // square partitions, dividing each square into four equally-sized squares. Each
699+ // point exists in a unique node; if multiple points are in the same position,
700+ // some points may be stored on internal nodes rather than leaf nodes. Quadtrees
701+ // can be used to accelerate various spatial operations, such as the Barnes-Hut
702+ // approximation for computing n-body forces, or collision detection.
703+ d3 . geom . quadtree = function ( points , x1 , y1 , x2 , y2 ) {
709704 var p ,
710705 i = - 1 ,
711706 n = points . length ;
712707
713- /* Type conversion for deprecated API. */
708+ // Type conversion for deprecated API.
714709 if ( n && isNaN ( points [ 0 ] . x ) ) points = points . map ( d3_geom_quadtreePoint ) ;
715710
716- /* Compute bounds. */
717- var x1 = Infinity , y1 = x1 ,
718- x2 = - Infinity , y2 = x2 ;
719- while ( ++ i < n ) {
720- p = points [ i ] ;
721- if ( p . x < x1 ) x1 = p . x ;
722- if ( p . y < y1 ) y1 = p . y ;
723- if ( p . x > x2 ) x2 = p . x ;
724- if ( p . y > y2 ) y2 = p . y ;
711+ // Allow bounds to be specified explicitly.
712+ if ( arguments . length < 5 ) {
713+ if ( arguments . length === 3 ) {
714+ y2 = x2 = y1 ;
715+ y1 = x1 ;
716+ } else {
717+ x1 = y1 = Infinity ;
718+ x2 = y2 = - Infinity ;
719+
720+ // Compute bounds.
721+ while ( ++ i < n ) {
722+ p = points [ i ] ;
723+ if ( p . x < x1 ) x1 = p . x ;
724+ if ( p . y < y1 ) y1 = p . y ;
725+ if ( p . x > x2 ) x2 = p . x ;
726+ if ( p . y > y2 ) y2 = p . y ;
727+ }
728+
729+ // Squarify the bounds.
730+ var dx = x2 - x1 ,
731+ dy = y2 - y1 ;
732+ if ( dx > dy ) y2 = y1 + dx ;
733+ else x2 = x1 + dy ;
734+ }
725735 }
726736
727- /* Squarify the bounds. */
728- var dx = x2 - x1 ,
729- dy = y2 - y1 ;
730- if ( dx > dy ) y2 = y1 + dx ;
731- else x2 = x1 + dy ;
732-
733- /**
734- * @ignore Recursively inserts the specified point <i>p</i> at the node
735- * <i>n</i> or one of its descendants. The bounds are defined by [<i>x1</i>,
736- * <i>x2</i>] and [<i>y1</i>, <i>y2</i>].
737- */
737+ // Recursively inserts the specified point p at the node n or one of its
738+ // descendants. The bounds are defined by [x1, x2] and [y1, y2].
738739 function insert ( n , p , x1 , y1 , x2 , y2 ) {
739740 if ( isNaN ( p . x ) || isNaN ( p . y ) ) return ; // ignore invalid points
740741 if ( n . leaf ) {
741742 var v = n . point ;
742743 if ( v ) {
743- /*
744- * If the point at this leaf node is at the same position as the new
745- * point we are adding, we leave the point associated with the
746- * internal node while adding the new point to a child node. This
747- * avoids infinite recursion.
748- */
744+ // If the point at this leaf node is at the same position as the new
745+ // point we are adding, we leave the point associated with the
746+ // internal node while adding the new point to a child node. This
747+ // avoids infinite recursion.
749748 if ( ( Math . abs ( v . x - p . x ) + Math . abs ( v . y - p . y ) ) < .01 ) {
750749 insertChild ( n , p , x1 , y1 , x2 , y2 ) ;
751750 } else {
@@ -761,41 +760,39 @@ d3.geom.quadtree = function(points) {
761760 }
762761 }
763762
764- /**
765- * @ignore Recursively inserts the specified point <i>p</i> into a
766- * descendant of node <i>n</i>. The bounds are defined by [<i>x1</i>,
767- * <i>x2</i>] and [<i>y1</i>, <i>y2</i>].
768- */
763+ // Recursively inserts the specified point p into a descendant of node n. The
764+ // bounds are defined by [x1, x2] and [y1, y2].
769765 function insertChild ( n , p , x1 , y1 , x2 , y2 ) {
770- /* Compute the split point, and the quadrant in which to insert p. */
766+ // Compute the split point, and the quadrant in which to insert p.
771767 var sx = ( x1 + x2 ) * .5 ,
772768 sy = ( y1 + y2 ) * .5 ,
773769 right = p . x >= sx ,
774770 bottom = p . y >= sy ,
775771 i = ( bottom << 1 ) + right ;
776772
777- /* Recursively insert into the child node. */
773+ // Recursively insert into the child node.
778774 n . leaf = false ;
779775 n = n . nodes [ i ] || ( n . nodes [ i ] = d3_geom_quadtreeNode ( ) ) ;
780776
781- /* Update the bounds as we recurse. */
777+ // Update the bounds as we recurse.
782778 if ( right ) x1 = sx ; else x2 = sx ;
783779 if ( bottom ) y1 = sy ; else y2 = sy ;
784780 insert ( n , p , x1 , y1 , x2 , y2 ) ;
785781 }
786782
787- /* Create the root node. */
783+ // Create the root node.
788784 var root = d3_geom_quadtreeNode ( ) ;
789785
790- /* Insert all points. */
791- i = - 1 ;
792- while ( ++ i < n ) insert ( root , points [ i ] , x1 , y1 , x2 , y2 ) ;
786+ root . add = function ( p ) {
787+ insert ( root , p , x1 , y1 , x2 , y2 ) ;
788+ } ;
793789
794- /* Register a visitor function for the root. */
795790 root . visit = function ( f ) {
796791 d3_geom_quadtreeVisit ( f , root , x1 , y1 , x2 , y2 ) ;
797792 } ;
798793
794+ // Insert all points.
795+ points . forEach ( root . add ) ;
799796 return root ;
800797} ;
801798
0 commit comments