粒子と線要素の接触

Pythonで有限差分法、有限要素法などの数値解析を勉強中。



粒子と線要素の接触

基本的な流れは、以下です。
・線と円の距離を算出し、線と触れる範囲か判定する
・線分と円の接触判定し、接点の座標を取得する
接触点の座標を取得するのは、のちの処理のためです。

この手の処理を実装する際、一般に、ベクトル演算の内積・外積という 概念が登場するのですが、よくわからないので、 三角関数(sin,cos,tan)で実装しました。
三角関数は処理が遅いので、ほんとは使わない方が良いです。

線と円の接触判定

線と円の最短距離(垂線)の長さを算出し、円の半径以下か判定します。 線分の始点をベースに、始点と円の中点を結ぶ線と線分の角度Θをatanで求め、 始点と円の距離×sinΘで、円の中点と線との距離を算出しました。

  1. p = particles[i]
  2. l = lines[j]
  3. th0 = math.atan2(l.y2-l.y1, l.x2-l.x1)
  4. th1 = math.atan2(p.y-l.y1, p.x-l.x1)
  5. a = math.sqrt((p.x-l.x1)**2+(p.y-l.y1)**2)
  6. d = abs(a*math.sin(th1-th0))
  7. if d < p.r:
  8. print('touched!')

線分と円の接触判定と接点座標の取得

この処理では、触れている箇所が線分上か、始点か、終点かに分岐します。

線分上の内、円が始点に接している条件での終点と円の中点の長さSを求めます。 また、始点と円の中点との長さAと、終点と円の中点の長さBを求めます。 AとBがどちらもSより短い条件が、線分と接している条件になります。

それよりも外側に出ていて、始点に点接触している条件は、 始点と円の中点との長さが円の半径以下になっている時です。 円が始点よりかどうかは、長さAが長さBより小さいかで判定します。 終点の場合は、その逆です。

  1. if d < p.r:
  2. a = math.sqrt((p.x-l.x1)**2+(p.y-l.y1)**2)
  3. b = math.sqrt((p.x-l.x2)**2+(p.y-l.y2)**2)
  4. s = math.sqrt((l.x2-l.x1)**2+(l.y2-l.y1)**2)
  5. s = math.sqrt(s**2 + p.r**2)
  6. if a < s and b < s:
  7. c = math.sqrt(a**2-d**2)
  8. x = l.x1 + c*math.cos(th0)
  9. y = l.y1 + c*math.sin(th0)
  10. elif a < b and a < p.r:
  11. x = l.x1
  12. y = l.y1
  13. elif b < p.r:
  14. x = l.x2
  15. y = l.y2

線要素と粒子間の力

線要素と粒子間の力の処理は、粒子同士の処理と一緒です(同じ関数)。 異なる点は、法線方向を円の中点同士ではなく、接点とするので、上記の処理の座標と することと、バネ定数などのパラメータです。

ページトップへ