MimmoCGUtils.cpp
1 /*---------------------------------------------------------------------------*\
2  *
3  * mimmo
4  *
5  * Copyright (C) 2015-2021 OPTIMAD engineering Srl
6  *
7  * -------------------------------------------------------------------------
8  * License
9  * This file is part of mimmo.
10  *
11  * mimmo is free software: you can redistribute it and/or modify it
12  * under the terms of the GNU Lesser General Public License v3 (LGPL)
13  * as published by the Free Software Foundation.
14  *
15  * mimmo is distributed in the hope that it will be useful, but WITHOUT
16  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
17  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
18  * License for more details.
19  *
20  * You should have received a copy of the GNU Lesser General Public License
21  * along with mimmo. If not, see <http://www.gnu.org/licenses/>.
22  *
23 \*---------------------------------------------------------------------------*/
24 
25 #include "MimmoCGUtils.hpp"
26 #include <CG.hpp>
27 #include <bitpit_operators.hpp>
28 
29 namespace mimmo{
30 
31 namespace mimmoCGUtils{
32 
41 double distancePointPolygon(const darray3E & p,const dvecarr3E & vertCoords){
42 
43  //calculate barycenter
44  darray3E barycenter = {{0.0,0.0,0.0}};
45  for(const auto & vv : vertCoords){
46  barycenter += vv;
47  }
48  barycenter /= double(vertCoords.size());
49 
50  //split it in subtriangles - fixed barycenter, run 2-by-2 along vertCoords to get the other two vertices
51  double distance(std::numeric_limits<double>::max());
52  std::size_t sizeV = vertCoords.size();
53  for(std::size_t i=0; i<sizeV-1; ++i){
54  distance = std::min(distance, bitpit::CGElem::distancePointTriangle(p, barycenter, vertCoords[i], vertCoords[i+1]));
55  }
56  return distance;
57 }
58 
59 
67 bool isPointInsideSegment(const darray3E & p, const darray3E & V0,const darray3E & V1, double tol ){
68  darray3E Pv = p - V0;
69  darray3E segment = V1 - V0;
70  double normSegment = norm2(segment);
71  if(normSegment > std::numeric_limits<double>::min()) segment /= normSegment;
72  double V = dotProduct(Pv, segment);
73  if(norm2(Pv - V*segment)> tol) return false;
74  return ( V >= (0.0-tol) && V <= (normSegment + tol));
75 }
76 
85 bool isPointInsideTriangle(const darray3E & p, const darray3E & V0,const darray3E & V1,const darray3E & V2, double tol){
86 
87  darray3E normal = crossProduct(V1 - V0,V2 - V0);
88  double normNormal = norm2(normal);
89  if(normNormal > std::numeric_limits<double>::min()) normal /= normNormal;
90  else return false;
91 
92  if(std::abs(dotProduct((p-V0), normal)) > tol){ return false;}
93 
94  double a1 = bitpit::CGElem::areaTriangle(p,V0,V1)/(0.5*normNormal);
95  double a2 = bitpit::CGElem::areaTriangle(p,V1,V2)/(0.5*normNormal);
96  double a3 = bitpit::CGElem::areaTriangle(p,V2,V0)/(0.5*normNormal);
97 
98  return ( (a1+a2+a3 -1.0) <= tol );
99 }
100 
109 bool isPointInsidePolygon(const darray3E & p,const dvecarr3E & vertCoords, double tol){
110 
111  //split it in subtriangles - fixed vertex 0 as pivot point, run 2-by-2 along vertCoords to get the other two vertices
112  bool check = false;
113  std::size_t sizeV = vertCoords.size();
114  std::size_t i = 1;
115  while(i<sizeV-1 && !check ){
116  check = mimmoCGUtils::isPointInsideTriangle(p, vertCoords[0], vertCoords[i], vertCoords[i+1], tol);
117  ++i;
118  }
119  return check;
120 }
121 
122 }
123 
124 }; // end namespace mimmo
std::vector< darray3E > dvecarr3E
double distancePointPolygon(const darray3E &p, const dvecarr3E &vertCoords)
bool isPointInsideSegment(const darray3E &p, const darray3E &V0, const darray3E &V1, double tol)
bool isPointInsidePolygon(const darray3E &p, const dvecarr3E &vertCoords, double tol)
std::array< double, 3 > darray3E
bool isPointInsideTriangle(const darray3E &p, const darray3E &V0, const darray3E &V1, const darray3E &V2, double tol)