triangle.go 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  1. // Copyright 2016 The G3N Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style
  3. // license that can be found in the LICENSE file.
  4. package math32
  5. // Triangle represents a triangle of vertices
  6. type Triangle struct {
  7. a Vector3
  8. b Vector3
  9. c Vector3
  10. }
  11. // New Triangle returns a pointer to a new Triangle object
  12. func NewTriangle(a, b, c *Vector3) *Triangle {
  13. t := new(Triangle)
  14. if a != nil {
  15. t.a = *a
  16. }
  17. if b != nil {
  18. t.b = *b
  19. }
  20. if c != nil {
  21. t.c = *c
  22. }
  23. return t
  24. }
  25. // Normal returns the triangle's normal
  26. func Normal(a, b, c, optionalTarget *Vector3) *Vector3 {
  27. var v0 Vector3
  28. var result *Vector3
  29. if optionalTarget != nil {
  30. result = optionalTarget
  31. } else {
  32. result = NewVector3(0, 0, 0)
  33. }
  34. result.SubVectors(c, b)
  35. v0.SubVectors(a, b)
  36. result.Cross(&v0)
  37. resultLengthSq := result.LengthSq()
  38. if resultLengthSq > 0 {
  39. return result.MultiplyScalar(1 / Sqrt(resultLengthSq))
  40. }
  41. return result.Set(0, 0, 0)
  42. }
  43. // BarycoordFromPoint returns the barycentric coordinates for the specified point
  44. func BarycoordFromPoint(point, a, b, c, optionalTarget *Vector3) *Vector3 {
  45. var v0 Vector3
  46. var v1 Vector3
  47. var v2 Vector3
  48. v0.SubVectors(c, a)
  49. v1.SubVectors(b, a)
  50. v2.SubVectors(point, a)
  51. dot00 := v0.Dot(&v0)
  52. dot01 := v0.Dot(&v1)
  53. dot02 := v0.Dot(&v2)
  54. dot11 := v1.Dot(&v1)
  55. dot12 := v1.Dot(&v2)
  56. denom := dot00*dot11 - dot01*dot01
  57. var result *Vector3
  58. if optionalTarget != nil {
  59. result = optionalTarget
  60. } else {
  61. result = NewVector3(0, 0, 0)
  62. }
  63. // colinear or singular triangle
  64. if denom == 0 {
  65. // arbitrary location outside of triangle?
  66. // not sure if this is the best idea, maybe should be returning undefined
  67. return result.Set(-2, -1, -1)
  68. }
  69. invDenom := 1 / denom
  70. u := (dot11*dot02 - dot01*dot12) * invDenom
  71. v := (dot00*dot12 - dot01*dot02) * invDenom
  72. // barycoordinates must always sum to 1
  73. return result.Set(1-u-v, v, u)
  74. }
  75. // ContainsPoint returns whether a triangle contains a point
  76. func ContainsPoint(point, a, b, c *Vector3) bool {
  77. var v1 Vector3
  78. result := BarycoordFromPoint(point, a, b, c, &v1)
  79. return (result.X >= 0) && (result.Y >= 0) && ((result.X + result.Y) <= 1)
  80. }
  81. // Set sets the triangle's three vertices
  82. func (t *Triangle) Set(a, b, c *Vector3) *Triangle {
  83. t.a = *a
  84. t.b = *b
  85. t.c = *c
  86. return t
  87. }
  88. // SetFromPointsAndIndices sets the triangle's vertices based on the specified points and indices
  89. func (t *Triangle) SetFromPointsAndIndices(points []*Vector3, i0, i1, i2 int) *Triangle {
  90. t.a = *points[i0]
  91. t.b = *points[i1]
  92. t.c = *points[i2]
  93. return t
  94. }
  95. // Copy modifies the receiver triangle to match the provided triangle
  96. func (t *Triangle) Copy(triangle *Triangle) *Triangle {
  97. *t = *triangle
  98. return t
  99. }
  100. // Area returns the triangle's area
  101. func (t *Triangle) Area() float32 {
  102. var v0 Vector3
  103. var v1 Vector3
  104. v0.SubVectors(&t.c, &t.b)
  105. v1.SubVectors(&t.a, &t.b)
  106. return v0.Cross(&v1).Length() * 0.5
  107. }
  108. // Midpoint returns the triangle's midpoint
  109. func (t *Triangle) Midpoint(optionalTarget *Vector3) *Vector3 {
  110. var result *Vector3
  111. if optionalTarget != nil {
  112. result = optionalTarget
  113. } else {
  114. result = NewVector3(0, 0, 0)
  115. }
  116. return result.AddVectors(&t.a, &t.b).Add(&t.c).MultiplyScalar(1 / 3)
  117. }
  118. // Normal returns the triangle's normal
  119. func (t *Triangle) Normal(optionalTarget *Vector3) *Vector3 {
  120. return Normal(&t.a, &t.b, &t.c, optionalTarget)
  121. }
  122. // Plane returns a Plane object aligned with the triangle
  123. func (t *Triangle) Plane(optionalTarget *Plane) *Plane {
  124. var result *Plane
  125. if optionalTarget != nil {
  126. result = optionalTarget
  127. } else {
  128. result = NewPlane(nil, 0)
  129. }
  130. return result.SetFromCoplanarPoints(&t.a, &t.b, &t.c)
  131. }
  132. // BarycoordFromPoint returns the barycentric coordinates for the specified point
  133. func (t *Triangle) BarycoordFromPoint(point, optionalTarget *Vector3) *Vector3 {
  134. return BarycoordFromPoint(point, &t.a, &t.b, &t.c, optionalTarget)
  135. }
  136. // ContainsPoint returns whether the triangle contains a point
  137. func (t *Triangle) ContainsPoint(point *Vector3) bool {
  138. return ContainsPoint(point, &t.a, &t.b, &t.c)
  139. }
  140. // Equals returns whether the triangles are equal in all their vertices
  141. func (t *Triangle) Equals(triangle *Triangle) bool {
  142. return triangle.a.Equals(&t.a) && triangle.b.Equals(&t.b) && triangle.c.Equals(&t.c)
  143. }
  144. // Clone clones a triangle
  145. func (t *Triangle) Clone(triangle *Triangle) *Triangle {
  146. return NewTriangle(nil, nil, nil).Copy(t)
  147. }