Created
May 17, 2020 22:18
-
-
Save dam2k/960ecac776c506a9f3474d4e467969b5 to your computer and use it in GitHub Desktop.
Is a point inside a triangle? Ported in C from http://totologic.blogspot.com/2014/01/accurate-point-in-triangle-test.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <math.h> | |
// ported in C from http://totologic.blogspot.com/2014/01/accurate-point-in-triangle-test.html?m=1 | |
// really really really thank you! | |
// compile with -lm (math library) | |
#define EPSILON 0.00001 | |
const static float epsilon = EPSILON; | |
const static float epsilon2 = EPSILON*EPSILON; | |
float side(float x1, float y1, float x2, float y2, float x, float y) { | |
return (y2-y1)*(x-x1)+(-x2+x1)*(y-y1); | |
} | |
int naivePointInTriangle(float x1, float y1, float x2, float y2, float x3, float y3, float x, float y) { | |
if((side(x1, y1, x2, y2, x, y) >= 0) && (side(x2, y2, x3, y3, x, y) >= 0) && (side(x3, y3, x1, y1, x, y) >= 0)) return 1; | |
return 0; | |
} | |
int pointInTriangleBoundingBox(float x1, float y1, float x2, float y2, float x3, float y3, float x, float y) { | |
float xMin, xMax, yMin, yMax; | |
xMin = fminf(x1, fminf(x2, x3)) - epsilon; | |
xMax = fmaxf(x1, fmaxf(x2, x3)) + epsilon; | |
yMin = fminf(y1, fminf(y2, y3)) - epsilon; | |
yMax = fmaxf(y1, fmaxf(y2, y3)) + epsilon; | |
if(x < xMin || xMax < x || y < yMin || yMax < y ) return 0; | |
return 1; | |
} | |
float distanceSquarePointToSegment(float x1, float y1, float x2, float y2, float x, float y) { | |
float p1_p2_squareLength, dotProduct, p_p1_squareLength; | |
p1_p2_squareLength = (x2 - x1) * (x2 - x1) + (y2 - y1)*(y2 - y1); | |
dotProduct = ((x - x1)*(x2 - x1) + (y - y1)*(y2 - y1)) / p1_p2_squareLength; | |
if(dotProduct < 0) { | |
return (x - x1) * (x - x1) + (y - y1) * (y - y1); | |
} | |
if (dotProduct <= 1) { | |
p_p1_squareLength = (x1 - x) * (x1 - x) + (y1 - y) * (y1 - y); | |
return p_p1_squareLength - dotProduct * dotProduct * p1_p2_squareLength; | |
} | |
return (x - x2) * (x - x2) + (y - y2) * (y - y2); | |
} | |
int accuratePointInTriangle(float x1, float y1, float x2, float y2, float x3, float y3, float x, float y) { | |
if(!pointInTriangleBoundingBox(x1, y1, x2, y2, x3, y3, x, y)) return 0; | |
if(naivePointInTriangle(x1, y1, x2, y2, x3, y3, x, y)) return 1; | |
if(distanceSquarePointToSegment(x1, y1, x2, y2, x, y) <= epsilon2) return 1; | |
if(distanceSquarePointToSegment(x2, y2, x3, y3, x, y) <= epsilon2) return 1; | |
if(distanceSquarePointToSegment(x3, y3, x1, y1, x, y) <= epsilon2) return 1; | |
return 0; | |
} | |
int main() { | |
float x1, y1, x2, y2, x3, y3, x, y; | |
// testo un triangolo rettangolo | |
x1=100; y1=100; x2=100; y2=200; x3=200; y3=100; | |
x=150; y=150; | |
//x=150; y=150.00001; | |
printf("XY point is into the triangle with vertex x1.y1, x2.y2, x3.y3? Response: %s\n", accuratePointInTriangle(x1,y1,x2,y2,x3,y3,x,y) ? "yes" : "no"); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment