Как я могу определить гравитационную силу любого 2-го многоугольника? - PullRequest
4 голосов
/ 16 января 2020

(Работая в 2d для простоты) Я знаю, что сила, действующая на два сферических тела друг на друга под действием силы тяжести, равна G(m1*m2/r**2) Однако для несферического объекта я не могу найти алгоритм или формулу, способную рассчитать ту же силу. Моя первоначальная мысль состояла в том, чтобы упаковать круги в объект так, чтобы сила тяжести была равна сумме сил каждого из кругов. Например (псевдокод), * ​​1002 *

def gravity(pos1,shape):
     circles = packCircles(shape.points)
     force = 0
     for each circle in circles:
           distance = distanceTo(pos1,circle.pos)
           force += newtonForce(distance,shape.mass,1) #1 mass of observer
     return force 

Будет ли это жизнеспособным решением? Если да, то как бы я быстро и эффективно упаковывал круги? Если нет, то есть ли лучшее решение?

Редактировать: Обратите внимание, как я хочу найти силу объекта в указанной c точке, поэтому необходимо рассчитать углы между окружностью и наблюдателем (и векторы суммируются). Это отличается от нахождения общей приложенной силы.

1 Ответ

6 голосов
/ 18 января 2020

Справочная информация

Некоторые из этих объяснений будут несколько неуместны c, но я думаю, что необходимо помочь прояснить некоторые вещи, поднятые в комментариях, и потому, что многое из этого несколько противоречит интуиции.

Это объяснение гравитационных взаимодействий зависит от концепции точечных масс . Предположим, у вас есть две точечные массы, которые в изолированной системе отделены друг от друга некоторым расстоянием, r 1 , с массами m 1 и м 2 соответственно,

enter image description here

Создано гравитационное поле м 1 задается

enter image description here

, где G является универсальная гравитационная постоянная , r - это расстояние от m 1 и - единичное направление вдоль линии между м 1 и м 2 .

Гравитационная сила, действующая на м 2 этим полем, определяется как

enter image description here

Примечание - Важно то, что это верно для любых двухточечных масс на любом расстоянии. 1

полевая природа гравитационных взаимодействий позволяет нам использовать суперпозицию при расчете net гравитационной силы, обусловленной множественными взаимодействиями. Рассмотрим, добавим ли мы другую массу, м 3 к предыдущему сценарию,

enter image description here

Тогда гравитационное сила на массу м 2 - это просто сумма гравитационной силы полей, создаваемых каждой другой массой,

enter image description here

с r i, j = r j, i . Это справедливо для любого количества масс при любом разделении. Это также подразумевает, что поле, созданное набором масс, может быть агрегировано векторной суммой , если вы предпочитаете этот формализм.

Теперь рассмотрим, было ли у нас очень большое количество точечных масс, M , собранных вместе в непрерывное твердое тело однородной плотности. Затем мы хотели вычислить гравитационную силу на единичную пространственно-точечную массу, м , из-за совокупной массы M :

enter image description here

Тогда вместо учета точечных масс мы можем рассмотреть области (или объемы) массы дифференциального размера и либо интегрировать, либо суммировать влияние этих областей (или объемов) на точечную массу. В двумерном случае величина гравитационной силы равна

enter image description here

, где σ - плотность совокупной массы . 2 Это эквивалентно суммированию гравитационного векторного поля для каждой дифференциальной массы, σdxdy . Такая эквивалентность критически важна, поскольку подразумевает, что для любой точечной массы достаточно далеко за пределами распределения массы, гравитационная сила, обусловленная распределением массы, почти точно так же, как это было бы для точечной массы M , расположенной в центре масс распределения массы. 3 4

Это означает, что в очень хорошем приближении, когда дело доходит до вычисления гравитационного поля из-за любого распределения массы, распределение массы может быть заменено точечной массой эквивалентной массы в центре масс распределения. Это справедливо для любого числа пространственно различных массовых распределений, независимо от того, представляют ли эти распределения твердое тело или нет. Кроме того, это означает, что вы даже можете объединять групп распределений в единую точечную массу в центре масс системы. 5 Пока контрольная точка находится далеко достаточно далеко .

Однако , чтобы найти гравитационную силу на точечной массе, обусловленную распределением массы в любой точке, для любого распределения массы в зависимости от формы и разделения c, мы должны вычислить гравитационное поле в этой точке путем суммирования вкладов от каждой части распределения массы. 6

Вернуться к вопросу

