如何检查triangle2D是否在另一个内部或重叠?

时间:2017-11-19 14:19:04

标签: java algorithm math geometry

我正在尝试检查triangle2D是包含另一个三角形还是重叠它。

我可以用圆圈做到这一点,例如:

/** Return true if the specified point
 *   (x, y) is inside this circle     */
public boolean contains(double x, double y) {
    return Math.sqrt(Math.pow(x - this.x, 2) +
            Math.pow(y - this.y, 2))
            < radius;
}

/** Return true if the specified
 *   circle is inside this circle */
public boolean contains(Circle2D circle) {
    return Math.sqrt(Math.pow(circle.getX() - x, 2) +
            Math.pow(circle.getY() - y, 2))
            <= Math.abs(radius - circle.getRadius());
}

/** Return true if the specified
 *   circle overlaps with this circle */
public boolean overlaps(Circle2D circle) {
    return Math.sqrt(Math.pow(circle.getX() - x, 2) +
            Math.pow(circle.getY() - y, 2))
            <= radius + circle.getRadius();
}

但我不知道如何用三角形做到这一点。

我发现只有this question,但如果三角形包含其他三角形或重叠三角形,我不知道如何做到这一点。

3 个答案:

答案 0 :(得分:0)

对于包含的情况,您可以检查三角形的所有顶点。如果所有这些都存在于另一个内部,则其中一个包含另一个。

对于重叠的情况,您应该考虑这两个三角形的任何边缘之间是否存在任何交叉。如果没有,并且没有发生包含案例,则将它们分开。对于在平面上交叉两条边(作为两个线段)的情况,您可以使用this post

答案 1 :(得分:0)

您可以在java.awt.geom.Line2D内使用Line2D#containsLine2D#linesIntersect方法。

修改

在数学中思考:

  

要检测点是否在三角形内部,请绘制三条虚线,如果该点位于三角形内,则每条虚线应仅与一侧相交一次。如果虚线与边相交两次,那么该点必须在三角形之外。

所以我们可以在下面的其他问题(你提到过)中使用这种方式:

    public boolean contains(MyPoint p) {
//        double area1 = calcArea(p, p1, p2);
//        double area2 = calcArea(p, p2, p3);
//        double area3 = calcArea(p, p3, p1);
//        double area = Math.round((area1 + area2 + area3) * 100) / 100;
//        double triangleArea =  Math.round(getArea() * 100) / 100;
//        return (triangleArea == area)

    }

但这不是有效的方式,所以我们将按照以下方式实施,以便重用它与其他情况。

我们应该有三种方法用于检查 max x, y,一种用于检查 min x, y,另一种用于检查 lineSegment

lineSegment 如下所示:

  

双位=(x1 - x0)*(y2 - y0) - (x2 - x0)*(y1 - y0);

     

返回位置&lt; = 0.0000000001&amp;&amp; ((x0&lt; = x2&amp;&amp; x2&lt; = x1)||(x0&gt; = x2&amp;&amp; x2&gt; = x1));

  /**
 * returns true if the specified point is inside this triangle
 **/
public boolean contains(MyPoint p) {

    return contains(p.getX(), p.getY());
}

public boolean contains(double x, double y) {

    // Get max X & Y
    double maxX = getMax(p1.getX(), p2.getY(), p3.getX());
    double maxY = getMax(p1.getY(), p2.getY(), p3.getX());

    // Get min X & Y
    double minX = getMin(p1.getX(), p2.getX(), p3.getX());
    double minY = getMin(p1.getY(), p2.getY(), p3.getY());

    // Outside the bounding rectangle of the triangle
    if (x < minX || x > maxX || y < minY || y > maxY) return false;

    // Check if point is the border of the triangle
    MyPoint p = new MyPoint(x, y);
    boolean side1 = p.onTheLineSegment(p1, p2); //assume A to B
    boolean side2 = p.onTheLineSegment(p1, p3); //assume B to C
    boolean side3 = p.onTheLineSegment(p2, p3); //assume C to A
    return side1 || side2 || side3; //return true if any point of these vertices inside triangle.

}

因此,要检查三角形是否包含其他三角形,我们的方法将如下所示:

public boolean contains(Triangle t) {

    return contains(t.p1) && contains(t.p2) && contains(t.p3); //All three points is inside the triangle
}

或者就像我上面提到的那样使用Line2D类:

Line2D line2D = new Line2D.Double(p1.getX(), p1.getY(), p2.getX(), p2.getY());
return line2D.contains(....); //check if contain triangle or point

答案 2 :(得分:0)

使用LeftOf谓词,当三角形ABC的代数区域为正(使用适当的符号约定)时,该谓词为真,告诉您C位于AB行的左侧。

然后检查第一个三角形的所有三个顶点是否位于第二个三角形的某一侧的左侧。如果没有,请在交换两个三角形后重复。

最后,如果是,三角形不会干扰。

enter image description here