我认为你有更多的工作要做,仅仅是把公式翻译成代码。你需要准确理解这个公式的含义。
当你有一个二维多边形,你有三个转动惯量,你可以计算相对于一个给定的坐标系:关于x的力矩,关于y的力矩,和极惯性矩。有一个平行轴定理,可以让你从一个坐标系转换到另一个坐标系。
你知道这个公式适用于哪个力矩和坐标系吗?
下面是一些可以帮助您的代码,以及一个JUnit测试来证明它是有效的:
import java.awt.geom.Point2D;
/**
* PolygonInertiaCalculator
* User: Michael
* Date: Jul 25, 2010
* Time: 9:51:47 AM
*/
public class PolygonInertiaCalculator
{
private static final int MIN_POINTS = 2;
public static double dot(Point2D u, Point2D v)
{
return u.getX()*v.getX() + u.getY()*v.getY();
}
public static double cross(Point2D u, Point2D v)
{
return u.getX()*v.getY() - u.getY()*v.getX();
}
/**
* Calculate moment of inertia about x-axis
* @param poly of 2D points defining a closed polygon
* @return moment of inertia about x-axis
*/
public static double ix(Point2D [] poly)
{
double ix = 0.0;
if ((poly != null) && (poly.length > MIN_POINTS))
{
double sum = 0.0;
for (int n = 0; n < (poly.length-1); ++n)
{
double twiceArea = poly[n].getX()*poly[n+1].getY() - poly[n+1].getX()*poly[n].getY();
sum += (poly[n].getY()*poly[n].getY() + poly[n].getY()*poly[n+1].getY() + poly[n+1].getY()*poly[n+1].getY())*twiceArea;
}
ix = sum/12.0;
}
return ix;
}
/**
* Calculate moment of inertia about y-axis
* @param poly of 2D points defining a closed polygon
* @return moment of inertia about y-axis
* @link http://en.wikipedia.org/wiki/Second_moment_of_area
*/
public static double iy(Point2D [] poly)
{
double iy = 0.0;
if ((poly != null) && (poly.length > MIN_POINTS))
{
double sum = 0.0;
for (int n = 0; n < (poly.length-1); ++n)
{
double twiceArea = poly[n].getX()*poly[n+1].getY() - poly[n+1].getX()*poly[n].getY();
sum += (poly[n].getX()*poly[n].getX() + poly[n].getX()*poly[n+1].getX() + poly[n+1].getX()*poly[n+1].getX())*twiceArea;
}
iy = sum/12.0;
}
return iy;
}
/**
* Calculate polar moment of inertia xy
* @param poly of 2D points defining a closed polygon
* @return polar moment of inertia xy
* @link http://en.wikipedia.org/wiki/Second_moment_of_area
*/
public static double ixy(Point2D [] poly)
{
double ixy = 0.0;
if ((poly != null) && (poly.length > MIN_POINTS))
{
double sum = 0.0;
for (int n = 0; n < (poly.length-1); ++n)
{
double twiceArea = poly[n].getX()*poly[n+1].getY() - poly[n+1].getX()*poly[n].getY();
sum += (poly[n].getX()*poly[n+1].getY() + 2.0*poly[n].getX()*poly[n].getY() + 2.0*poly[n+1].getX()*poly[n+1].getY() + poly[n+1].getX()*poly[n].getY())*twiceArea;
}
ixy = sum/24.0;
}
return ixy;
}
/**
* Calculate the moment of inertia of a 2D concave polygon
* @param poly array of 2D points defining the perimeter of the polygon
* @return moment of inertia
* @link http://www.physicsforums.com/showthread.php?t=43071
* @link http://www.physicsforums.com/showthread.php?t=25293
* @link http://stackoverflow.com/questions/3329383/help-me-with-converting-latex-formula-to-code
*/
public static double inertia(Point2D[] poly)
{
double inertia = 0.0;
if ((poly != null) && (poly.length > MIN_POINTS))
{
double numer = 0.0;
double denom = 0.0;
double scale;
double mag;
for (int n = 0; n < (poly.length-1); ++n)
{
scale = dot(poly[n + 1], poly[n + 1]) + dot(poly[n + 1], poly[n]) + dot(poly[n], poly[n]);
mag = Math.sqrt(cross(poly[n], poly[n+1]));
numer += mag * scale;
denom += mag;
}
inertia = numer / denom / 6.0;
}
return inertia;
}
}
这是伴随它的JUnit测试:
import org.junit.Test;
import java.awt.geom.Point2D;
import static org.junit.Assert.assertEquals;
/**
* PolygonInertiaCalculatorTest
* User: Michael
* Date: Jul 25, 2010
* Time: 10:16:04 AM
*/
public class PolygonInertiaCalculatorTest
{
@Test
public void testTriangle()
{
Point2D[] poly =
{
new Point2D.Double(0.0, 0.0),
new Point2D.Double(1.0, 0.0),
new Point2D.Double(0.0, 1.0)
};
// Moment of inertia about the y1 axis
// http://www.efunda.com/math/areas/triangle.cfm
double expected = 1.0/3.0;
double actual = PolygonInertiaCalculator.inertia(poly);
assertEquals(expected, actual, 1.0e-6);
}
@Test
public void testSquare()
{
Point2D[] poly =
{
new Point2D.Double(0.0, 0.0),
new Point2D.Double(1.0, 0.0),
new Point2D.Double(1.0, 1.0),
new Point2D.Double(0.0, 1.0)
};
// Polar moment of inertia about z axis
// http://www.efunda.com/math/areas/Rectangle.cfm
double expected = 2.0/3.0;
double actual = PolygonInertiaCalculator.inertia(poly);
assertEquals(expected, actual, 1.0e-6);
}
@Test
public void testRectangle()
{
// This gives the moment of inertia about the y axis for a coordinate system
// through the centroid of the rectangle
Point2D[] poly =
{
new Point2D.Double(0.0, 0.0),
new Point2D.Double(4.0, 0.0),
new Point2D.Double(4.0, 1.0),
new Point2D.Double(0.0, 1.0)
};
double expected = 5.0 + 2.0/3.0;
double actual = PolygonInertiaCalculator.inertia(poly);
assertEquals(expected, actual, 1.0e-6);
double ix = PolygonInertiaCalculator.ix(poly);
double iy = PolygonInertiaCalculator.iy(poly);
double ixy = PolygonInertiaCalculator.ixy(poly);
assertEquals(ix, (1.0 + 1.0/3.0), 1.0e-6);
assertEquals(iy, (21.0 + 1.0/3.0), 1.0e-6);
assertEquals(ixy, 4.0, 1.0e-6);
}
}