Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Bug when implement "check point inside triangle" algorithm

I'm following the algorithm 1 in this article to check if a point is inside a triangle. This is my code:

//========================================================================================================================//
// Methods
//========================================================================================================================//

private float getPerpDotProduct(final PointF p1, final PointF p2) {
    return p1.x * p2.y - p1.y * p2.x;
}

private boolean isInside(final PointF pPoint) { 
    final float c1 = this.getPerpDotProduct(this.mA, pPoint);
    final float c2 = this.getPerpDotProduct(this.mB, pPoint);
    final float c3 = this.getPerpDotProduct(this.mC, pPoint);

    return ((c1 >= 0 && c2 >= 0 & c3 >= 0) || (c1 <= 0 && c2 <= 0 && c3 <= 0));
}

And this is my test: enter image description here

Cyan zone: The real triangle I give.

Pink zone: "Inside" the triangle

Blue Zone: "Outside" the triangle

EDIT:

This is my new code to calculate by vectors:

private PointF getVector(final PointF pPoint1, final PointF pPoint2) {
    return new PointF(pPoint2.x - pPoint1.x, pPoint2.y - pPoint1.y);
}

private float getPerpDotProduct(final PointF p1, final PointF p2) {
    return p1.x * p2.y - p1.y * p2.x;
}

private boolean isInside(final PointF pPoint) { 
    final float c1 = this.getPerpDotProduct(getVector(this.mA, this.mB), getVector(this.mA, pPoint));
    final float c2 = this.getPerpDotProduct(getVector(this.mB, this.mC), getVector(this.mB, pPoint));
    final float c3 = this.getPerpDotProduct(getVector(this.mC, this.mA), getVector(this.mC, pPoint));

    return ((c1 > 0 && c2 > 0 & c3 > 0) || (c1 < 0 && c2 < 0 && c3 < 0));
}

Please clarify my code. Thank you.

like image 522
Luke Vo Avatar asked Jul 08 '12 10:07

Luke Vo


1 Answers

There is a "bug" in the article's description of what needs to be done:

Calculate the perpDotProduct/crossproduct of all three points V1, V2, V3 with the testpoint P

should be "Calculate the perpDotProduct/crossproduct of all three vectors with vectors to the testpoint P".

As explained in the article, the algorithm returns true if all three points are visible at the same "angular direction" from the origin (the upper-left corner of your picture). Your picture shows it precisely, too: vectors (0, p) for all pink points need to turn clockwise to reach the triangle if they are above the blue zone; if they are below the blue zone, the vectors would need to move counterclockwise.

To fix the algorithm, you need to compute cross products of vectors {(V1-V2), (V1-P)}, {(V2-V3), (V2-P)}, and {(V3-V1), (V3-P)}. Take a look at this article for pseudocode.

like image 53
Sergey Kalinichenko Avatar answered Oct 24 '22 19:10

Sergey Kalinichenko