在Mathematica的圆形区域内选择点

500*_*500 7 select wolfram-mathematica conditional-statements

请考虑 :

dalist = {{9, 6}, {5, 6}, {6, 0}, {0, 5}, {10, 8}, {1, 2}, {10, 4}, {1, 1}, {7, 7}, 
          {6, 8}, {5, 3}, {6, 10}, {7, 4}, {1, 8}, {10, 0}, {10, 7}, {6, 3}, {4, 0}, 
           {9, 2}, {4, 7}, {1, 6}, {10, 8}, {7, 8}, {0, 10}, {3, 4}, {0, 0}, {8, 5}, 
           {4, 5}, {6,0}, {2, 9}, {2, 4}, {8, 4}, {7, 4}, {3, 6}, {7, 10}, {1, 10}, 
           {1, 4}, {8, 0}, {8, 9}, {5, 4}, {2, 5}, {2, 9}, {3, 1}, {0, 6}, {10, 3}, 
           {9, 6}, {8, 7}, {7, 6}, {7, 3}, {8, 9}};

frameCenter = {5, 5};

criticalRadius = 2;

Graphics[{
          White, EdgeForm[Thick], Rectangle[{0, 0}, {10, 10}], Black,
          Point /@ dalist,
          Circle[frameCenter, 2]}];
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

我想创建一个测试来检查dalist并拒绝位于frameCenter内或某个半径上的点,如上图所示.我过去曾经用矩形区域做过这个,但我很困惑如何用圆形区域做到这一点

Leo*_*rin 7

这将是非常有效的:

In[82]:= 
Pick[dalist,UnitStep[criticalRadius^2-Total[(Transpose[dalist]-frameCenter)^2]],0]

Out[82]= 
{{6,0},{10,8},{10,4},{1,1},{6,10},{10,0},{10,7},{4,0},{10,8},
{0,10},{0,0},{6,0},{7,10},{1,10},{8,0},{0,6},{10,3}}
Run Code Online (Sandbox Code Playgroud)

或者,

In[86]:= Select[dalist, EuclideanDistance[#, frameCenter] > criticalRadius &]

Out[86]= {{6, 0}, {10, 8}, {10, 4}, {1, 1}, {6, 10}, {10, 0}, {10, 7}, {4, 0}, 
 {10, 8}, {0, 10}, {0, 0}, {6, 0}, {7, 10}, {1, 10}, {8, 0}, {0, 6}, {10, 3}}
Run Code Online (Sandbox Code Playgroud)


Dan*_*lau 7

最近可用于诸如在给定点的某个半径内找到每个集合成员的目的.一个人使用不完整记录的第三个参数形式,允许一对表示{max number,max distance}.在这种情况下,我们允许最大半径范围内的数量,因此最大数量只设置为无穷大.

In[9]:= DeleteCases[dalist, 
 Alternatives @@ 
  Nearest[dalist, frameCenter, {Infinity, criticalRadius}]]

Out[9]= {{9, 6}, {6, 0}, {0, 5}, {10, 8}, {1, 2}, {10, 4}, {1, 1}, {7,
   7}, {6, 8}, {6, 10}, {7, 4}, {1, 8}, {10, 0}, {10, 7}, {6, 3}, {4, 
  0}, {9, 2}, {4, 7}, {1, 6}, {10, 8}, {7, 8}, {0, 10}, {3, 4}, {0, 
  0}, {8, 5}, {6, 0}, {2, 9}, {2, 4}, {8, 4}, {7, 4}, {3, 6}, {7, 
  10}, {1, 10}, {1, 4}, {8, 0}, {8, 9}, {2, 5}, {2, 9}, {3, 1}, {0, 
  6}, {10, 3}, {9, 6}, {8, 7}, {7, 6}, {7, 3}, {8, 9}}
Run Code Online (Sandbox Code Playgroud)

---编辑---

关于具有无模式替代方案的DeleteCases的复杂性,如果输入大小为n且替代方案组具有m个元素,则它是O(n + m)而不是O(n*m).这是Mathematica的第8版.

以下示例将证实这一说法.我们从10 ^ 5个元素开始,删除大约18000个元素.需要0.17秒.然后我们使用10倍的元素,并删除超过10倍的数量(因此n和m都增加了10倍或更多).总时间为1.6秒,或大约10倍.

In[90]:= dalist5 = RandomInteger[{-10, 10}, {10^5, 2}];
criticalRadius5 = 5;
Timing[rest5 = 
   DeleteCases[dalist5, 
    Alternatives @@ (closest5 = 
       Nearest[dalist5, {0, 0}, {Infinity, criticalRadius5}])];]
Length[closest5]

Out[92]= {0.17, Null}

Out[93]= 18443

In[94]:= dalist6 = RandomInteger[{-10, 10}, {10^6, 2}];
criticalRadius6 = 6;
Timing[rest6 = 
   DeleteCases[dalist6, 
    Alternatives @@ (closest6 = 
       Nearest[dalist6, {0, 0}, {Infinity, criticalRadius6}])];]
Length[closest6]

Out[96]= {1.61, Null}

Out[97]= 256465
Run Code Online (Sandbox Code Playgroud)

- 结束编辑---

Daniel Lichtlau

  • +1表示显示最近的语法._less-than-well_可能意味着_not_? (3认同)
  • @Leonid正确的想法,但不适用于模式匹配器.Case和DeleteCases在第二个参数无模式时进行了优化.它们以您建议的方式工作:(1)散列替代方法(2)查找散列表中的每个元素.如果有(或没有,在DeleteCases中)然后播种它.(3)(如同每一个良好的道德游戏:)收获你播种的东西.这是我2009年9月9日的贡献(所以我可以说我那个月做了至少一件有用的事). (3认同)
  • @Leonid参见:http://forums.wolfram.com/mathgroup/archive/2010/Sep/msg00342.html (2认同)