VPTissue Reference Manual
GeoData.h
Go to the documentation of this file.
1 #ifndef GEO_DATA_H_INCLUDED
2 #define GEO_DATA_H_INCLUDED
3 /*
4  * Copyright 2011-2016 Universiteit Antwerpen
5  *
6  * Licensed under the EUPL, Version 1.1 or as soon they will be approved by
7  * the European Commission - subsequent versions of the EUPL (the "Licence");
8  * You may not use this work except in compliance with the Licence.
9  * You may obtain a copy of the Licence at: http://ec.europa.eu/idabc/eupl5
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the Licence is distributed on an "AS IS" basis,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the Licence for the specific language governing
15  * permissions and limitations under the Licence.
16  */
22 #include "AreaMoment.h"
23 
24 #include "math/array3.h"
25 
26 #include <array>
27 #include <iostream>
28 #include <tuple>
29 
30 namespace SimPT_Sim {
31 
35 struct GeoData
36 {
37  GeoData()
38  : m_area(0.0)
39  {
40  }
41 
42  GeoData(double area, const std::array<double, 3>& centroid, const AreaMoment& area_moment)
43  : m_area(area), m_centroid(centroid), m_area_moment(area_moment)
44  {
45  }
46 
50  std::tuple<double, std::array<double, 3>, double> GetEllipseAxes() const
51  {
52  double const ea_xx = m_area_moment.m_xx - (m_centroid[0] * m_centroid[0]) * m_area;
53  double const ea_xy = m_area_moment.m_xy + (m_centroid[0] * m_centroid[1]) * m_area;
54  double const ea_yy = m_area_moment.m_yy - (m_centroid[1] * m_centroid[1]) * m_area;
55  double const rhs1 = 0.5 * (ea_xx + ea_yy);
56  double const rhs2 = 0.5 * sqrt((ea_xx - ea_yy) * (ea_xx - ea_yy) + 4 * ea_xy * ea_xy);
57 
58  const double length { 4.0 * sqrt((rhs1 + rhs2) / m_area) };
59  const double width { 4.0 * sqrt((rhs1 - rhs2) / m_area) };
60  const std::array<double, 3> long_axis {{ -ea_xy, rhs1 + rhs2 - ea_xx, 0.0 }};
61 
62  return std::make_tuple(length, long_axis, width);
63  }
64 
65 
66  GeoData& operator+=(const GeoData& rhs)
67  {
68  m_area += rhs.m_area;
69  m_centroid += rhs.m_centroid;
70  m_area_moment += rhs.m_area_moment;
71  return *this;
72  }
73 
74  GeoData& operator-=(const GeoData& rhs)
75  {
76  m_area -= rhs.m_area;
77  m_centroid -= rhs.m_centroid;
78  m_area_moment -= rhs.m_area_moment;
79  return *this;
80  }
81 
82  double m_area;
83  std::array<double, 3> m_centroid;
84  AreaMoment m_area_moment;
85 };
86 
87 
88 inline GeoData ModifyForMove(const GeoData& old_geo,
89  const std::array<double, 3>& nb1_p, const std::array<double, 3>& nb2_p,
90  const std::array<double, 3>& now_p, const std::array<double, 3>& mov_p)
91 {
92  const double del_area
93  = 0.5 * ((mov_p[0] - now_p[0]) * (nb1_p[1] - nb2_p[1])
94  + (mov_p[1] - now_p[1]) * (nb2_p[0] - nb1_p[0]));
95  const double new_area = old_geo.m_area - del_area;
96 
97  const double del_x
98  = (nb1_p[0] + mov_p[0]) * (mov_p[0] * nb1_p[1] - nb1_p[0] * mov_p[1])
99  + (mov_p[0] + nb2_p[0]) * (nb2_p[0] * mov_p[1] - mov_p[0] * nb2_p[1])
100  - (nb1_p[0] + now_p[0]) * (now_p[0] * nb1_p[1] - nb1_p[0] * now_p[1])
101  - (now_p[0] + nb2_p[0]) * (nb2_p[0] * now_p[1] - now_p[0] * nb2_p[1]);
102 
103  const double del_y
104  = (nb1_p[1] + mov_p[1]) * (mov_p[0] * nb1_p[1] - nb1_p[0] * mov_p[1])
105  + (mov_p[1] + nb2_p[1]) * (nb2_p[0] * mov_p[1] - mov_p[0] * nb2_p[1])
106  - (nb1_p[1] + now_p[1]) * (now_p[0] * nb1_p[1] - nb1_p[0] * now_p[1])
107  - (now_p[1] + nb2_p[1]) * (nb2_p[0] * now_p[1] - now_p[0] * nb2_p[1]);
108 
109  const double del_xx
110  = (mov_p[0] * mov_p[0] + nb1_p[0] * mov_p[0] + nb1_p[0] * nb1_p[0])
111  * (mov_p[0] * nb1_p[1] - nb1_p[0] * mov_p[1])
112  + (nb2_p[0] * nb2_p[0] + mov_p[0] * nb2_p[0] + mov_p[0] * mov_p[0])
113  * (nb2_p[0] * mov_p[1] - mov_p[0] * nb2_p[1])
114  - (now_p[0] * now_p[0] + nb1_p[0] * now_p[0] + nb1_p[0] * nb1_p[0])
115  * (now_p[0] * nb1_p[1] - nb1_p[0] * now_p[1])
116  - (nb2_p[0] * nb2_p[0] + now_p[0] * nb2_p[0] + now_p[0] * now_p[0])
117  * (nb2_p[0] * now_p[1] - now_p[0] * nb2_p[1]);
118 
119  const double del_xy
120  = (nb1_p[0] * mov_p[1] - mov_p[0] * nb1_p[1])
121  * (mov_p[0] * (2 * mov_p[1] + nb1_p[1]) + nb1_p[0] * (mov_p[1] + 2.0 * nb1_p[1]))
122  + (mov_p[0] * nb2_p[1] - nb2_p[0] * mov_p[1])
123  * (nb2_p[0] * (2 * nb2_p[1] + mov_p[1]) + mov_p[0] * (nb2_p[1] + 2.0 * mov_p[1]))
124  - (nb1_p[0] * now_p[1] - now_p[0] * nb1_p[1])
125  * (now_p[0] * (2 * now_p[1] + nb1_p[1]) + nb1_p[0] * (now_p[1] + 2.0 * nb1_p[1]))
126  - (now_p[0] * nb2_p[1] - nb2_p[0] * now_p[1])
127  * (nb2_p[0] * (2 * nb2_p[1] + now_p[1]) + now_p[0] * (nb2_p[1] + 2.0 * now_p[1]));
128 
129  const double del_yy
130  = (mov_p[0] * nb1_p[1] - nb1_p[0] * mov_p[1])
131  * (mov_p[1] * mov_p[1] + nb1_p[1] * mov_p[1] + nb1_p[1] * nb1_p[1])
132  + (nb2_p[0] * mov_p[1] - mov_p[0] * nb2_p[1])
133  * (nb2_p[1] * nb2_p[1] + mov_p[1] * nb2_p[1] + mov_p[1] * mov_p[1])
134  - (now_p[0] * nb1_p[1] - nb1_p[0] * now_p[1])
135  * (now_p[1] * now_p[1] + nb1_p[1] * now_p[1] + nb1_p[1] * nb1_p[1])
136  - (nb2_p[0] * now_p[1] - now_p[0] * nb2_p[1])
137  * (nb2_p[1] * nb2_p[1] + now_p[1] * nb2_p[1] + now_p[1] * now_p[1]);
138 
139  return GeoData(
140  new_area,
141  (old_geo.m_centroid * 6.0 * old_geo.m_area - std::array<double, 3> {{del_x, del_y, 0.0 }}) / (6.0 * new_area),
142  old_geo.m_area_moment - AreaMoment(del_xx/ 12.0, del_xy / 24.0, del_yy / 12.0)
143  );
144 }
145 
146 inline GeoData operator+(const GeoData& i1, const GeoData& i2)
147 {
148  return GeoData(i1.m_area + i2.m_area,
149  i1.m_centroid + i2.m_centroid, i1.m_area_moment + i2.m_area_moment);
150 }
151 
152 inline GeoData operator-(const GeoData& i1, const GeoData& i2)
153 {
154  return GeoData(i1.m_area - i2.m_area,
155  i1.m_centroid - i2.m_centroid, i1.m_area_moment - i2.m_area_moment);
156 }
157 
158 inline std::ostream& operator<<(std::ostream& os, const GeoData& c)
159 {
160  os << "GeoData: {" << std::endl
161  << "\t area: " << c.m_area << std::endl
162  << "\t centroid: " << c.m_centroid << std::endl
163  << "\t area moment of inertia: " << c.m_area_moment << std::endl
164  << "}";
165 
166  return os;
167 }
168 
169 }
170 
171 #endif //end_of_include_guard
Plain data structure with cell geometric data (such as area).
Definition: GeoData.h:35
Interface/Implementation for AreaMoment.
Namespace for the core simulator.
Structure with functionality for calculations of the area moment of inertia.
Definition: AreaMoment.h:27
Extending std with arithmetic for std::array.
std::tuple< double, std::array< double, 3 >, double > GetEllipseAxes() const
Calculate axes (length and direction) area moment of inertia ellipse.
Definition: GeoData.h:50