【问题标题】:How to check if triangle2D is inside another one or overlapping it?如何检查 triangle2D 是否在另一个内部或重叠?
【发布时间】:2018-05-02 20:06:00
【问题描述】:

我正在尝试检查 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 仅用于point,但如果三角形包含其他三角形或重叠它,我不知道该怎么做。

【问题讨论】:

标签: java algorithm math geometry


【解决方案1】:

您可以在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);

返回位置 = x2 && x2 >= 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】:

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

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

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

【讨论】:

    【解决方案3】:

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

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

    【讨论】:

      猜你喜欢
      • 2015-04-09
      • 1970-01-01
      • 2021-05-23
      • 2016-10-05
      • 1970-01-01
      • 1970-01-01
      • 2019-11-06
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多