-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtriangle.go
62 lines (53 loc) · 1.22 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
package PPM
import "math"
type Triangle struct {
Point [3]V // 位置
Mat Material // 材质
Norm V //法向量
Name string // 名称
center V
}
// 是否相交,交点
func (t Triangle) Collide(r *Ray) (bool, float64, *V) {
t0 := t.Norm.Dot(r.Dir)
if t0 > 0 { // 单向面
return false, -1, nil
}
e1 := t.Point[1].Sub(t.Point[0])
e2 := t.Point[2].Sub(t.Point[0])
T := r.Pos.Sub(t.Point[0])
p := r.Dir.Cross(e2)
q := T.Cross(e1)
pe1 := p.Dot(e1)
if math.Abs(pe1) < 1e-5 {
return false, -1., nil
}
tt := q.Dot(e2) / pe1
u := p.Dot(T) / pe1
v := q.Dot(r.Dir) / pe1
if u < 0 || v < 0 || u+v > 1 || tt < 0 {
return false, -1., nil
}
return true, tt, &t.Norm
}
func (t Triangle) GetMaterial() Material {
return t.Mat
}
func (t Triangle) GetName() string {
return t.Name
}
func (t Triangle) GetCenter() V {
return t.center
}
func (t Triangle) GetMin() V {
return t.Point[0].Min(t.Point[1]).Min(t.Point[2])
}
func (t Triangle) GetMax() V {
return t.Point[0].Max(t.Point[1]).Max(t.Point[2])
}
func NewTriangle(a, b, c V, mat Material, name string) *Triangle {
v1 := b.Sub(a)
v2 := c.Sub(a)
norm := v1.Cross(v2).Norm()
return &Triangle{[3]V{a, b, c}, mat, norm, name, a.Add(b).Add(c).Div(3)}
}