triangle.go 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  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. type Triangle struct {
  6. a Vector3
  7. b Vector3
  8. c Vector3
  9. }
  10. func NewTriangle(a, b, c *Vector3) *Triangle {
  11. this := new(Triangle)
  12. if a != nil {
  13. this.a = *a
  14. }
  15. if b != nil {
  16. this.b = *b
  17. }
  18. if c != nil {
  19. this.c = *c
  20. }
  21. return this
  22. }
  23. func Normal(a, b, c, optionalTarget *Vector3) *Vector3 {
  24. var v0 Vector3
  25. var result *Vector3
  26. if optionalTarget != nil {
  27. result = optionalTarget
  28. } else {
  29. result = NewVector3(0, 0, 0)
  30. }
  31. result.SubVectors(c, b)
  32. v0.SubVectors(a, b)
  33. result.Cross(&v0)
  34. resultLengthSq := result.LengthSq()
  35. if resultLengthSq > 0 {
  36. return result.MultiplyScalar(1 / Sqrt(resultLengthSq))
  37. }
  38. return result.Set(0, 0, 0)
  39. }
  40. func BarycoordFromPoint(point, a, b, c, optionalTarget *Vector3) *Vector3 {
  41. var v0 Vector3
  42. var v1 Vector3
  43. var v2 Vector3
  44. v0.SubVectors(c, a)
  45. v1.SubVectors(b, a)
  46. v2.SubVectors(point, a)
  47. dot00 := v0.Dot(&v0)
  48. dot01 := v0.Dot(&v1)
  49. dot02 := v0.Dot(&v2)
  50. dot11 := v1.Dot(&v1)
  51. dot12 := v1.Dot(&v2)
  52. denom := dot00*dot11 - dot01*dot01
  53. var result *Vector3
  54. if optionalTarget != nil {
  55. result = optionalTarget
  56. } else {
  57. result = NewVector3(0, 0, 0)
  58. }
  59. // colinear or singular triangle
  60. if denom == 0 {
  61. // arbitrary location outside of triangle?
  62. // not sure if this is the best idea, maybe should be returning undefined
  63. return result.Set(-2, -1, -1)
  64. }
  65. invDenom := 1 / denom
  66. u := (dot11*dot02 - dot01*dot12) * invDenom
  67. v := (dot00*dot12 - dot01*dot02) * invDenom
  68. // barycoordinates must always sum to 1
  69. return result.Set(1-u-v, v, u)
  70. }
  71. func ContainsPoint(point, a, b, c *Vector3) bool {
  72. var v1 Vector3
  73. result := BarycoordFromPoint(point, a, b, c, &v1)
  74. return (result.X >= 0) && (result.Y >= 0) && ((result.X + result.Y) <= 1)
  75. }
  76. func (this *Triangle) Set(a, b, c *Vector3) *Triangle {
  77. this.a = *a
  78. this.b = *b
  79. this.c = *c
  80. return this
  81. }
  82. func (this *Triangle) SetFromPointsAndIndices(points []*Vector3, i0, i1, i2 int) *Triangle {
  83. this.a = *points[i0]
  84. this.b = *points[i1]
  85. this.c = *points[i2]
  86. return this
  87. }
  88. func (this *Triangle) Copy(triangle *Triangle) *Triangle {
  89. *this = *triangle
  90. return this
  91. }
  92. func (this *Triangle) Area() float32 {
  93. var v0 Vector3
  94. var v1 Vector3
  95. v0.SubVectors(&this.c, &this.b)
  96. v1.SubVectors(&this.a, &this.b)
  97. return v0.Cross(&v1).Length() * 0.5
  98. }
  99. func (this *Triangle) Midpoint(optionalTarget *Vector3) *Vector3 {
  100. var result *Vector3
  101. if optionalTarget != nil {
  102. result = optionalTarget
  103. } else {
  104. result = NewVector3(0, 0, 0)
  105. }
  106. return result.AddVectors(&this.a, &this.b).Add(&this.c).MultiplyScalar(1 / 3)
  107. }
  108. func (this *Triangle) Normal(optionalTarget *Vector3) *Vector3 {
  109. return Normal(&this.a, &this.b, &this.c, optionalTarget)
  110. }
  111. func (this *Triangle) Plane(optionalTarget *Plane) *Plane {
  112. var result *Plane
  113. if optionalTarget != nil {
  114. result = optionalTarget
  115. } else {
  116. result = NewPlane(nil, 0)
  117. }
  118. return result.SetFromCoplanarPoints(&this.a, &this.b, &this.c)
  119. }
  120. func (this *Triangle) BarycoordFromPoint(point, optionalTarget *Vector3) *Vector3 {
  121. return BarycoordFromPoint(point, &this.a, &this.b, &this.c, optionalTarget)
  122. }
  123. func (this *Triangle) ContainsPoint(point *Vector3) bool {
  124. return ContainsPoint(point, &this.a, &this.b, &this.c)
  125. }
  126. func (this *Triangle) Equals(triangle *Triangle) bool {
  127. return triangle.a.Equals(&this.a) && triangle.b.Equals(&this.b) && triangle.c.Equals(&this.c)
  128. }
  129. func (this *Triangle) Clone(triangle *Triangle) *Triangle {
  130. return NewTriangle(nil, nil, nil).Copy(this)
  131. }