sphere.go 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  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 Sphere struct {
  6. Center Vector3 // center of the sphere
  7. Radius float32 // radius of the sphere
  8. }
  9. // NewSphere creates and returns a pointer to a new sphere with
  10. // the specified center and radius
  11. func NewSphere(center *Vector3, radius float32) *Sphere {
  12. s := new(Sphere)
  13. s.Center = *center
  14. s.Radius = radius
  15. return s
  16. }
  17. // Set sets the center and radius of the sphere
  18. func (s *Sphere) Set(center *Vector3, radius float32) *Sphere {
  19. s.Center = *center
  20. s.Radius = radius
  21. return s
  22. }
  23. func (this *Sphere) SetFromPoints(points []Vector3, optionalCenter *Vector3) *Sphere {
  24. box := NewBox3(nil, nil)
  25. if optionalCenter != nil {
  26. this.Center.Copy(optionalCenter)
  27. } else {
  28. box.SetFromPoints(points).Center(&this.Center)
  29. }
  30. var maxRadiusSq float32 = 0.0
  31. for i := 0; i < len(points); i++ {
  32. maxRadiusSq = Max(maxRadiusSq, this.Center.DistanceToSquared(&points[i]))
  33. }
  34. this.Radius = Sqrt(maxRadiusSq)
  35. return this
  36. }
  37. func (this *Sphere) Copy(sphere *Sphere) *Sphere {
  38. *this = *sphere
  39. return this
  40. }
  41. // Empty checks if this sphere is empty (radius <= 0)
  42. func (s *Sphere) Empty(sphere *Sphere) bool {
  43. if s.Radius <= 0 {
  44. return true
  45. }
  46. return false
  47. }
  48. // ContainsPoint checks if this sphere contains the specified point
  49. func (s *Sphere) ContainsPoint(point *Vector3) bool {
  50. if point.DistanceToSquared(&s.Center) <= (s.Radius * s.Radius) {
  51. return true
  52. }
  53. return false
  54. }
  55. func (this *Sphere) DistanceToPoint(point *Vector3) float32 {
  56. return point.DistanceTo(&this.Center) - this.Radius
  57. }
  58. func (this *Sphere) IntersectSphere(sphere *Sphere) bool {
  59. radiusSum := this.Radius + sphere.Radius
  60. if sphere.Center.DistanceToSquared(&this.Center) <= (radiusSum * radiusSum) {
  61. return true
  62. }
  63. return false
  64. }
  65. func (this *Sphere) ClampPoint(point *Vector3, optionalTarget *Vector3) *Vector3 {
  66. deltaLengthSq := this.Center.DistanceToSquared(point)
  67. var result *Vector3
  68. if optionalTarget != nil {
  69. result = optionalTarget
  70. } else {
  71. result = NewVector3(0, 0, 0)
  72. }
  73. result.Copy(point)
  74. if deltaLengthSq > (this.Radius * this.Radius) {
  75. result.Sub(&this.Center).Normalize()
  76. result.MultiplyScalar(this.Radius).Add(&this.Center)
  77. }
  78. return result
  79. }
  80. func (s *Sphere) GetBoundingBox(optionalTarget *Box3) *Box3 {
  81. var box *Box3
  82. if optionalTarget != nil {
  83. box = optionalTarget
  84. } else {
  85. box = NewBox3(nil, nil)
  86. }
  87. box.Set(&s.Center, &s.Center)
  88. box.ExpandByScalar(s.Radius)
  89. return box
  90. }
  91. // ApplyMatrix4 applies the specified matrix transform to this sphere
  92. func (s *Sphere) ApplyMatrix4(matrix *Matrix4) *Sphere {
  93. s.Center.ApplyMatrix4(matrix)
  94. s.Radius = s.Radius * matrix.GetMaxScaleOnAxis()
  95. return s
  96. }
  97. func (this *Sphere) Translate(offset *Vector3) *Sphere {
  98. this.Center.Add(offset)
  99. return this
  100. }