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)

模拟所需的是"碰撞检测算法".这些算法的领域很普遍,因为它与计算机游戏(Pong)一样古老,并且不可能在这里给出完整的答案.
你现在的模拟是非常基本的,因为你每次进步都会使你的带电球进入,这使得它们从一个位置"跳跃"到另一个位置.如果运动与恒定速度和零加速度一样简单,您就可以知道运动的精确方程,并可以通过简单地将时间放入方程式来计算所有位置.当一个球从墙上反弹时,它会得到一个新的等式.
有了这个,你可以预测,当两个球碰撞时.你只需要解决两个球,无论他们是否同时拥有相同的位置.这称为A Priori检测.当您按照现在进行模拟时,您必须在每个时间步检查两个球是否如此靠近在一起,它们可能会发生碰撞.
问题是,你的模拟速度不是无限高,你的球越快,模拟中的跳跃越大.然后,两个球互相跳过并且你错过了碰撞是不可能的.
考虑到这一点,您可以从阅读该主题的维基百科文章开始,以获得概述.接下来,您可以阅读一些有关它的科学文章或检查,裂缝是如何做到的.例如,Chipmunk物理引擎是一个惊人的二维物理引擎.为了确保这些东西有效,我很确定他们必须在碰撞检测中加入很多想法.