forcefield.go 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  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 physics
  5. import "github.com/g3n/engine/math32"
  6. // ForceField represents a force field. A force is defined for every point.
  7. type ForceField interface {
  8. ForceAt(pos *math32.Vector3) *math32.Vector3
  9. }
  10. //
  11. // Constant is a constant force field.
  12. // It can be used to simulate surface gravity.
  13. //
  14. type Constant struct {
  15. force math32.Vector3
  16. }
  17. // NewConstant creates and returns a pointer to a new Constant force field.
  18. func NewConstant(acceleration float32) *Constant {
  19. g := new(Constant)
  20. g.force = math32.Vector3{0,0,-acceleration}
  21. return g
  22. }
  23. // SetForce sets the force of the force field.
  24. func (g *Constant) SetForce(newDirection *math32.Vector3) {
  25. g.force = *newDirection
  26. }
  27. // Force returns the force of the force field.
  28. func (g *Constant) Force() *math32.Vector3 {
  29. return &g.force
  30. }
  31. // ForceAt satisfies the ForceField interface and returns the force at the specified position.
  32. func (g *Constant) ForceAt(pos *math32.Vector3) *math32.Vector3 {
  33. return &g.force
  34. }
  35. //
  36. // PointAttractor is a force field where all forces point to a single point.
  37. // The force strength changes with the inverse distance squared.
  38. // This can be used to model planetary attractions.
  39. //
  40. type PointAttractor struct {
  41. position math32.Vector3
  42. mass float32
  43. }
  44. // NewPointAttractor creates and returns a pointer to a new PointAttractor force field.
  45. func NewPointAttractor(position *math32.Vector3, mass float32) *PointAttractor {
  46. pa := new(PointAttractor)
  47. pa.position = *position
  48. pa.mass = mass
  49. return pa
  50. }
  51. // SetPosition sets the position of the PointAttractor.
  52. func (pa *PointAttractor) SetPosition(newPosition *math32.Vector3) {
  53. pa.position = *newPosition
  54. }
  55. // Position returns the position of the PointAttractor.
  56. func (pa *PointAttractor) Position() *math32.Vector3 {
  57. return &pa.position
  58. }
  59. // SetMass sets the mass of the PointAttractor.
  60. func (pa *PointAttractor) SetMass(newMass float32) {
  61. pa.mass = newMass
  62. }
  63. // Mass returns the mass of the PointAttractor.
  64. func (pa *PointAttractor) Mass() float32 {
  65. return pa.mass
  66. }
  67. // ForceAt satisfies the ForceField interface and returns the force at the specified position.
  68. func (pa *PointAttractor) ForceAt(pos *math32.Vector3) *math32.Vector3 {
  69. dir := pos
  70. dir.Negate()
  71. dir.Add(&pa.position)
  72. dist := dir.Length()
  73. dir.Normalize()
  74. dir.MultiplyScalar(pa.mass/(dist*dist))
  75. return dir
  76. }
  77. //
  78. // PointRepeller is a force field where all forces point away from a single point.
  79. // The force strength changes with the inverse distance squared.
  80. //
  81. type PointRepeller struct {
  82. position math32.Vector3
  83. mass float32
  84. }
  85. // NewPointRepeller creates and returns a pointer to a new PointRepeller force field.
  86. func NewPointRepeller(position *math32.Vector3, mass float32) *PointRepeller {
  87. pr := new(PointRepeller)
  88. pr.position = *position
  89. pr.mass = mass
  90. return pr
  91. }
  92. // SetPosition sets the position of the PointRepeller.
  93. func (pr *PointRepeller) SetPosition(newPosition *math32.Vector3) {
  94. pr.position = *newPosition
  95. }
  96. // Position returns the position of the PointRepeller.
  97. func (pr *PointRepeller) Position() *math32.Vector3 {
  98. return &pr.position
  99. }
  100. // SetMass sets the mass of the PointRepeller.
  101. func (pr *PointRepeller) SetMass(newMass float32) {
  102. pr.mass = newMass
  103. }
  104. // Mass returns the mass of the PointRepeller.
  105. func (pr *PointRepeller) Mass() float32 {
  106. return pr.mass
  107. }
  108. // ForceAt satisfies the ForceField interface and returns the force at the specified position.
  109. func (pr *PointRepeller) ForceAt(pos *math32.Vector3) *math32.Vector3 {
  110. dir := pr.position
  111. dir.Negate()
  112. dir.Add(pos)
  113. dist := dir.Length()
  114. dir.Normalize()
  115. dir.MultiplyScalar(pr.mass/(dist*dist))
  116. return &dir
  117. }