Конечно, для произвольного многоугольника или многогранника аналитические Решение может быть непомерно трудным, поэтому гораздо проще использовать суммирование, а алгоритмы c подходы также будут использовать суммирование.

С точки зрения алгоритма, простейший подход здесь на самом деле не заключается в использовании геометрии c упаковки , с использованием кругов / сфер или квадратов / кубов. Использование упаковки не является невозможным, но с математической точки зрения у этого подхода есть серьезные проблемы - лучше использовать метод, основанный на более простой математике. Одним из таких подходов является определение сетки, охватывающей пространственную протяженность распределения масс, а затем создание простых (квадрат / куби c или прямоугольник / кубоид c) многоугольников или многогранников с точками сетки в качестве вершин. Это создает три вида многоугольников или многогранников:

  1. Те, которые не охватывают распределение массы
  2. Те, которые полностью заполнены распределением массы
  3. Те которые частично заполнены распределением массы

enter image description here

Центр масс - подход 1

Это будет хорошо работать, когда расстояние от контрольной точки до распределения масс велико по отношению к angular степени распределения, а при отсутствии геометрии c вложения эталона по распределению масс (или любым другим распределениям).

Затем можно найти центр масс, R распределения, суммируя вклады каждого многоугольника,

enter image description here

где M - общая масса распределения, r i - пространственный вектор геометрии c центра ith многоугольник и m i - плотность, умноженная на часть многоугольника, которая содержит массу (то есть 1,00 для полностью заполненных многоугольников и 0,00 для полностью пустых многоугольников) , По мере увеличения размера выборки (количества точек сетки) приближение для центра масс будет приближаться к аналитическому решению. Получив центр масс, вычислить созданное гравитационное поле тривиально: вы просто помещаете точечную массу M в точку R и используете уравнение из выше .

Для демонстрации приведена реализация описанного подхода в двух измерениях в Python с использованием библиотеки shapely для операций многоугольника:

import numpy as np
import matplotlib.pyplot as plt
import shapely.geometry as geom

def centerOfMass(r, density = 1.0, n = 100):
    theta = np.linspace(0, np.pi*2, len(r))
    xy = np.stack([np.cos(theta)*r, np.sin(theta)*r], 1)

    mass_dist = geom.Polygon(xy)
    x, y = mass_dist.exterior.xy

    # Create the grid and populate with polygons
    gx, gy  = np.meshgrid(np.linspace(min(x), max(x), n), np.linspace(min(y), max(y), n))
    polygons = [geom.Polygon([[gx[i,j],    gy[i,j]], 
                              [gx[i,j+1],  gy[i,j+1]], 
                              [gx[i+1,j+1],gy[i+1,j+1]], 
                              [gx[i+1,j],  gy[i+1,j]],
                              [gx[i,j],    gy[i,j]]])
                for i in range(gx.shape[0]-1) for j in range(gx.shape[1]-1)]

    # Calculate center of mass
    R = np.zeros(2)
    M = 0
    for p in polygons:
        m = (p.intersection(mass_dist).area / p.area) * density
        M += m
        R += m * np.array([p.centroid.x, p.centroid.y])

    return geom.Point(R / M), M

density = 1.0     # kg/m^2
G = 6.67408e-11   # m^3/kgs^2
theta = np.linspace(0, np.pi*2, 100)
r = np.cos(theta*2+np.pi)+5+np.sin(theta)+np.cos(theta*3+np.pi/6)

R, M = centerOfMass(r, density)
m = geom.Point(20, 0)
r_1 = m.distance(R)
m_1 = 5.0         # kg
F = G * (m_1 * M) / r_1**2
rhat = np.array([R.x - m.x, R.y - m.y])
rhat /= (rhat[0]**2 + rhat[1]**2)**0.5

# Draw the mass distribution and force vector, etc
plt.figure(figsize=(12, 6))
plt.axis('off')
plt.plot(np.cos(theta)*r, np.sin(theta)*r, color='k', lw=0.5, linestyle='-')
plt.scatter(m.x, m.y, s=20, color='k')
plt.text(m.x, m.y-1, r'$m$', ha='center')
plt.text(1, -1, r'$M$', ha='center')
plt.quiver([m.x], [m.y], [rhat[0]], [rhat[1]], width=0.004, scale=0.25, scale_units='xy')
plt.text(m.x - 5, m.y + 1, r'$F = {:.5e}$'.format(F))
plt.scatter(R.x, R.y, color='k')
plt.text(R.x, R.y+0.5, 'Center of Mass', va='bottom', ha='center')
plt.gca().set_aspect('equal')
plt.show()

