vector4.go 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558
  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 Vector4 struct {
  6. X float32
  7. Y float32
  8. Z float32
  9. W float32
  10. }
  11. func NewVector4(x, y, z, w float32) *Vector4 {
  12. return &Vector4{X: x, Y: y, Z: z, W: w}
  13. }
  14. func (v *Vector4) Set(x, y, z, w float32) *Vector4 {
  15. v.X = x
  16. v.Y = y
  17. v.Z = z
  18. v.W = w
  19. return v
  20. }
  21. // SetVector3 sets this vector from another Vector3 and 'w' value
  22. func (v *Vector4) SetVector3(other *Vector3, w float32) *Vector4 {
  23. v.X = other.X
  24. v.Y = other.Y
  25. v.Z = other.Z
  26. v.W = w
  27. return v
  28. }
  29. //func (this *Vector4) SetX(x float32) *Vector4 {
  30. //
  31. // this.X = x
  32. // return this
  33. //}
  34. //
  35. //func (this *Vector4) SetY(y float32) *Vector4 {
  36. //
  37. // this.Y = y
  38. // return this
  39. //}
  40. //
  41. //func (this *Vector4) SetZ(z float32) *Vector4 {
  42. //
  43. // this.Z = z
  44. // return this
  45. //}
  46. //
  47. //func (this *Vector4) SetW(w float32) *Vector4 {
  48. //
  49. // this.W = w
  50. // return this
  51. //}
  52. func (this *Vector4) SetComponent(index int, value float32) *Vector4 {
  53. switch index {
  54. case 0:
  55. this.X = value
  56. case 1:
  57. this.Y = value
  58. case 2:
  59. this.Z = value
  60. case 3:
  61. this.Z = value
  62. default:
  63. panic("index is out of range")
  64. }
  65. return this
  66. }
  67. func (this *Vector4) GetComponent(index int) float32 {
  68. switch index {
  69. case 0:
  70. return this.X
  71. case 1:
  72. return this.Y
  73. case 2:
  74. return this.Z
  75. case 3:
  76. return this.W
  77. default:
  78. panic("index is out of range")
  79. }
  80. }
  81. func (this *Vector4) Copy(v *Vector4) *Vector4 {
  82. this.X = v.X
  83. this.Y = v.Y
  84. this.Z = v.Z
  85. this.W = v.W
  86. return this
  87. }
  88. func (this *Vector4) Add(v *Vector4) *Vector4 {
  89. this.X += v.X
  90. this.Y += v.Y
  91. this.Z += v.Z
  92. this.W += v.W
  93. return this
  94. }
  95. func (this *Vector4) AddScalar(s float32) *Vector4 {
  96. this.X += s
  97. this.Y += s
  98. this.Z += s
  99. this.W += s
  100. return this
  101. }
  102. func (this *Vector4) AddVectors(a, b *Vector4) *Vector4 {
  103. this.X = a.X + b.X
  104. this.Y = a.Y + b.Y
  105. this.Z = a.Z + b.Z
  106. this.W = a.W + b.W
  107. return this
  108. }
  109. func (this *Vector4) Sub(v *Vector4) *Vector4 {
  110. this.X -= v.X
  111. this.Y -= v.Y
  112. this.Z -= v.Z
  113. this.W -= v.W
  114. return this
  115. }
  116. func (this *Vector4) SubScalar(s float32) *Vector4 {
  117. this.X -= s
  118. this.Y -= s
  119. this.Z -= s
  120. this.W -= s
  121. return this
  122. }
  123. func (this *Vector4) SubVectors(a, b *Vector4) *Vector4 {
  124. this.X = a.X - b.X
  125. this.Y = a.Y - b.Y
  126. this.Z = a.Y - b.Z
  127. this.W = a.Y - b.W
  128. return this
  129. }
  130. func (this *Vector4) MultiplyScalar(scalar float32) *Vector4 {
  131. this.X *= scalar
  132. this.Y *= scalar
  133. this.Z *= scalar
  134. this.W *= scalar
  135. return this
  136. }
  137. func (this *Vector4) ApplyMatrix4(m *Matrix4) *Vector4 {
  138. x := this.X
  139. y := this.Y
  140. z := this.Z
  141. w := this.W
  142. this.X = m[0]*x + m[4]*y + m[8]*z + m[12]*w
  143. this.Y = m[1]*x + m[5]*y + m[9]*z + m[13]*w
  144. this.Z = m[2]*x + m[6]*y + m[10]*z + m[14]*w
  145. this.W = m[3]*x + m[7]*y + m[11]*z + m[15]*w
  146. return this
  147. }
  148. func (this *Vector4) DivideScalar(scalar float32) *Vector4 {
  149. if scalar != 0 {
  150. invScalar := 1 / scalar
  151. this.X *= invScalar
  152. this.Y *= invScalar
  153. this.Z *= invScalar
  154. this.W *= invScalar
  155. } else {
  156. this.X = 0
  157. this.Y = 0
  158. this.Z = 0
  159. this.W = 0
  160. }
  161. return this
  162. }
  163. func (this *Vector4) SetAxisAngleFromQuaternion(q *Quaternion) *Vector4 {
  164. // http://www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToAngle/index.htm
  165. // q is assumed to be normalized
  166. this.W = 2 * Acos(q.W())
  167. s := Sqrt(1 - q.W()*q.W())
  168. if s < 0.0001 {
  169. this.X = 1
  170. this.Y = 0
  171. this.Z = 0
  172. } else {
  173. this.X = q.X() / s
  174. this.Y = q.Y() / s
  175. this.Z = q.Z() / s
  176. }
  177. return this
  178. }
  179. func (this *Vector4) SetAxisFromRotationMatrix(m *Matrix4) *Vector4 {
  180. // http://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToAngle/index.htm
  181. // assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled)
  182. var angle, x, y, z float32 // variables for result
  183. var epsilon float32 = 0.01 // margin to allow for rounding errors
  184. var epsilon2 float32 = 0.1 // margin to distinguish between 0 and 180 degrees
  185. m11 := m[0]
  186. m12 := m[4]
  187. m13 := m[8]
  188. m21 := m[1]
  189. m22 := m[5]
  190. m23 := m[9]
  191. m31 := m[2]
  192. m32 := m[6]
  193. m33 := m[10]
  194. if (Abs(m12-m21) < epsilon) && (Abs(m13-m31) < epsilon) && (Abs(m23-m32) < epsilon) {
  195. // singularity found
  196. // first check for identity matrix which must have +1 for all terms
  197. // in leading diagonal and zero in other terms
  198. if (Abs(m12+m21) < epsilon2) && (Abs(m13+m31) < epsilon2) && (Abs(m23+m32) < epsilon2) && (Abs(m11+m22+m33-3) < epsilon2) {
  199. // this singularity is identity matrix so angle = 0
  200. this.Set(1, 0, 0, 0)
  201. return this // zero angle, arbitrary axis
  202. }
  203. // otherwise this singularity is angle = 180
  204. angle = Pi
  205. var xx = (m11 + 1) / 2
  206. var yy = (m22 + 1) / 2
  207. var zz = (m33 + 1) / 2
  208. var xy = (m12 + m21) / 4
  209. var xz = (m13 + m31) / 4
  210. var yz = (m23 + m32) / 4
  211. if (xx > yy) && (xx > zz) { // m11 is the largest diagonal term
  212. if xx < epsilon {
  213. x = 0
  214. y = 0.707106781
  215. z = 0.707106781
  216. } else {
  217. x = Sqrt(xx)
  218. y = xy / x
  219. z = xz / x
  220. }
  221. } else if yy > zz { // m22 is the largest diagonal term
  222. if yy < epsilon {
  223. x = 0.707106781
  224. y = 0
  225. z = 0.707106781
  226. } else {
  227. y = Sqrt(yy)
  228. x = xy / y
  229. z = yz / y
  230. }
  231. } else { // m33 is the largest diagonal term so base result on this
  232. if zz < epsilon {
  233. x = 0.707106781
  234. y = 0.707106781
  235. z = 0
  236. } else {
  237. z = Sqrt(zz)
  238. x = xz / z
  239. y = yz / z
  240. }
  241. }
  242. this.Set(x, y, z, angle)
  243. return this // return 180 deg rotation
  244. }
  245. // as we have reached here there are no singularities so we can handle normally
  246. s := Sqrt((m32-m23)*(m32-m23) + (m13-m31)*(m13-m31) + (m21-m12)*(m21-m12)) // used to normalize
  247. if Abs(s) < 0.001 {
  248. s = 1
  249. }
  250. // prevent divide by zero, should not happen if matrix is orthogonal and should be
  251. // caught by singularity test above, but I've left it in just in case
  252. this.X = (m32 - m23) / s
  253. this.Y = (m13 - m31) / s
  254. this.Z = (m21 - m12) / s
  255. this.W = Acos((m11 + m22 + m33 - 1) / 2)
  256. return this
  257. }
  258. func (this *Vector4) Min(v *Vector4) *Vector4 {
  259. if this.X > v.X {
  260. this.X = v.X
  261. }
  262. if this.Y > v.Y {
  263. this.Y = v.Y
  264. }
  265. if this.Z > v.Z {
  266. this.Z = v.Z
  267. }
  268. if this.W > v.W {
  269. this.W = v.W
  270. }
  271. return this
  272. }
  273. func (this *Vector4) Max(v *Vector4) *Vector4 {
  274. if this.X < v.X {
  275. this.X = v.X
  276. }
  277. if this.Y < v.Y {
  278. this.Y = v.Y
  279. }
  280. if this.Z < v.Z {
  281. this.Z = v.Z
  282. }
  283. if this.W < v.W {
  284. this.W = v.W
  285. }
  286. return this
  287. }
  288. func (this *Vector4) Clamp(min, max *Vector4) *Vector4 {
  289. // This function assumes min < max, if this assumption isn't true it will not operate correctly
  290. if this.X < min.X {
  291. this.X = min.X
  292. } else if this.X > max.X {
  293. this.X = max.X
  294. }
  295. if this.Y < min.Y {
  296. this.Y = min.Y
  297. } else if this.Y > max.Y {
  298. this.Y = max.Y
  299. }
  300. if this.Z < min.Z {
  301. this.Z = min.Z
  302. } else if this.Z > max.Z {
  303. this.Z = max.Z
  304. }
  305. if this.W < min.W {
  306. this.W = min.W
  307. } else if this.W > max.W {
  308. this.W = max.W
  309. }
  310. return this
  311. }
  312. func (this *Vector4) ClampScalar(minVal, maxVal float32) *Vector4 {
  313. min := NewVector4(minVal, minVal, minVal, minVal)
  314. max := NewVector4(maxVal, maxVal, maxVal, maxVal)
  315. return this.Clamp(min, max)
  316. }
  317. func (this *Vector4) Floor() *Vector4 {
  318. this.X = Floor(this.X)
  319. this.Y = Floor(this.Y)
  320. this.Z = Floor(this.Z)
  321. this.W = Floor(this.W)
  322. return this
  323. }
  324. func (this *Vector4) Ceil() *Vector4 {
  325. this.X = Ceil(this.X)
  326. this.Y = Ceil(this.Y)
  327. this.Z = Ceil(this.Z)
  328. this.W = Ceil(this.W)
  329. return this
  330. }
  331. func (this *Vector4) Round() *Vector4 {
  332. // TODO NEED CHECK
  333. this.X = Floor(this.X + 0.5)
  334. this.Y = Floor(this.Y + 0.5)
  335. this.Z = Floor(this.Z + 0.5)
  336. this.W = Floor(this.W + 0.5)
  337. return this
  338. }
  339. func (this *Vector4) RoundToZero() *Vector4 {
  340. if this.X < 0 {
  341. this.X = Ceil(this.X)
  342. } else {
  343. this.X = Floor(this.X)
  344. }
  345. if this.Y < 0 {
  346. this.Y = Ceil(this.Y)
  347. } else {
  348. this.Y = Floor(this.Y)
  349. }
  350. if this.Z < 0 {
  351. this.Z = Ceil(this.Z)
  352. } else {
  353. this.Z = Floor(this.Z)
  354. }
  355. if this.W < 0 {
  356. this.W = Ceil(this.W)
  357. } else {
  358. this.W = Floor(this.W)
  359. }
  360. return this
  361. }
  362. func (this *Vector4) Negate() *Vector4 {
  363. this.X = -this.X
  364. this.Y = -this.Y
  365. this.Z = -this.Z
  366. this.W = -this.W
  367. return this
  368. }
  369. func (this *Vector4) Dot(v *Vector4) float32 {
  370. return this.X*v.X + this.Y*v.Y + this.Z*v.Z + this.W*v.W
  371. }
  372. func (this *Vector4) LengthSq(v *Vector4) float32 {
  373. return this.X*this.X + this.Y*this.Y + this.Z*this.Z + this.W*this.W
  374. }
  375. func (this *Vector4) Length() float32 {
  376. return Sqrt(this.X*this.X + this.Y*this.Y + this.Z*this.Z + this.W*this.W)
  377. }
  378. func (this *Vector4) LengthManhattan(v *Vector4) float32 {
  379. return Abs(this.X + Abs(this.Y+Abs(this.Z)) + Abs(this.W))
  380. }
  381. func (this *Vector4) Normalize() *Vector4 {
  382. return this.DivideScalar(this.Length())
  383. }
  384. func (this *Vector4) SetLength(l float32) *Vector4 {
  385. oldLength := this.Length()
  386. if oldLength != 0 && l != oldLength {
  387. this.MultiplyScalar(l / oldLength)
  388. }
  389. return this
  390. }
  391. func (this *Vector4) Lerp(v *Vector4, alpha float32) *Vector4 {
  392. this.X += (v.X - this.X) * alpha
  393. this.Y += (v.Y - this.Y) * alpha
  394. this.Z += (v.Z - this.Z) * alpha
  395. this.W += (v.W - this.W) * alpha
  396. return this
  397. }
  398. func (this *Vector4) LerpVectors(v1, v2 *Vector4, alpha float32) *Vector4 {
  399. this.SubVectors(v2, v2).MultiplyScalar(alpha).Add(v1)
  400. return this
  401. }
  402. func (this *Vector4) Equals(v *Vector4) bool {
  403. return (v.X == this.X) && (v.Y == this.Y) && (v.Z == this.Z) && (v.W == this.W)
  404. }
  405. func (this *Vector4) FromArray(array []float32, offset int) *Vector4 {
  406. this.X = array[offset]
  407. this.Y = array[offset+1]
  408. this.Z = array[offset+2]
  409. this.W = array[offset+3]
  410. return this
  411. }
  412. func (this *Vector4) ToArray(array []float32, offset int) []float32 {
  413. array[offset] = this.X
  414. array[offset+1] = this.Y
  415. array[offset+2] = this.Z
  416. array[offset+3] = this.W
  417. return array
  418. }
  419. // TODO fromAttribute: function ( attribute, index, offset ) {
  420. func (this *Vector4) Clone() *Vector4 {
  421. return NewVector4(this.X, this.Y, this.Z, this.W)
  422. }