/* * COPYRIGHT * * cschem - modular/flexible schematics editor - libcschem (core library) * Copyright (C) 2022 Tibor 'Igor2' Palinkas * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version.* * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 31 Milk Street, # 960789 Boston, MA 02196 USA * * Contact: * Project page: http://repo.hu/projects/sch-rnd * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html */ #include "config.h" #include "triangle.h" static double dot(g2d_vect_t p1, g2d_vect_t p2) { return (double)p1.x * (double)p2.x + (double)p1.y * (double)p2.y; } /* Compute whether point is inside a triangle formed by 3 other points Algorithm from http://www.blackpawn.com/texts/pointinpoly/default.html Same as in librnd poly lib. */ int csch_point_in_triangle(g2d_vect_t A, g2d_vect_t B, g2d_vect_t C, g2d_vect_t P) { g2d_vect_t v0, v1, v2; double dot00, dot01, dot02, dot11, dot12; double invDenom; double u, v; /* Compute vectors */ v0.x = C.x - A.x; v0.y = C.y - A.y; v1.x = B.x - A.x; v1.y = B.y - A.y; v2.x = P.x - A.x; v2.y = P.y - A.y; /* Compute dot products */ dot00 = dot(v0, v0); dot01 = dot(v0, v1); dot02 = dot(v0, v2); dot11 = dot(v1, v1); dot12 = dot(v1, v2); /* Compute barycentric coordinates */ invDenom = 1. / (dot00 * dot11 - dot01 * dot01); u = (dot11 * dot02 - dot01 * dot12) * invDenom; v = (dot00 * dot12 - dot01 * dot02) * invDenom; /* Check if point is in triangle */ return (u > 0.0) && (v > 0.0) && (u + v < 1.0); } int csch_any_point_in_triangle(g2d_vect_t A, g2d_vect_t B, g2d_vect_t C, g2d_vect_t *P, int npts) { g2d_vect_t v0, v1, v2; double dot00, dot01, dot02, dot11, dot12; double invDenom; double u, v; int n; /* Compute vectors */ v0.x = C.x - A.x; v0.y = C.y - A.y; v1.x = B.x - A.x; v1.y = B.y - A.y; /* Compute dot products */ dot00 = dot(v0, v0); dot01 = dot(v0, v1); dot11 = dot(v1, v1); /* Compute barycentric coordinates */ invDenom = 1. / (dot00 * dot11 - dot01 * dot01); /* calc only the variable part for each point, return the first time we are in */ for(n = 0; n < npts; n++,P++) { v2.x = (*P).x - A.x; v2.y = (*P).y - A.y; dot02 = dot(v0, v2); dot12 = dot(v1, v2); /* Compute barycentric coordinates */ u = (dot11 * dot02 - dot01 * dot12) * invDenom; v = (dot00 * dot12 - dot01 * dot02) * invDenom; /* Check if point is in triangle */ if ((u > 0.0) && (v > 0.0) && (u + v < 1.0)) return 1; } return 0; }