gpt4 book ai didi

game-physics - 给定任意凸二维多边形计算惯性矩

转载 作者:行者123 更新时间:2023-12-04 04:38:39 25 4
gpt4 key购买 nike

我一直在研究这个问题几个小时,但由于某种原因我一直无法找到解决方案。

给定一个凸多边形,它被定义为围绕多边形质心按顺时针顺序排列的点数组,如何计算多边形的转动惯量?

我已经能够找到各种形状(例如矩形或圆形)的方程,但不能找到任意凸多边形。

例如,质量为 m、高度为 h、宽度为 w 的矩形绕其质心旋转的惯性矩计算如下:

Moment of Inertia for a Rectangle

我正在寻找类似的公式/算法,但要找一个凸多边形。

最佳答案

有一种使用向量代数分析 2D 多边形的方法,在我看来,它比依赖三角学的方法更容易以编程方式实现。

每个Vector数量有两个组成部分 .x.y以及方法向量代数向量,包括点积和叉积

add(a,b) = [a.x+b.x, a.y+b.y]    // a+b = add(a,b)
scale(f,x) = [f*a.x, f*a.y] // 2*a = scale(2,a), a/3 = scale(1/3,a)
dot(a,b) = a.x*b.x + a.y*b.y // a·b = dot(a,b)
cross(a,b) = a.x*b.y - a.y*b.x // a×b = cross(a,b)

下面的方法遍历多边形的所有边,并将面积、中心和关于由边和原点定义的每个三角形的坐标原点的质量惯性矩相加。最后的总和负责添加或减去靠近或远离原点和 的区域。产生准确的结果 .

最后,质量力矩从原点转移到质心。
polygon(Vector[] points, double depth, double density)
{
// Accumulate the following values
double area = 0.0;
double mass = 0.0;
Vector center = [0.0, 0.0];
double mmoi = 0.0;

// Take each vertex pair starting from the last-first vertex
// in order to consider all sides.
int count = points.Length;
int prev = count - 1;
for(int index=0; index<count; index++)
{
Vector a = points[prev];
Vector b = points[index];

double area_step = TriangleArea(a,b);
double mass_step = density * area_step * depth;
Vector center_step = TriangleCenter(a,b);
double mmoi_step = TriangleMmoi(a,b, mass_step);

area += area_step;
center = (mass*center + mass_step*center_step)/(mass+mass_step);
mass += mass_step;
mmoi += mmoi_step;

prev = index;
}

// Transfer mass moment of inertia from the origin to the center of mass
mmoi -= mass*dot(center,center);

// use area, mass, center and mmoi
}

double TriangleArea(Vector a, Vector b)
{
return cross(a,b)/2;
}
double TriangleCenter(Vector a, Vector b)
{
return (a+b)/3;
{
double TriangleMmoi(Vector a, Vector b, double triangleMass)
{
return triangleMass/6*(dot(a,a)+dot(b.b)+dot(a.b));
}

以上是类似的流程 as outlined in this answer .更多细节包含在链接的答案中。

下面是一个 c#上面的实现,但指定质量,而不是密度和厚度。
public static RigidBody2 FromShape(double mass, params Vector2[] polygon)
{
double area = 0;
Vector2 center = Vector2.Zero;
double mmoi = 0;

int prev = polygon.Length-1;
for (int index = 0; index < polygon.Length; index++)
{
var a = polygon[prev];
var b = polygon[index];

var area_step = Vector2.Cross(a, b)/2;
var center_step = (a+b)/3;
var mmoi_step = area_step*(Vector2.Dot(a, a)+Vector2.Dot(b, b)+Vector2.Dot(a, b))/6;

center = (center*area + center_step * area_step)/(area + area_step);
area += area_step;
mmoi += mmoi_step;

prev = index;
}

double density = mass/area;
mmoi *= density;
mmoi -= mass * Vector2.Dot(center, center);

return new RigidBody2(mass, mmoi, center);
}

在测试中我使用了以下形状

shape

以及 center = [1.0, 0.75] 的结果和 mmoi = 787.5与在 CAD 包中完成的分析相匹配

CAD

这是检查 CAD 数据的单元测试:
[TestMethod, TestCategory("Linear Algebra, Planar")]
public void Geom_PlanarPolygonMass()
{
Vector2[] points = new Vector2[] {
Vector2.Cartesian(0.75, 0),
Vector2.Cartesian(2, 0),
Vector2.Cartesian(2, 0.5),
Vector2.Cartesian(1.25, 0.5),
Vector2.Cartesian(1.25, 1.5),
Vector2.Cartesian(0, 1.5),
Vector2.Cartesian(0, 1.0),
Vector2.Cartesian(0.75, 1),
};

var rg = RigidBody2.FromShape(1500, points);

Assert.AreEqual(1500, rg.Mass);
CollectionAssert.AreEqual(Vector2.Cartesian(1.0, 0.75), rg.LocalCg, AbsComparer(TinyNumber));
Assert.AreEqual(687.5, rg.LocalMmoi, DoubleEx.TinyNumber);
}

关于game-physics - 给定任意凸二维多边形计算惯性矩,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31106438/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com