簡體   English   中英

計算二維慣性張量

[英]Computing tensor of Inertia in 2D

我正在研究如何找到 2D 形狀的慣性。 這個形狀的輪廓由幾個點組成,每個點的 x 和 y 坐標是已知的。

我知道IxxIyyIxy的表達式,但身體沒有質量。 我該如何進行?

對於您擁有的任何形狀,您都需要將其拆分為三角形並分別處理每個三角形。 然后最后使用以下規則組合結果

總體

% Combined total area of all triangles
total_area = SUM( area(i), i=1:n )
total_mass = SUM( mass(i), i=1:n )
% Combined centroid (center of mass) coordinates
combined_centroid_x = SUM( mass(i)*centroid_x(i), i=1:n)/total_mass
combined_centroid_y = SUM( mass(i)*centroid_y(i), i=1:n)/total_mass
% Each distance to triangle (squared)
centroid_distance_sq(i) = centroid_x(i)*centroid_x(i)+centroid_y(i)*centroid_y(i)
% Combined mass moment of inertia
combined_mmoi = SUM(mmoi(i)+mass(i)*centroid_distance_sq(i), i=1:n)

現在為每個三角形。

考慮具有矢量坐標的三個角頂點,點ABC

a=[ax,ay]
b=[bx,by]
c=[cx,cy]

以及以下點積和叉積(標量)組合

a·a = ax*ax+ay*ay
b·b = bx*bx+by*by
c·c = cx*cx+cy*cy
a·b = ax*bx+ay*by
b·c = bx*cx+by*cy
c·a = cx*ax+cy*ay
a×b = ax*by-ay*bx
b×c = bx*cy-by*cx
c×a = cx*ay-cy*ax

三角形的屬性是( t(i)是厚度, rho是質量密度)

area(i) = 1/2*ABS( a×b + b×c + c×a )
mass(i) = rho*t(i)*area(i)
centroid_x(i) = 1/3*(ax + bx + cx)
centroid_y(i) = 1/3*(ay + by + cy)
mmoi(i) = 1/6*mass(i)*( a·a + b·b + c·c + a·b + b·c + c·a )

上面的組件是

area(i) = 1/2*ABS( ax*(by-cy)+ay*(cx-bx)+bx*cy-by*cx)
mmoi(i) = mass(i)/6*(ax^2+ax*(bx+cx)+bx^2+bx*cx+cx^2+ay^2+ay*(by+cy)+by^2+by*cy+cy^2)

附錄

這里有一個小理論。 每個三角形的面積是用

Area = 1/2 * || (b-a) × (c-b) ||

其中×是向量叉積,而|| .. || || .. || 是向量范數(長度函數)。

三角形由兩個變量ts參數化,使得二重積分A = INT(INT(1,dx),dy)給出總面積

% position r(s,t) = [x,y]
[x,y] = [ax,ay] + t*[bx-ax, by-zy] + t*s*[cx-bx,cy-by]

% gradient directions along s and t
(dr/dt) = [bx-ax,by-ay] + s*[cx-bx,cy-by]
(dr/ds) = t*[cx-bx,cy-by]

% Integration area element
dA = || (dr/ds)×(dr/dt) || = (2*A*t)*ds*dt
%
%   where A = 1/2*||(b-a)×(c-b)||

% Check that the integral returns the area
Area = INT( INT( 2*A*t,s=0..1), t=0..1) = 2*A*(1/2) = A

% Mass moment of inertia components

         /  /  /  | y^2+z^2  -x*y    -x*z   |
I = 2*m*|  |  | t*|  -x*y   x^2+z^2  -y*z   | dz ds dt
        /  /  /   |  -x*z    -y*z   x^2+y^2 |

% where [x,y] are defined from the parametrization

我想稍微糾正一下優秀的 John Alexiou 回答:

  1. 三角形 mmoi 算法期望相對於三角形質心(質心)定義角。 所以在計算 mmoi 之前從角中減去質心
  2. Shape mmoi 算法期望相對於形狀質心(組合質心)定義每個單個三角形的質心。 因此,在計算 mmoi 之前,從每個三角形質心中減去組合質心。

所以結果代碼看起來像這樣:

public static float CalculateMMOI(Triangle[] triangles, float thickness, float density)
{
    float[] mass = new float[triangles.Length];
    float[] mmoi = new float[triangles.Length];
    Vector2[] centroid = new Vector2[triangles.Length];
    
    float combinedMass = 0;
    float combinedMMOI = 0;
    Vector2 combinedCentroid = new Vector2(0, 0);
    
    for (var i = 0; i < triangles.Length; ++i) 
    {
        mass[i] = triangles[i].CalculateMass(thickness, density);
        mmoi[i] = triangles[i].CalculateMMOI(mass[i]);
        centroid[i] = triangles[i].CalculateCentroid();

        combinedMass += mass[i];
        combinedCentroid += mass[i] * centroid[i];
    }
    combinedCentroid /= combinedMass;


    for (var i = 0; i < triangles.Length; ++i) {
        combinedMMOI += mmoi[i] + mass[i] * (centroid[i] - combinedCentroid).LengthSquared();
    }

    return combinedMMOI;
}


public struct Triangle
{
    public Vector2 A, B, C;
    
    public float CalculateMass(float thickness, float density)
    {
        var area = CalculateArea();
        return area * thickness * density;
    }
    
    public float CalculateArea()
    {
        return 0.5f * Math.Abs(Vector2.Cross(A - B, A - C));
    }

    public float CalculateMMOI(float mass)
    {
        var centroid = CalculateCentroid()
        var a = A - centroid;
        var b = B - centroid;
        var c = C - centroid;
        
        var aa = Vector2.Dot(a, a);
        var bb = Vector2.Dot(b, b);
        var cc = Vector2.Dot(c, c);
        var ab = Vector2.Dot(a, b);
        var bc = Vector2.Dot(b, c);
        var ca = Vector2.Dot(c, a);
        return (aa + bb + cc + ab + bc + ca) * mass / 6f;
    }

    public Vector2 CalculateCentroid()
    {
        return (A + B + C) / 3f;
    }
}


public struct Vector2
{
    public float X, Y;
    
    public float LengthSquared()
    {
        return X * X + Y * Y;
    }
    
    public static float Dot(Vector2 a, Vector2 b)
    {
        return a.X * b.X + a.Y * b.Y;
    }

    public static float Cross(Vector2 a, Vector2 b)
    {
        return a.X * b.Y - a.Y * b.X;
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM