/* * Test if a point is inside a triangle. * Julian Saknussemm * * Given Three points of a triangle, and another arbitrary point this program determines if * that point lies inside the triangle. * * This is determined by satisfying the following rule: * A point P(x,y) is inside triangle A(x0,y0), B(x1,y1), C(x2,y2) * iff * P is on the same side of the line AB as C * P is on the same side of the line BC as A * and * P is on the same side of the line AC as B * * A special case exits for a vertical line (inf gradient) when testing the side of the line */ #include <stdio.h> #include <stdlib.h> #include <assert.h> #define ON 0 #define UNDER -1 #define OVER 1 // function prototypes void testRight (void); int testLine (double px, double py, double m, double b); int testTwoPoints (double px, double py, double m, double b, double lx, double ly); int verticalTest (double x0, double y0, double x1, double y1, double x2, double y2, double px, double py); int main(int argc, char* argv[]) { void testRight (void); double x0; double y0; double x1; double y1; double x2; double y2; double px; double py; // All scanf values summed together into one int numOfInputs = 0; // get input and printf("Triangle Vertex A (x,y): \n"); numOfInputs += scanf("%lf,%lf", &x0, &y0); printf("Triangle Vertex B (x,y): \n"); numOfInputs += scanf("%lf,%lf", &x1, &y1); printf("Triangle Vertex C (x,y): \n"); numOfInputs += scanf("%lf,%lf", &x2, &y2); printf("Test Point (x,y): \n"); numOfInputs += scanf("%lf,%lf", &px, &py); // print error and abort if the required number of inputs is not given if (numOfInputs != 8) { printf("You're stupid and didn't put in the right inputs!\n"); printf("Please place a comma between arguments.\n"); } assert (numOfInputs == 8); // print answer printf("Point (%.2lf,%.2lf) is ", px,py); if (verticalTest(x0, y0, x1, y1, x2, y2, px, py)) { printf("inside the triangle\n"); } else { printf("outside the triangle\n"); } return EXIT_SUCCESS; } void testRight (void) { assert (verticalTest(0, 0, 10, 0, 0, 10, 20, 20) == 0); assert (verticalTest(0, 0, 10, 0, 0, 10, 0, 0) == 1); assert (verticalTest(0, 0, 10, 0, 0, 10, 1, 1) == 1); assert (verticalTest(0, 0, 10, 0, 0, 10, -2, -42) == 0); assert (verticalTest(0, 0, 10, 0, 0, 10, 0, 5) == 1); } // Tests if point is under on or over a line int testLine (double px, double py, double m, double b) { int position; if( py < m * px + b ) { position = UNDER; } else if ( py == m * px + b ) { position = ON; } else { position = OVER; } return position; } // Test if two points lie on the same side of a line int testTwoPoints (double px, double py, double m, double b, double lx, double ly) { return (testLine(px, py, m, b) == testLine(lx, ly, m, b)); } int verticalTest (double x0, double y0, double x1, double y1, double x2, double y2, double px, double py) { int line1; int line2; int line3; // line eqns double m01 = (y1-y0)/(x1-x0); double b01 = m01 * - x1 + y1; double m02 = (y2-y0)/(x2-x0); double b02 = m02 * -x2 + y2; double m12 = (y2-y1)/(x2-x1); double b12 = m12 * -x2 + y2; // vertical line checks if (x1 == x0) { line1 = ((px <= x0) == (x2 <= x0)); } else { line1 = testTwoPoints (px, py, m01, b01, x2, y2); } if (x1 == x2) { line2 = ((px <= x2) == (x0 <= x2)); } else { line2 = testTwoPoints (px, py, m12, b12, x0, y0); } if (x2 == x0) { line3 = ((px <= x0 ) == (x1 <= x0)); } else { line3 = testTwoPoints(px, py, m02, b02, x1, y1); } return (line1 && line2 && line3); }
Download file: confusing.c
(3.9 KB)