Implementing a Quadtree in Mathematica

后端 未结 3 539
予麋鹿
予麋鹿 2020-12-12 11:48

I have implemented a quadtree in Mathematica. I am new to coding in a functional programming language like Mathematica, and I was wondering if I could improve this or make i

3条回答
  •  感情败类
    2020-12-12 12:10

    Here is a more compact version. It uses the same data structure as the original version. The functions splitBox and insideBox are essentially the same as well (just written in a slightly different way).

    Instead of adding points one-by-one, the initial box contains all the points at the beginning so there is no need for the qtInsert routines. In each recursion step, the boxes containing more than one point are split and the points are distributed over the sub-boxes. This means that all nodes with more than one point are leafs so there is no need to check for that either.

    qtMakeNode[bb_, pts_] := {{}, {}, {}, {}, qtbb @@ bb, pts}
    
    splitBox[bx_] := splitBox[{min_, max_}] := {min + #, max + #}/2 & /@  
      Tuples[Transpose[{min, max}]]
    
    
    insideBox[pt_, bb_] := bb[[1, 1]] <= pt[[1]] <= bb[[2, 1]] && 
      bb[[1, 2]] <= pt[[2]] <= bb[[2, 2]]
    
    distribute[qtree_] := Which[
      Length[qtree[[6]]] == 1, 
        (* no points in node -> return node unchanged *)
      qtree,
    
      Length[qtree[[6]]] == 1, 
        (* one point in node -> replace head of point with qtpt and return node *)
      ReplacePart[qtree, 6 -> qtpt @@ qtree[[6, 1]]],
    
      Length[qtree[[6]]] > 1, 
        (* multiple points in node -> create sub-nodes and distribute points *)
        (* apply distribute to sub-nodes *) 
      Module[{spl = splitBox[qtree[[5]]], div, newtreelist},
       div = Cases[qtree[[6]], a_ /; insideBox[a, #], 1] & /@ spl;
       ReplacePart[qtree, 
        Join[Table[i -> distribute[qtMakeNode[spl[[i]], div[[i]]]], {i, 4}], 
          {6 -> {}}]]]]
    

    Example (using the original version of qtDraw):

    len = 50;
    pts = RandomReal[{0, 2}, {len, 2}];
    qt = makeTree[qtMakeNode[{{0.0, 0.0}, {2.0, 2.0}}, pts]];
    qtDraw[qt]
    

    Result:

    Quadtree example

提交回复
热议问题