enter image description here

Этот подход немного излишний: в большинстве случаев достаточно найти центр тяжести и площадь многоугольника, умноженную на плотность для центра масс и общей массы. Тем не менее, он будет работать даже для неравномерного распределения массы - поэтому я использовал его для демонстрации.

Суммирование полей - Подход 2

Во многих случаях этот подход также излишним, особенно в сравнение с первым подходом, но он обеспечит наилучшее приближение при любых распределениях (в классическом режиме).

Идея здесь состоит в том, чтобы суммировать влияние каждого фрагмента распределения массы на точечную массу для определения гравитационной силы net (исходя из предпосылки, что гравитационные поля могут быть независимо добавлены)

class pointMass:
    def __init__(self, mass, x, y):
        self.mass = mass
        self.x = x
        self.y = y

density = 1.0     # kg/m^2
G = 6.67408e-11   # m^3/kgs^2

def netForce(r, m1, density = 1.0, n = 100):
    theta = np.linspace(0, np.pi*2, len(r))
    xy = np.stack([np.cos(theta)*r, np.sin(theta)*r], 1)

    # Create a shapely polygon for the mass distribution
    mass_dist = geom.Polygon(xy)
    x, y = mass_dist.exterior.xy

    # Create the grid and populate with polygons
    gx, gy  = np.meshgrid(np.linspace(min(x), max(x), n), np.linspace(min(y), max(y), n))
    polygons = [geom.Polygon([[gx[i,j],    gy[i,j]], 
                              [gx[i,j+1],  gy[i,j+1]], 
                              [gx[i+1,j+1],gy[i+1,j+1]], 
                              [gx[i+1,j],  gy[i+1,j]],
                              [gx[i,j],    gy[i,j]]])
                for i in range(gx.shape[0]-1) for j in range(gx.shape[1]-1)]

    g = np.zeros(2)
    for p in polygons:
        m2 = (p.intersection(mass_dist).area / p.area) * density
        rhat = np.array([p.centroid.x - m1.x, p.centroid.y - m1.y]) 
        rhat /= (rhat[0]**2 + rhat[1]**2)**0.5
        g += m1.mass * m2 / p.centroid.distance(geom.Point(m1.x, m1.y))**2 * rhat
    g *= G

    return g

theta = np.linspace(0, np.pi*2, 100)
r = np.cos(theta*2+np.pi)+5+np.sin(theta)+np.cos(theta*3+np.pi/6)
m = pointMass(5.0, 20.0, 0.0)
g = netForce(r, m)

plt.figure(figsize=(12, 6))
plt.axis('off')
plt.plot(np.cos(theta)*r, np.sin(theta)*r, color='k', lw=0.5, linestyle='-')
plt.scatter(m.x, m.y, s=20, color='k')
plt.text(m.x, m.y-1, r'$m$', ha='center')
plt.text(1, -1, r'$M$', ha='center')
ghat = g / (g[0]**2 + g[1]**2)**0.5
plt.quiver([m.x], [m.y], [ghat[0]], [ghat[1]], width=0.004, scale=0.25, scale_units='xy')
plt.text(m.x - 5, m.y + 1, r'$F = ({:0.3e}, {:0.3e})$'.format(g[0], g[1]))
plt.gca().set_aspect('equal')
plt.show()

, что для относительно простого тестового примера дает результат, который очень близко к первому подходу:

enter image description here

Но хотя бывают случаи, когда первый подход не будет работать правильно, нет таких случаев, когда второй подход потерпит неудачу (в классическом режиме), поэтому рекомендуется отдать предпочтение этому подходу.


1 Это нарушается при крайних значениях, например, за горизонтом событий черных дыр или когда r приближается к Планковской длине , но эти случаи не предмет этого вопроса.

2 Это становится значительно более сложным в случаях, когда плотность неоднородна, и нет тривиального аналитического решения в случаях, когда распределение массы не может быть описывается символически.

3 Следует, вероятно, отметить, что это именно то, что делает интеграл ; найти центр масс.

4 Для точечной массы в пределах распределение массы Теорема Ньютона , или необходимо использовать суммирование поля.

5 В астрономии это называется барицентр , а тела всегда вращаются вокруг барицентра системы, а не центра масс любого данного тела.

6 В некоторых случаях достаточно использовать теорему Ньютона Shell , однако эти случаи не являются независимыми от геометрии распределения c.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...