2015-10-27 196 views
0

我不知道如何解決這個問題。我已經創建了3個三角形:計算幾個三角形的重心

enter image description here

我所有的個體三角形的XY座標。如果按照圖示將它們放在一起,我想計算重心,但是隻使用填充的部分,並且無論它們在哪裏交叉,都不會將質量計算兩次。我怎麼能在java中這樣做呢?

我可以以某種方式將這些對象合併爲一個對象,然後對每個區域進行數值計算並找到中間地帶,還是有更好的方法?

+2

你需要首先解決你的數學/幾何的問題 - 那麼你寫的代碼...... – assylias

+0

能否請您發佈自己編寫的代碼和公式試圖解決這個問題到目前爲止? – rze

+1

https://en.wikipedia.org/wiki/Centroid可能會幫助你。 –

回答

0

將您的形狀轉換爲單個多邊形(有兩個交點要計算)。

然後使用centroid formula作爲多邊形。

另一種選擇是填充相同顏色的所有三角形(通過多邊形或種子填充),然後種子填充合成區域,同時積累X和Y座標。

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; 
    } 

}