我无法解决如何解决这个问题。我创建了3个三角形:
我有所有单个三角形的XY坐标。我想计算重心,如果它们如图所示放在一起,但只使用填充的部分,并且无论它们在哪里交叉,你都不计算质量两次。我怎样才能在java中这样做呢?
我能以某种方式将这些组合成某种物体中的1种,然后对每个区域进行数值计算并找到中间地带,还是有更好的方法?
答案 0 :(得分:0)
将形状转换为单个多边形(要计算两个交点)。
然后使用centroid formula作为多边形。
另一种选择是用相同的颜色填充所有三角形(通过多边形或种子填充),然后种子填充结果区域,同时在运行中累积X和Y坐标。
答案 1 :(得分:0)
首先,您必须确定实际想要计算重心的内容。显然,当三角形相交(并且重叠区域不应计算两次)时,您不是计算三角形的重心,而是计算它们交叉区域的重心。
幸运的是,可以使用Area
类轻松计算这样的交叉区域。根据一条评论,您已经有Area
描述这个区域。
因此,计算此区域的重心的一个选项是计算Area
的所有边界点的平均值。
请注意,这只适用于Area
没有漏洞的情况。
否则,您必须计算Area
的面积。
这是一个可能的实现:
import java.awt.Shape;
import java.awt.geom.Area;
import java.awt.geom.Path2D;
import java.awt.geom.PathIterator;
import java.awt.geom.Point2D;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
public class CenterOfGravity
{
public static void main(String[] args)
{
Path2D p0 = new Path2D.Double();
p0.moveTo(100, 100);
p0.lineTo(200, 100);
p0.lineTo(150, 50);
p0.closePath();
Path2D p1 = new Path2D.Double();
p1.moveTo(150, 100);
p1.lineTo(250, 100);
p1.lineTo(200, 50);
p1.closePath();
Area a = new Area();
a.add(new Area(p0));
a.intersect(new Area(p1));
Point2D cog = computeCenterOfGravity(a);
System.out.println(cog);
}
private static Point2D computeCenterOfGravity(Shape shape)
{
return computeAverage(computePoints(shape, 1.0));
}
private static Point2D computeAverage(
Collection<? extends Point2D> points)
{
double x = 0;
double y = 0;
for (Point2D point : points)
{
x += point.getX();
y += point.getY();
}
if (!points.isEmpty())
{
x /= points.size();
y /= points.size();
}
return new Point2D.Double(x, y);
}
public static List<Point2D> computePoints(
Shape shape, double flatness)
{
List<Point2D> result = new ArrayList<Point2D>();
PathIterator pi = shape.getPathIterator(null, flatness);
double[] coords = new double[6];
while (!pi.isDone())
{
int segment = pi.currentSegment(coords);
switch (segment)
{
case PathIterator.SEG_MOVETO:
case PathIterator.SEG_LINETO:
result.add(new Point2D.Double(coords[0], coords[1]));
break;
case PathIterator.SEG_CLOSE:
break;
case PathIterator.SEG_QUADTO:
case PathIterator.SEG_CUBICTO:
default:
throw new AssertionError(
"Invalid segment in flattened path!");
}
pi.next();
}
return result;
}
}