如何在Mathematica中模拟多点电荷(滚珠轴承)之间的排斥?

Fer*_*235 8 physics wolfram-mathematica point spread

我正在尝试在Mathematica中编写一个程序,它将模拟带电球轴承在充电时充电的方式(它们相互排斥).到目前为止,我的程序使滚珠轴承不会从屏幕上移开,并计算它们撞到盒子侧面的次数.到目前为止,我的球轴承随机移动,但我需要知道如何使它们相互排斥.

到目前为止,这是我的代码:

Manipulate[
 (*If the number of points has been reduced, discard  points*)
 If[ballcount < Length[contents], 
   contents = Take[contents, ballcount]];

 (*If the number of points has been increased, generate some random points*)
 If[ballcount > Length[contents], 
  contents = 
   Join[contents, 
    Table[{RandomReal[{-size, size}, {2}], {Cos[#], Sin[#]} &[
       RandomReal[{0, 2 \[Pi]}]]}, {ballcount - Length[contents]}]]];

 Grid[{{Graphics[{PointSize[0.02],

  (*Draw the container*)
  Line[size {{-1, -1}, {1, -1}, {1, 1}, {-1, 1}, {-1, -1}}], 
  Blend[{Blue, Red}, charge/0.3],
  Point[

   (*Start the main dynamic actions*)
   Dynamic[

    (*Reset the collision counter*)
    collision = 0;

    (*Check for mouse interaction and add points if there has been one*)
    Refresh[
     If[pt =!= lastpt, If[ballcount =!= 50, ballcount++]; 
      AppendTo[
       contents, {pt, {Cos[#], Sin[#]} &[
         RandomReal[{0, 2 \[Pi]}]]}]; lastpt = pt], 
     TrackedSymbols -> {pt}];

    (*Update the position of the points using their velocity values*)
    contents = Map[{#[[1]] + #[[2]] charge, #[[2]]} &, contents];

    (*Check for and fix points that have exceeded the box in Y
      direction, incrementing the collision counter for each one*)
    contents = Map[
      If[Abs[#[[1, 2]]] > size, 
        collision++; {{#[[1, 1]], 
          2 size Sign[#[[1, 2]]] - #[[1, 2]]}, {1, -1} #[[
           2]]}, #] &,
      contents];


    (*Check for and fix points that have exceeded the box in X 
      direction, incrementing the collision counter for each one*)
    contents = Map[
      If[Abs[#[[1, 1]]] > size, 
        collision++; {{2 size Sign[#[[1, 1]]] - #[[1, 1]], #[[1, 
           2]]}, {-1, 1} #[[2]]}, #] &,
      contents];

    hits = Take[PadLeft[Append[hits, collision/size], 200], 200];
    Map[First, contents]]]},
 PlotRange -> {{-1.01, 1.01}, {-1.01, 1.01}}, 
 ImageSize -> {250, 250}],

(*Show the hits*)
Dynamic@Show
  [
   ListPlot
   [
   Take[MovingAverage[hits, smooth], -100
    ]
   ,
   Joined -> True, ImageSize -> {250, 250}, AspectRatio -> 1, 
   PlotLabel -> "number of hits", AxesLabel -> {"time", "hits"}, 
   PlotRange -> {0, Max[Max[hits], 1]}], Graphics[]
  ]
}}
  ]
 ,
 {{pt, {0, 1}}, {-1, -1}, {1, 1}, Locator, Appearance -> None},
 {{ballcount, 5, "number of ball bearings"}, 1, 50, 1},
 {{charge, 0.05, "charge"}, 0.002, 0.3},
 {smooth, 1, ControlType -> None, Appearance -> None},
 {size, 1, ControlType -> None, Appearance -> None},
 {hits, {{}}, ControlType -> None},
 {contents, {{}}, ControlType -> None},
 {lastpt, {{0, 0}}, ControlType -> None}
 ]
Run Code Online (Sandbox Code Playgroud)

Mathematica图形

hal*_*tan 7

模拟所需的是"碰撞检测算法".这些算法的领域很普遍,因为它与计算机游戏(Pong)一样古老,并且不可能在这里给出完整的答案.

你现在的模拟是非常基本的,因为你每次进步都会使你的带电球进入,这使得它们从一个位置"跳跃"到另一个位置.如果运动与恒定速度和零加速度一样简单,您就可以知道运动的精确方程,并可以通过简单地将时间放入方程式来计算所有位置.当一个球从墙上反弹时,它会得到一个新的等式.

有了这个,你可以预测,当两个球碰撞时.你只需要解决两个球,无论他们是否同时拥有相同的位置.这称为A Priori检测.当您按照现在进行模拟时,您必须在每个时间步检查两个球是否如此靠近在一起,它们可能会发生碰撞.

问题是,你的模拟速度不是无限高,你的球越快,模拟中的跳跃越大.然后,两个球互相跳过并且你错过了碰撞是不可能的.

考虑到这一点,您可以从阅读该主题的维基百科文章开始,以获得概述.接下来,您可以阅读一些有关它的科学文章或检查,裂缝是如何做到的.例如,Chipmunk物理引擎是一个惊人的二维物理引擎.为了确保这些东西有效,我很确定他们必须在碰撞检测中加入很多想法.