-
Notifications
You must be signed in to change notification settings - Fork 14
/
triangle.go
67 lines (57 loc) · 2.42 KB
/
triangle.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
package stl
// This file defines the Triangle data type, the building block for Solid
// Triangle represents single triangles used in Solid.Triangles. The vertices
// have to be ordered counter-clockwise when looking at their outside surface.
// The vector Normal is orthogonal to the triangle, pointing outside, and
// has length 1. This is redundant but included in the STL format in order to
// avoid recalculation.
type Triangle struct {
// Normal vector of triangle, should be normalized...
Normal Vec3
// Vertices of triangle in right hand order.
// I.e. from the front the triangle's vertices are ordered counterclockwise
// and the normal vector is orthogonal to the front pointing outside.
Vertices [3]Vec3
// 16 bits of attributes. Not available in ASCII format. Could be used
// for color selection, texture selection, refraction etc. Some tools ignore
// this field completely, always writing 0 on export.
Attributes uint16
}
// Calculate the normal vector using the right hand rule
func (t *Triangle) calculateNormal() Vec3 {
// The normal is calculated by normalizing the result of
// (V0-V2) x (V1-V2)
return t.Vertices[0].Diff(t.Vertices[2]).
Cross(t.Vertices[1].Diff(t.Vertices[2])).
UnitVec3()
}
// Recalculate the redundant normal vector using the right hand rule
func (t *Triangle) recalculateNormal() {
t.Normal = t.calculateNormal()
}
// Applies a 4x4 transformation matrix to every vertex
// and recalculates the normal
func (t *Triangle) transform(transformationMatrix *Mat4) {
t.transformNR(transformationMatrix)
t.recalculateNormal()
}
// Applies a 4x4 transformation matrix to every vertex
// without recalculating the normal afterwards
func (t *Triangle) transformNR(transformationMatrix *Mat4) {
t.Vertices[0] = transformationMatrix.MultVec3(t.Vertices[0])
t.Vertices[1] = transformationMatrix.MultVec3(t.Vertices[1])
t.Vertices[2] = transformationMatrix.MultVec3(t.Vertices[2])
}
// Returns true if at least two vertices are exactly equal, meaning
// this is a line, or even a Dot.
func (t *Triangle) hasEqualVertices() bool {
return t.Vertices[0] == t.Vertices[1] ||
t.Vertices[0] == t.Vertices[2] ||
t.Vertices[1] == t.Vertices[2]
}
// Checks if normal matches vertices using right hand rule, with
// numerical tolerance for Angle between them given by tol in radians.
func (t *Triangle) checkNormal(tol float64) bool {
calculatedNormal := t.calculateNormal()
return t.Normal.Angle(calculatedNormal) < tol
}