vect.go 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  1. /* Copyright (c) 2010 Beoran
  2. * Copyright (c) 2007 Scott Lembcke
  3. *
  4. * Permission is hereby granted, free of charge, to any person obtaining a copy
  5. * of this software and associated documentation files (the "Software"), to deal
  6. * in the Software without restriction, including without limitation the rights
  7. * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  8. * copies of the Software, and to permit persons to whom the Software is
  9. * furnished to do so, subject to the following conditions:
  10. *
  11. * The above copyright notice and this permission notice shall be included in
  12. * all copies or substantial portions of the Software.
  13. *
  14. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  17. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  19. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  20. * SOFTWARE.
  21. */
  22. package tamias
  23. import "fmt"
  24. // import "math"
  25. // type Float float;
  26. type Vect struct {
  27. X Float
  28. Y Float
  29. }
  30. var VZERO=Vect{0.0,0.0};
  31. func V(x Float, y Float) (Vect) {
  32. result := Vect{X:x, Y:y}
  33. return result
  34. }
  35. func VF(x float, y float) (Vect) {
  36. return V(Float(x), Float(y))
  37. }
  38. func (v1 Vect) Equals(o interface {}) (bool) {
  39. v2, ok := o.(Vect)
  40. if !ok { return false; }
  41. return (v1.X == v2.X) && (v1.Y == v2.Y)
  42. }
  43. // non-inlined functions
  44. /*
  45. cpFloat cpvlength(const cpVect v);
  46. cpVect cpvslerp(const cpVect v1, const cpVect v2, const cpFloat t);
  47. cpVect cpvslerpconst(const cpVect v1, const cpVect v2, const cpFloat a);
  48. cpVect cpvforangle(const cpFloat a); // convert radians to a normalized vector
  49. cpFloat cpvtoangle(const cpVect v); // convert a vector to radians
  50. char *cpvstr(const cpVect v); // get a string representation of a vector
  51. */
  52. func (v1 Vect) Add(v2 Vect) (Vect) {
  53. return V(v1.X + v2.X, v1.Y + v2.Y)
  54. }
  55. func (v Vect) Neg() (Vect) {
  56. return V(-v.X, -v.Y)
  57. }
  58. func (v1 Vect) Sub(v2 Vect) (Vect) {
  59. return V(v1.X - v2.X, v1.Y - v2.Y)
  60. }
  61. func (v1 Vect) Mult(s Float) (Vect) {
  62. return V(v1.X * s, v1.Y * s)
  63. }
  64. func (v1 Vect) Dot(v2 Vect) (Float) {
  65. return v1.X * v2.X + v1.Y * v2.Y
  66. }
  67. func (v1 Vect) Cross(v2 Vect) (Float) {
  68. return v1.X * v2.Y - v1.Y * v2.X
  69. }
  70. func (v Vect) Perp() (Vect) {
  71. return V(-v.Y, v.X)
  72. }
  73. func (v Vect) Rperp() (Vect) {
  74. return V(v.Y, -v.X)
  75. }
  76. func (v1 Vect) Project(v2 Vect) (Vect) {
  77. return v2.Mult(v1.Dot(v2) / v2.Dot(v2))
  78. }
  79. func (v1 Vect) Rotate(v2 Vect) (Vect) {
  80. return V(v1.X*v2.X - v1.Y*v2.Y, v1.X*v2.Y + v1.Y*v2.X)
  81. }
  82. func (v1 Vect) Unrotate(v2 Vect) (Vect) {
  83. return V(v1.X*v2.X + v1.Y*v2.Y, v1.Y*v2.X - v1.X*v2.Y)
  84. }
  85. func (v Vect) Lengthsq() (Float) {
  86. return v.Dot(v)
  87. }
  88. func (v Vect) Length() (Float) {
  89. return v.Lengthsq().Sqrt()
  90. }
  91. func (v1 Vect) Lerp(v2 Vect, t Float) (Vect) {
  92. aid1 := v1.Mult(1.0 - t)
  93. aid2 := v2.Mult(t)
  94. return aid1.Add(aid2)
  95. }
  96. func (v Vect) Normalize() (Vect) {
  97. return v.Mult(1.0 / v.Length())
  98. }
  99. func (v Vect) NormalizeSafe() (Vect) {
  100. if v.X == 0.0 && v.Y == 0.0 {
  101. return VZERO
  102. }
  103. return v.Normalize()
  104. }
  105. func (v Vect) Clamp(len Float) (Vect) {
  106. if v.Lengthsq() > (len * len) {
  107. return v.Normalize().Mult(len)
  108. }
  109. return v
  110. }
  111. func (v1 Vect) Lerpconst(v2 Vect, d Float) (Vect) {
  112. return v1.Add(v2.Sub(v1).Clamp(d));
  113. }
  114. func (v1 Vect) Dist(v2 Vect) (Float) {
  115. return v1.Sub(v2).Length()
  116. }
  117. func (v1 Vect) Distsq(v2 Vect) (Float) {
  118. return v1.Sub(v2).Lengthsq()
  119. }
  120. func (v1 Vect) Near(v2 Vect, dist Float) (bool) {
  121. return v1.Distsq(v2) < dist*dist
  122. }
  123. func (v1 Vect) Slerp(v2 Vect, t Float) (Vect) {
  124. omega := v1.Dot(v2).Acos();
  125. if(omega != 0.0){
  126. denom := 1.0 / omega.Sin();
  127. par1 := ((1.0 - t)*omega).Sin() *denom
  128. par2 := ((t)*omega).Sin() *denom
  129. aid1 := v1.Mult(par1)
  130. aid2 := v2.Mult(par2)
  131. return aid1.Add(aid2)
  132. }
  133. // else
  134. return v1;
  135. }
  136. func (v1 Vect) Slerpconst(v2 Vect, a Float) (Vect) {
  137. angle := v1.Dot(v2).Acos()
  138. return v1.Slerp(v2, a.Min(angle) / angle)
  139. }
  140. func ForAngle(a Float) (Vect) {
  141. return V(a.Cos(), a.Sin());
  142. }
  143. func (v Vect) ToAngle() (Float) {
  144. return v.Y.Atan2(v.X)
  145. }
  146. func (v Vect) String() (string) {
  147. return fmt.Sprintf("(%.3f, %.3f)", v.X, v.Y)
  148. }