PeriDyno 1.0.0
Loading...
Searching...
No Matches
IntersectionArea.h
Go to the documentation of this file.
1
16#pragma once
18
19namespace dyno
20{
30 template<typename Real>
31 DYN_FUNC inline Real calculateIntersectionArea(const TPoint3D<Real>& pt, const TTriangle3D<Real>& triangle, const Real& R)
32 {
33 typedef typename ::dyno::Vector<Real, 3> Coord3D;
34
35 Real R2 = R * R;
36
37 if (triangle.area() < EPSILON) {
38 return Real(0);
39 }
40
41 TPlane3D<Real> plane = TPlane3D<Real>(triangle.v[0], triangle.normal());
42
43 Real d2 = pt.distanceSquared(plane);
44
45 if (d2 >= R2) return Real(0);
46
47 //case 0
48 if (abs(pt.distance(triangle)) > R)
49 return Real(0);
50
51 Real r = sqrt(R2 - d2);
52
53 TPoint3D<Real> center = pt.project(plane);
54
55 uint nv = 0;
56 for (uint j = 0; j < 3; j++)
57 {
58 if ((triangle.v[j] - center.origin).norm() <= r)
59 {
60 nv++;
61 }
62 }
63
64 //case 9
65 if (nv == 3)
66 return triangle.area();
67
68 //case 8
69 if (nv == 2)
70 {
71 Real ret = Real(0);
72 uint outsideId = 0;
73 for (uint j = 0; j < 3; j++)
74 {
75 if ((triangle.v[j] - center.origin).norm() > r)
76 {
77 outsideId = j;
78 break;
79 }
80 }
81
82 Coord3D v0 = triangle.v[outsideId];
83 Coord3D v1 = triangle.v[(outsideId + 1) % 3];
84 Coord3D v2 = triangle.v[(outsideId + 2) % 3];
85
86 Coord3D dir01 = v1 - v0; dir01.normalize();
87 Coord3D dir02 = v2 - v0; dir02.normalize();
88
89 Line3D line1 = Line3D(v0, dir01);
90 Line3D line2 = Line3D(v0, dir02);
91
92 Point3D p1 = center.project(line1);
93 Point3D p2 = center.project(line2);
94
95 Real l1 = sqrt(r * r - center.distanceSquared(p1));
96 Real l2 = sqrt(r * r - center.distanceSquared(p2));
97
98 Coord3D s1 = p1.origin - l1 * dir01;
99 Coord3D s2 = p2.origin - l2 * dir02;
100
101 ret += TTriangle3D<Real>(v0, v1, v2).area();
102 ret -= TTriangle3D<Real>(v0, s1, s2).area();
103
104 Real d1 = center.distance(Segment3D(s1, s2));
105 Real d10 = 0.5 * (s1 - s2).norm();
106 Real angle = asin(d10 / r);
107 Real secArea = angle * r * r - d1 * d10;
108
109 ret += secArea;
110
111 return maximum(ret, Real(0));
112 }
113
114 //case 6 and 7
115 if (nv == 1)
116 {
117 Real ret = Real(0);
118 uint insideId = 0;
119 for (uint j = 0; j < 3; j++)
120 {
121 if ((triangle.v[j] - center.origin).norm() <= r)
122 {
123 insideId = j;
124 break;
125 }
126 }
127
128 Coord3D v0 = triangle.v[insideId];
129 Coord3D v1 = triangle.v[(insideId + 1) % 3];
130 Coord3D v2 = triangle.v[(insideId + 2) % 3];
131
132 //Calculate the intersection points between the circle and v0-v1/v0-v2
133 Coord3D dir01 = v1 - v0; dir01.normalize();
134 Coord3D dir02 = v2 - v0; dir02.normalize();
135 Coord3D dir12 = v2 - v1; dir12.normalize();
136
137 Line3D line01 = Line3D(v0, dir01);
138 Line3D line02 = Line3D(v0, dir02);
139
140 Point3D p1 = center.project(line01);
141 Point3D p2 = center.project(line02);
142
143 Real d1 = center.distance(p1);
144 Real d2 = center.distance(p2);
145
146 Real l1 = sqrt(r * r - d1 * d1);
147 Real l2 = sqrt(r * r - d2 * d2);
148
149 Coord3D s1 = p1.origin + l1 * dir01;
150 Coord3D s2 = p2.origin + l2 * dir02;
151 TSegment3D<Real> seg12 = Segment3D(v1, v2);
152 //case 7
153 if (center.distance(seg12) <= r)
154 {
155 ret += Triangle3D(v0, v1, v2).area();
156
157 TPoint3D<Real> p0 = center.project(seg12);
158 Real l = sqrt(r * r - center.distanceSquared(p0));
159
160 Coord3D s10 = p0.origin - l * dir12;
161 Coord3D s20 = p0.origin + l * dir12;
162
163 ret -= TTriangle3D<Real>(v1, s1, s10).area();
164 ret -= TTriangle3D<Real>(v2, s2, s20).area();
165
166 Real d2 = center.distance(Segment3D(s2, s20));
167 Real d20 = 0.5 * (s2 - s20).norm();
168 Real angle2 = asin(d20 / r);
169 Real secArea2 = angle2 * r * r - d2 * d20;
170
171 Real d1 = center.distance(Segment3D(s1, s10));
172 Real d10 = 0.5 * (s1 - s10).norm();
173 Real angle1 = asin(d10 / r);
174 Real secArea1 = angle1 * r * r - d1 * d10;
175
176 ret += secArea1 + secArea2;
177 }
178 //case 6
179 else
180 {
181 ret += TTriangle3D<Real>(v0, s1, s2).area();
182
183 Real d0 = center.distance(Segment3D(s1, s2));
184 Real d12 = 0.5 * (s1 - s2).norm();
185 Real angle = asin(d12 / r);
186
187 //check whether the center is located inside the triangle
188 bool opposite = (v0 - s1).dot(center.origin - s1) < 0;
189
190 //calculate sector area
191 Real secArea = opposite ? (M_PI - angle) * r * r : angle * r * r;
192
193 //subtract/add the triangle from/to the sector
194 secArea += opposite ? d0 * d12 : -d0 * d12;
195
196 ret += secArea;
197 }
198
199 return maximum(ret, Real(0));
200 }
201
202 //case 2, 3, 4 and 5
203 Real circleArea = Real(M_PI) * r * r;
204 Real ret = circleArea;
205 for (int j = 0; j < 3; j++)
206 {
207 Coord3D v0 = triangle.v[j];
208 Coord3D v1 = triangle.v[(j + 1) % 3];
209 Coord3D v2 = triangle.v[(j + 2) % 3];
210 TSegment3D<Real> seg12 = TSegment3D<Real>(v1, v2);
211
212 TPoint3D<Real> p = center.project(seg12);
213
214 Real secArea = Real(0);
215 Real d0 = center.distance(p);
216 if (d0 <= r)
217 {
218 Real d1 = sqrt(r * r - d0 * d0);
219 Real angle = asin(d1 / r);
220
221 //check whether the center is located inside the triangle
222 bool opposite = (p.origin - center.origin).dot(p.origin - v0) < 0;
223
224 //calculate sector area
225 secArea = opposite ? (M_PI - angle) * r * r : angle * r * r;
226
227 //subtract/add the triangle from/to the sector
228 secArea += opposite ? d0 * d1 : -d0 * d1;
229 }
230
231 ret -= secArea;
232 }
233 return maximum(ret, Real(0));
234 }
235}
double Real
Definition Typedef.inl:23
#define M_PI
Definition Typedef.inl:36
2D geometric primitives in three-dimensional space
0D geometric primitive in three-dimensional space
DYN_FUNC Real distanceSquared(const TPoint3D< Real > &pt) const
DYN_FUNC TPoint3D< Real > project(const TLine3D< Real > &line) const
project a point onto linear components – lines, rays and segments
DYN_FUNC Real distance(const TPoint3D< Real > &pt) const
DYN_FUNC Real area() const
DYN_FUNC Coord3D normal() const
This is an implementation of AdditiveCCD based on peridyno.
Definition Array.h:25
DYN_FUNC T dot(Vector< T, 2 > const &U, Vector< T, 2 > const &V)
Definition SimpleMath.h:199
TLine3D< double > Line3D
DYN_FUNC T abs(const T &v)
Definition SimpleMath.h:81
TTriangle3D< double > Triangle3D
constexpr Real EPSILON
Definition Typedef.inl:42
DYN_FUNC Real calculateIntersectionArea(const TPoint3D< Real > &pt, const TTriangle3D< Real > &triangle, const Real &R)
Calculate the intersection area between a sphere and a triangle by using the domain decompsotion algo...
TPoint3D< double > Point3D
DYN_FUNC Complex< Real > sqrt(const Complex< Real > &)
Definition Complex.inl:321
unsigned int uint
Definition VkProgram.h:14
DYN_FUNC T maximum(const T &v0, const T &v1)
Definition SimpleMath.h:160
TSegment3D< double > Segment3D
DYN_FUNC Complex< Real > asin(const Complex< Real > &)
Definition Complex.inl:510