vector4.go 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632
  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. // Vector4 is a vector/point in homogeneous coordinates with X, Y, Z and W components.
  6. type Vector4 struct {
  7. X float32
  8. Y float32
  9. Z float32
  10. W float32
  11. }
  12. // NewVector4 creates and returns a pointer to a new Vector4
  13. func NewVector4(x, y, z, w float32) *Vector4 {
  14. return &Vector4{X: x, Y: y, Z: z, W: w}
  15. }
  16. // NewVec4 creates and returns a pointer to a new zero-ed Vector4 (with W=1).
  17. func NewVec4() *Vector4 {
  18. return &Vector4{X: 0, Y: 0, Z: 0, W: 1}
  19. }
  20. // Set sets this vector X, Y, Z and W components.
  21. // Returns the pointer to this updated vector.
  22. func (v *Vector4) Set(x, y, z, w float32) *Vector4 {
  23. v.X = x
  24. v.Y = y
  25. v.Z = z
  26. v.W = w
  27. return v
  28. }
  29. // SetVector3 sets this vector from another Vector3 and W
  30. func (v *Vector4) SetVector3(other *Vector3, w float32) *Vector4 {
  31. v.X = other.X
  32. v.Y = other.Y
  33. v.Z = other.Z
  34. v.W = w
  35. return v
  36. }
  37. // SetX sets this vector X component.
  38. // Returns the pointer to this updated Vector.
  39. func (v *Vector4) SetX(x float32) *Vector4 {
  40. v.X = x
  41. return v
  42. }
  43. // SetY sets this vector Y component.
  44. // Returns the pointer to this updated vector.
  45. func (v *Vector4) SetY(y float32) *Vector4 {
  46. v.Y = y
  47. return v
  48. }
  49. // SetZ sets this vector Z component.
  50. // Returns the pointer to this updated vector.
  51. func (v *Vector4) SetZ(z float32) *Vector4 {
  52. v.Z = z
  53. return v
  54. }
  55. // SetW sets this vector W component.
  56. // Returns the pointer to this updated vector.
  57. func (v *Vector4) SetW(w float32) *Vector4 {
  58. v.W = w
  59. return v
  60. }
  61. // SetComponent sets this vector component value by its index: 0 for X, 1 for Y, 2 for Z, 3 for W.
  62. // Returns the pointer to this updated vector
  63. func (v *Vector4) SetComponent(index int, value float32) *Vector4 {
  64. switch index {
  65. case 0:
  66. v.X = value
  67. case 1:
  68. v.Y = value
  69. case 2:
  70. v.Z = value
  71. case 3:
  72. v.W = value
  73. default:
  74. panic("index is out of range")
  75. }
  76. return v
  77. }
  78. // Component returns this vector component by its index: 0 for X, 1 for Y, 2 for Z, 3 for W.
  79. func (v *Vector4) Component(index int) float32 {
  80. switch index {
  81. case 0:
  82. return v.X
  83. case 1:
  84. return v.Y
  85. case 2:
  86. return v.Z
  87. case 3:
  88. return v.W
  89. default:
  90. panic("index is out of range")
  91. }
  92. }
  93. // SetByName sets this vector component value by its case insensitive name: "x", "y", "z" or "w".
  94. func (v *Vector4) SetByName(name string, value float32) {
  95. switch name {
  96. case "x", "X":
  97. v.X = value
  98. case "y", "Y":
  99. v.Y = value
  100. case "z", "Z":
  101. v.Z = value
  102. case "w", "W":
  103. v.W = value
  104. default:
  105. panic("Invalid Vector4 component name: " + name)
  106. }
  107. }
  108. // Zero sets this vector X, Y and Z components to be zero and W to be one.
  109. // Returns the pointer to this updated vector.
  110. func (v *Vector4) Zero() *Vector4 {
  111. v.X = 0
  112. v.Y = 0
  113. v.Z = 0
  114. v.W = 1
  115. return v
  116. }
  117. // Copy copies other vector to this one.
  118. // Returns the pointer to this updated vector.
  119. func (v *Vector4) Copy(other *Vector4) *Vector4 {
  120. *v = *other
  121. return v
  122. }
  123. // Add adds other vector to this one.
  124. // Returns the pointer to this updated vector.
  125. func (v *Vector4) Add(other *Vector4) *Vector4 {
  126. v.X += other.X
  127. v.Y += other.Y
  128. v.Z += other.Z
  129. v.W += other.W
  130. return v
  131. }
  132. // AddScalar adds scalar s to each component of this vector.
  133. // Returns the pointer to this updated vector.
  134. func (v *Vector4) AddScalar(s float32) *Vector4 {
  135. v.X += s
  136. v.Y += s
  137. v.Z += s
  138. v.W += s
  139. return v
  140. }
  141. // AddVectors adds vectors a and b to this one.
  142. // Returns the pointer to this updated vector.
  143. func (v *Vector4) AddVectors(a, b *Vector4) *Vector4 {
  144. v.X = a.X + b.X
  145. v.Y = a.Y + b.Y
  146. v.Z = a.Z + b.Z
  147. v.W = a.W + b.W
  148. return v
  149. }
  150. // Sub subtracts other vector from this one.
  151. // Returns the pointer to this updated vector.
  152. func (v *Vector4) Sub(other *Vector4) *Vector4 {
  153. v.X -= other.X
  154. v.Y -= other.Y
  155. v.Z -= other.Z
  156. v.W -= other.W
  157. return v
  158. }
  159. // SubScalar subtracts scalar s from each component of this vector.
  160. // Returns the pointer to this updated vector.
  161. func (v *Vector4) SubScalar(s float32) *Vector4 {
  162. v.X -= s
  163. v.Y -= s
  164. v.Z -= s
  165. v.W -= s
  166. return v
  167. }
  168. // SubVectors sets this vector to a - b.
  169. // Returns the pointer to this updated vector.
  170. func (v *Vector4) SubVectors(a, b *Vector4) *Vector4 {
  171. v.X = a.X - b.X
  172. v.Y = a.Y - b.Y
  173. v.Z = a.Y - b.Z
  174. v.W = a.Y - b.W
  175. return v
  176. }
  177. // Multiply multiplies each component of this vector by the corresponding one from other vector.
  178. // Returns the pointer to this updated vector.
  179. func (v *Vector4) Multiply(other *Vector4) *Vector4 {
  180. v.X *= other.X
  181. v.Y *= other.Y
  182. v.Z *= other.Z
  183. v.W *= other.W
  184. return v
  185. }
  186. // MultiplyScalar multiplies each component of this vector by the scalar s.
  187. // Returns the pointer to this updated vector.
  188. func (v *Vector4) MultiplyScalar(scalar float32) *Vector4 {
  189. v.X *= scalar
  190. v.Y *= scalar
  191. v.Z *= scalar
  192. v.W *= scalar
  193. return v
  194. }
  195. // Divide divides each component of this vector by the corresponding one from other vector.
  196. // Returns the pointer to this updated vector
  197. func (v *Vector4) Divide(other *Vector4) *Vector4 {
  198. v.X /= other.X
  199. v.Y /= other.Y
  200. v.Z /= other.Z
  201. v.W /= other.W
  202. return v
  203. }
  204. // DivideScalar divides each component of this vector by the scalar s.
  205. // If scalar is zero, sets this vector to zero.
  206. // Returns the pointer to this updated vector.
  207. func (v *Vector4) DivideScalar(scalar float32) *Vector4 {
  208. if scalar != 0 {
  209. invScalar := 1 / scalar
  210. v.X *= invScalar
  211. v.Y *= invScalar
  212. v.Z *= invScalar
  213. v.W *= invScalar
  214. } else {
  215. v.X = 0
  216. v.Y = 0
  217. v.Z = 0
  218. v.W = 0
  219. }
  220. return v
  221. }
  222. // Min sets this vector components to the minimum values of itself and other vector.
  223. // Returns the pointer to this updated vector.
  224. func (v *Vector4) Min(other *Vector4) *Vector4 {
  225. if v.X > other.X {
  226. v.X = other.X
  227. }
  228. if v.Y > other.Y {
  229. v.Y = other.Y
  230. }
  231. if v.Z > other.Z {
  232. v.Z = other.Z
  233. }
  234. if v.W > other.W {
  235. v.W = other.W
  236. }
  237. return v
  238. }
  239. // Max sets this vector components to the maximum value of itself and other vector.
  240. // Returns the pointer to this updated vector.
  241. func (v *Vector4) Max(other *Vector4) *Vector4 {
  242. if v.X < other.X {
  243. v.X = other.X
  244. }
  245. if v.Y < other.Y {
  246. v.Y = other.Y
  247. }
  248. if v.Z < other.Z {
  249. v.Z = other.Z
  250. }
  251. if v.W < other.W {
  252. v.W = other.W
  253. }
  254. return v
  255. }
  256. // Clamp sets this vector components to be no less than the corresponding components of min
  257. // and not greater than the corresponding component of max.
  258. // Assumes min < max, if this assumption isn't true it will not operate correctly.
  259. // Returns the pointer to this updated vector.
  260. func (v *Vector4) Clamp(min, max *Vector4) *Vector4 {
  261. if v.X < min.X {
  262. v.X = min.X
  263. } else if v.X > max.X {
  264. v.X = max.X
  265. }
  266. if v.Y < min.Y {
  267. v.Y = min.Y
  268. } else if v.Y > max.Y {
  269. v.Y = max.Y
  270. }
  271. if v.Z < min.Z {
  272. v.Z = min.Z
  273. } else if v.Z > max.Z {
  274. v.Z = max.Z
  275. }
  276. if v.W < min.W {
  277. v.W = min.W
  278. } else if v.W > max.W {
  279. v.W = max.W
  280. }
  281. return v
  282. }
  283. // ClampScalar sets this vector components to be no less than minVal and not greater than maxVal.
  284. // Returns the pointer to this updated vector.
  285. func (v *Vector4) ClampScalar(minVal, maxVal float32) *Vector4 {
  286. min := NewVector4(minVal, minVal, minVal, minVal)
  287. max := NewVector4(maxVal, maxVal, maxVal, maxVal)
  288. return v.Clamp(min, max)
  289. }
  290. // Floor applies math32.Floor() to each of this vector's components.
  291. // Returns the pointer to this updated vector.
  292. func (v *Vector4) Floor() *Vector4 {
  293. v.X = Floor(v.X)
  294. v.Y = Floor(v.Y)
  295. v.Z = Floor(v.Z)
  296. v.W = Floor(v.W)
  297. return v
  298. }
  299. // Ceil applies math32.Ceil() to each of this vector's components.
  300. // Returns the pointer to this updated vector.
  301. func (v *Vector4) Ceil() *Vector4 {
  302. v.X = Ceil(v.X)
  303. v.Y = Ceil(v.Y)
  304. v.Z = Ceil(v.Z)
  305. v.W = Ceil(v.W)
  306. return v
  307. }
  308. // Round rounds each of this vector's components.
  309. // Returns the pointer to this updated vector.
  310. func (v *Vector4) Round() *Vector4 {
  311. v.X = Floor(v.X + 0.5)
  312. v.Y = Floor(v.Y + 0.5)
  313. v.Z = Floor(v.Z + 0.5)
  314. v.W = Floor(v.W + 0.5)
  315. return v
  316. }
  317. // Negate negates each of this vector's components.
  318. // Returns the pointer to this updated vector.
  319. func (v *Vector4) Negate() *Vector4 {
  320. v.X = -v.X
  321. v.Y = -v.Y
  322. v.Z = -v.Z
  323. v.W = -v.W
  324. return v
  325. }
  326. // Dot returns the dot product of this vector with other.
  327. // None of the vectors are changed.
  328. func (v *Vector4) Dot(other *Vector4) float32 {
  329. return v.X*other.X + v.Y*other.Y + v.Z*other.Z + v.W*other.W
  330. }
  331. // LengthSq returns the length squared of this vector.
  332. // LengthSq can be used to compare vectors' lengths without the need to perform a square root.
  333. func (v *Vector4) LengthSq() float32 {
  334. return v.X*v.X + v.Y*v.Y + v.Z*v.Z + v.W*v.W
  335. }
  336. // Length returns the length of this vector.
  337. func (v *Vector4) Length() float32 {
  338. return Sqrt(v.X*v.X + v.Y*v.Y + v.Z*v.Z + v.W*v.W)
  339. }
  340. // Normalize normalizes this vector so its length will be 1.
  341. // Returns the pointer to this updated vector.
  342. func (v *Vector4) Normalize() *Vector4 {
  343. return v.DivideScalar(v.Length())
  344. }
  345. // SetLength sets this vector to have the specified length.
  346. // If the current length is zero, does nothing.
  347. // Returns the pointer to this updated vector.
  348. func (v *Vector4) SetLength(l float32) *Vector4 {
  349. oldLength := v.Length()
  350. if oldLength != 0 && l != oldLength {
  351. v.MultiplyScalar(l / oldLength)
  352. }
  353. return v
  354. }
  355. // Lerp sets each of this vector's components to the linear interpolated value of
  356. // alpha between ifself and the corresponding other component.
  357. // Returns the pointer to this updated vector.
  358. func (v *Vector4) Lerp(other *Vector4, alpha float32) *Vector4 {
  359. v.X += (other.X - v.X) * alpha
  360. v.Y += (other.Y - v.Y) * alpha
  361. v.Z += (other.Z - v.Z) * alpha
  362. v.W += (other.W - v.W) * alpha
  363. return v
  364. }
  365. // Equals returns if this vector is equal to other.
  366. func (v *Vector4) Equals(other *Vector4) bool {
  367. return (other.X == v.X) && (other.Y == v.Y) && (other.Z == v.Z) && (other.W == v.W)
  368. }
  369. // FromArray sets this vector's components from the specified array and offset
  370. // Returns the pointer to this updated vector.
  371. func (v *Vector4) FromArray(array []float32, offset int) *Vector4 {
  372. v.X = array[offset]
  373. v.Y = array[offset+1]
  374. v.Z = array[offset+2]
  375. v.W = array[offset+3]
  376. return v
  377. }
  378. // ToArray copies this vector's components to array starting at offset.
  379. // Returns the array.
  380. func (v *Vector4) ToArray(array []float32, offset int) []float32 {
  381. array[offset] = v.X
  382. array[offset+1] = v.Y
  383. array[offset+2] = v.Z
  384. array[offset+3] = v.W
  385. return array
  386. }
  387. // ApplyMatrix4 multiplies the specified 4x4 matrix by this vector.
  388. // Returns the pointer to this updated vector.
  389. func (v *Vector4) ApplyMatrix4(m *Matrix4) *Vector4 {
  390. x := v.X
  391. y := v.Y
  392. z := v.Z
  393. w := v.W
  394. v.X = m[0]*x + m[4]*y + m[8]*z + m[12]*w
  395. v.Y = m[1]*x + m[5]*y + m[9]*z + m[13]*w
  396. v.Z = m[2]*x + m[6]*y + m[10]*z + m[14]*w
  397. v.W = m[3]*x + m[7]*y + m[11]*z + m[15]*w
  398. return v
  399. }
  400. // SetAxisAngleFromQuaternion set this vector to be the axis (x, y, z) and angle (w) of a rotation specified the quaternion q.
  401. // Assumes q is normalized.
  402. func (v *Vector4) SetAxisAngleFromQuaternion(q *Quaternion) *Vector4 {
  403. // http://www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToAngle/index.htm
  404. v.W = 2 * Acos(q.W)
  405. s := Sqrt(1 - q.W*q.W)
  406. if s < 0.0001 {
  407. v.X = 1
  408. v.Y = 0
  409. v.Z = 0
  410. } else {
  411. v.X = q.X / s
  412. v.Y = q.Y / s
  413. v.Z = q.Z / s
  414. }
  415. return v
  416. }
  417. // SetAxisFromRotationMatrix this vector to be the axis (x, y, z) and angle (w) of a rotation specified the matrix m.
  418. // Assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled).
  419. func (v *Vector4) SetAxisFromRotationMatrix(m *Matrix4) *Vector4 {
  420. // http://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToAngle/index.htm
  421. var angle, x, y, z float32 // variables for result
  422. var epsilon float32 = 0.01 // margin to allow for rounding errors
  423. var epsilon2 float32 = 0.1 // margin to distinguish between 0 and 180 degrees
  424. m11 := m[0]
  425. m12 := m[4]
  426. m13 := m[8]
  427. m21 := m[1]
  428. m22 := m[5]
  429. m23 := m[9]
  430. m31 := m[2]
  431. m32 := m[6]
  432. m33 := m[10]
  433. if (Abs(m12-m21) < epsilon) && (Abs(m13-m31) < epsilon) && (Abs(m23-m32) < epsilon) {
  434. // singularity found
  435. // first check for identity matrix which must have +1 for all terms
  436. // in leading diagonal and zero in other terms
  437. if (Abs(m12+m21) < epsilon2) && (Abs(m13+m31) < epsilon2) && (Abs(m23+m32) < epsilon2) && (Abs(m11+m22+m33-3) < epsilon2) {
  438. // v singularity is identity matrix so angle = 0
  439. v.Set(1, 0, 0, 0)
  440. return v // zero angle, arbitrary axis
  441. }
  442. // otherwise this singularity is angle = 180
  443. angle = Pi
  444. var xx = (m11 + 1) / 2
  445. var yy = (m22 + 1) / 2
  446. var zz = (m33 + 1) / 2
  447. var xy = (m12 + m21) / 4
  448. var xz = (m13 + m31) / 4
  449. var yz = (m23 + m32) / 4
  450. if (xx > yy) && (xx > zz) { // m11 is the largest diagonal term
  451. if xx < epsilon {
  452. x = 0
  453. y = 0.707106781
  454. z = 0.707106781
  455. } else {
  456. x = Sqrt(xx)
  457. y = xy / x
  458. z = xz / x
  459. }
  460. } else if yy > zz { // m22 is the largest diagonal term
  461. if yy < epsilon {
  462. x = 0.707106781
  463. y = 0
  464. z = 0.707106781
  465. } else {
  466. y = Sqrt(yy)
  467. x = xy / y
  468. z = yz / y
  469. }
  470. } else { // m33 is the largest diagonal term so base result on this
  471. if zz < epsilon {
  472. x = 0.707106781
  473. y = 0.707106781
  474. z = 0
  475. } else {
  476. z = Sqrt(zz)
  477. x = xz / z
  478. y = yz / z
  479. }
  480. }
  481. v.Set(x, y, z, angle)
  482. return v // return 180 deg rotation
  483. }
  484. // as we have reached here there are no singularities so we can handle normally
  485. s := Sqrt((m32-m23)*(m32-m23) + (m13-m31)*(m13-m31) + (m21-m12)*(m21-m12)) // used to normalize
  486. if Abs(s) < 0.001 {
  487. s = 1
  488. }
  489. // prevent divide by zero, should not happen if matrix is orthogonal and should be
  490. // caught by singularity test above, but I've left it in just in case
  491. v.X = (m32 - m23) / s
  492. v.Y = (m13 - m31) / s
  493. v.Z = (m21 - m12) / s
  494. v.W = Acos((m11 + m22 + m33 - 1) / 2)
  495. return v
  496. }
  497. // Clone returns a copy of this vector
  498. func (v *Vector4) Clone() *Vector4 {
  499. return NewVector4(v.X, v.Y, v.Z, v.W)
  500. }