点在三角形2d内

时间:2015-04-28 19:46:25

标签: java double point

所以我创建一个方法来检查点“ponto”是否在点A,B,C作为顶点给出的三角形内。

到目前为止,我有这个:

final double PRECISION = 0.1;
public boolean dentroDoTriangulo (Point A, Point B, Point C, Point ponto){

    //total
    double ABC = Math.abs ((A.x*(B.y-C.y)+B.x*(C.y-A.y)+ C.x*(A.y-B.y))/2);

    //parcial
    double ABP = Math.abs((A.x*(B.y-ponto.y)+B.x*(ponto.y-A.y)+ponto.x*(A.y-B.y))/2);
    double APC = Math.abs (A.x*(ponto.y-C.y)+ponto.x*(C.y-A.y)+C.x*(A.y-ponto.y))/2;
    double PBC = Math.abs (ponto.x*(B.y-C.y)+B.x*(C.y-ponto.y)+C.x*(ponto.y-B.y))/2;
    double parciais = ABP + APC + PBC ;
    return Math.abs(ABC - parciais) <= PRECISION;
}

我已经尝试过这样做了:

ABP +APC +PBC == ABC

也没有,有人可以帮助我理解我在这里做错了什么吗?

3 个答案:

答案 0 :(得分:0)

编辑:您的代码似乎运行正常。这是一个Point类示例,以防你崩溃的地方。

    public class Point {
      float x;
      float y;
      Point() {
        x = 0;
        y = 0;
      }
      Point(float x, float y) {
        this.x = x;
        this.y = y;
      }
    }

以防万一,我提出另一个解决方案:

查看this algorithm for determining if the point is inside a triangle

我看不到您的Point课程,所以我不知道那里是否有错误。我假设x&amp; y坐标是两个浮点数。我们假设没关系。

你能更好地解释一下你的算法吗?我看起来你正在拍摄三个子三角形区域并将它们相加以与原始三角形进行比较(具有PRECISION容差)。如果需要,尝试三次超链接中提到的“SameSide”功能 - 这需要两个交叉产品,然后是交叉产品结果的点积,以确定一个点是否在一条线的“正确的一侧”之间任意两个顶点(有三条这样的线)。

算法的代码段:

boolean SameSide(p1, p2, a, b) {
  int[] cp1 = CrossProduct(b - a, p1 - a);
  int[] cp2 = CrossProduct(b - a, p2 - a);
  if (DotProduct(cp1, cp2) >= 0) {
    return true;
  }
  return false;
}

boolean PointInTriangle(p, a, b, c) {
  if (SameSide(p, a, b, c) && SameSide(p, b, a, c) &&
    SameSide(p, c, a, b) {
      return true;
    }
  return false;
}

其中a,b,c是顶点,p是点。我建议使用int []来保存向量。您需要编写辅助函数来计算向量操作。

答案 1 :(得分:0)

我无法遵循您的算法,但您可以从该点向两个方向发送水平(或任何方向)光线。如果它在两个方向上都击中三角形,则该点将位于三角形内。您需要注意光线撞击顶点的特殊条件。这将被视为在一侧击中两条线。但是只要光线在两个方向上都会碰到三角形,那么这个点就会在里面。

答案 2 :(得分:0)

所以我将你的代码用于方法dentroDoTriangulo并且卡在一个类中。我使用了上面给出的Point类。然后我使用下面给出的快速和脏代码调用您的方法。它似乎没有任何问题。就像上面提到的@TNT一样,测试用例会有所帮助。

public class Caller {
	public static void main(String[] args) {
		
		Triangle myTraingle = new Triangle();
		boolean isInside = myTraingle.dentroDoTriangulo(new Point(1,0), new Point(3,0), new Point(2,2), new Point(2,1));
		if (isInside) {
			System.out.println("Point is inside");
		} else {
			System.out.println("Point is outside");
		}
	}
}