2 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
4 // + This file is part of enGrid. +
6 // + Copyright 2008-2013 enGits GmbH +
8 // + enGrid is free software: you can redistribute it and/or modify +
9 // + it under the terms of the GNU General Public License as published by +
10 // + the Free Software Foundation, either version 3 of the License, or +
11 // + (at your option) any later version. +
13 // + enGrid is distributed in the hope that it will be useful, +
14 // + but WITHOUT ANY WARRANTY; without even the implied warranty of +
15 // + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +
16 // + GNU General Public License for more details. +
18 // + You should have received a copy of the GNU General Public License +
19 // + along with enGrid. If not, see <http://www.gnu.org/licenses/>. +
21 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
24 #include "geometrytools.h"
26 #include "utilities.h"
27 #include "egvtkobject.h"
29 Triangle::Triangle() : EgVtkObject()
35 Triangle::Triangle(vec3_t a
, vec3_t b
, vec3_t c
) : EgVtkObject()
44 Triangle::Triangle(vtkUnstructuredGrid
* grid
, vtkIdType id_a
, vtkIdType id_b
, vtkIdType id_c
) : EgVtkObject()
50 grid
->GetPoints()->GetPoint(id_a
, m_Xa
.data());
51 grid
->GetPoints()->GetPoint(id_b
, m_Xb
.data());
52 grid
->GetPoints()->GetPoint(id_c
, m_Xc
.data());
56 Triangle::Triangle(vtkUnstructuredGrid
* grid
, vtkIdType id_cell
) : EgVtkObject()
60 grid
->GetCellPoints(id_cell
, Npts
, pts
);
65 grid
->GetPoints()->GetPoint(m_IdA
, m_Xa
.data());
66 grid
->GetPoints()->GetPoint(m_IdB
, m_Xb
.data());
67 grid
->GetPoints()->GetPoint(m_IdC
, m_Xc
.data());
70 EG_ERR_RETURN("only triangles allowed at the moment");
74 void Triangle::setDefaults()
79 m_Xa
= vec3_t(0, 0, 0);
80 m_Xb
= vec3_t(0, 1, 0);
81 m_Xc
= vec3_t(0, 0, 1);
82 m_NormalA
= vec3_t(0, 0, 0);
83 m_NormalB
= vec3_t(0, 0, 0);
84 m_NormalC
= vec3_t(0, 0, 0);
87 void Triangle::setupTriangle()
89 m_HasNeighbour
.fill(false, 6);
93 m_G3
= m_G1
.cross(m_G2
);
95 if(m_G3
.abs2() <= 0) {
101 if(!checkVector(m_G3
)) {
102 qWarning() << "m_G1=" << m_G1
;
103 qWarning() << "m_G2=" << m_G2
;
104 qWarning() << "m_G3=" << m_G3
;
108 m_A
= 0.5 * m_G3
.abs();
113 if(!checkVector(m_G3
)) {
114 qWarning() << "m_G1="<<m_G1
;
115 qWarning() << "m_G2="<<m_G2
;
116 qWarning() << "m_G3="<<m_G3
;
117 qWarning() << "m_Xa="<<m_Xa
;
118 qWarning() << "m_Xb="<<m_Xb
;
119 qWarning() << "m_Xc="<<m_Xc
;
120 this->saveTriangle("crash");
127 m_GI
= m_G
.inverse();
129 m_SmallestLength
= (m_Xb
- m_Xa
).abs();
130 m_SmallestLength
= min(m_SmallestLength
, (m_Xc
- m_Xb
).abs());
131 m_SmallestLength
= min(m_SmallestLength
, (m_Xa
- m_Xc
).abs());
133 // compute minimal height
134 double ha
= (GeometryTools::projectPointOnEdge(m_Xa
, m_Xb
, (m_Xc
- m_Xb
)) - m_Xa
).abs();
135 double hb
= (GeometryTools::projectPointOnEdge(m_Xb
, m_Xa
, (m_Xc
- m_Xa
)) - m_Xb
).abs();
136 double hc
= (GeometryTools::projectPointOnEdge(m_Xc
, m_Xa
, (m_Xb
- m_Xa
)) - m_Xc
).abs();
137 m_SmallestHeight
= min(ha
, min(hb
, hc
));
141 vec3_t
Triangle::local3DToGlobal3D(vec3_t r
)
146 vec3_t
Triangle::global3DToLocal3D(vec3_t x
)
148 vec3_t tmp
= x
- m_Xa
;
152 vec3_t
Triangle::local2DToGlobal3D(vec2_t r
)
154 return local3DToGlobal3D(vec3_t(r
[0], r
[1], 0));
157 vec2_t
Triangle::global3DToLocal2D(vec3_t x
)
159 vec3_t r
= global3DToLocal3D(x
);
160 return vec2_t(r
[0], r
[1]);
163 bool Triangle::snapOntoTriangle(vec3_t xp
, vec3_t
&xi
, vec3_t
&ri
, double &d
, int& side
, bool restrict_to_triangle
)
166 double scal
= (xp
- this->m_Xa
) * this->m_G3
;
169 x1
= xp
+ this->m_G3
;
170 x2
= xp
- scal
* this->m_G3
- this->m_G3
;
172 x1
= xp
- this->m_G3
;
173 x2
= xp
- scal
* this->m_G3
+ this->m_G3
;
175 // (xi,ri) gets set to the intersection of the line with the plane here!
176 bool intersects_face
= GeometryTools::intersectEdgeAndTriangle(this->m_Xa
, this->m_Xb
, this->m_Xc
, x1
, x2
, xi
, ri
);
178 if (intersects_face
) {
179 vec3_t dx
= xp
- this->m_Xa
;
180 d
= fabs(dx
* this->m_G3
);
182 double kab
= GeometryTools::intersection(this->m_Xa
, this->m_Xb
- this->m_Xa
, xp
, this->m_Xb
- this->m_Xa
);
183 double kac
= GeometryTools::intersection(this->m_Xa
, this->m_Xc
- this->m_Xa
, xp
, this->m_Xc
- this->m_Xa
);
184 double kbc
= GeometryTools::intersection(this->m_Xb
, this->m_Xc
- this->m_Xb
, xp
, this->m_Xc
- this->m_Xb
);
186 double dab
= (this->m_Xa
+ kab
* (this->m_Xb
- this->m_Xa
) - xp
).abs2();
187 double dac
= (this->m_Xa
+ kac
* (this->m_Xc
- this->m_Xa
) - xp
).abs2();
188 double dbc
= (this->m_Xb
+ kbc
* (this->m_Xc
- this->m_Xb
) - xp
).abs2();
189 double da
= (this->m_Xa
- xp
).abs2();
190 double db
= (this->m_Xb
- xp
).abs2();
191 double dc
= (this->m_Xc
- xp
).abs2();
194 d
= 1e99
;//max(max(max(max(max(dab,dac),dbc),da),db),dc);
197 if ((kab
>= 0) && (kab
<= 1)) {
198 xi
= this->m_Xa
+ kab
* (this->m_Xb
- this->m_Xa
);
199 ri
= vec3_t(kab
, 0, 0);
206 if ((kbc
>= 0) && (kbc
<= 1)) {
207 xi
= this->m_Xb
+ kbc
* (this->m_Xc
- this->m_Xb
);
208 ri
= vec3_t(1 - kbc
, kbc
, 0);
215 if ((kac
>= 0) && (kac
<= 1)) {
216 xi
= this->m_Xa
+ kac
* (this->m_Xc
- this->m_Xa
);
217 ri
= vec3_t(0, kac
, 0);
249 if (!intersects_face
&& !restrict_to_triangle
) {
252 if (xi
[0] > 1e98
) { // should never happen
255 return intersects_face
;
258 void Triangle::saveTriangle(QString filename
)
263 EG_VTKSP(vtkUnstructuredGrid
, triangle_grid
);
264 allocateGrid(triangle_grid
, N_cells
, N_points
);
266 vtkIdType node_count
= 0;
270 triangle_grid
->GetPoints()->SetPoint(node_count
, m_Xa
.data()); pts
[0]=node_count
; node_count
++;
271 triangle_grid
->GetPoints()->SetPoint(node_count
, m_Xb
.data()); pts
[1]=node_count
; node_count
++;
272 triangle_grid
->GetPoints()->SetPoint(node_count
, m_Xc
.data()); pts
[2]=node_count
; node_count
++;
274 triangle_grid
->InsertNextCell(VTK_TRIANGLE
,3,pts
);cell_count
++;
276 saveGrid(triangle_grid
, filename
+"_triangle_grid");
279 void Triangle::setNormals(vec3_t na
, vec3_t nb
, vec3_t nc
)
284 // compute normal vectors in local coordinate system
285 m_RNormalA
= global3DToLocal3D(a() + nA());
286 m_RNormalB
= global3DToLocal3D(a() + nB());
287 m_RNormalC
= global3DToLocal3D(a() + nC());